Skip to content

Commit 66ab6f4

Browse files
authored
NVAPI support doc (shader-slang#1574)
* #include an absolute path didn't work - because paths were taken to always be relative. * Split out NVAPI documentation. Attempt to describe updated usage. * Discuss downstream compiler include paths issues. * Fix links . * Apparently github supports relative links... * Fix typo.
1 parent 55cd421 commit 66ab6f4

File tree

2 files changed

+89
-29
lines changed

2 files changed

+89
-29
lines changed

docs/nvapi-support.md

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
NVAPI Support
2+
=============
3+
4+
Slang provides support for [NVAPI](https://developer.nvidia.com/nvapi) in several ways
5+
6+
* Slang allows the use of NVAPI directly, by the inclusion of the `#include "nvHLSLExtns.h"` header in your Slang code. Doing so will make all the NVAPI functions directly available and usabe within your Slang source code.
7+
* NVAPI is used to provide features implicitly for certain targets. For example support for [RWByteAddressBuffer atomics](target-compatibility.md) on HLSL based targets is supported currently via NVAPI.
8+
* Direct and implicit NVAPI usage can be freely mixed.
9+
10+
Direct usage of NVAPI
11+
=====================
12+
13+
Direct usage of NVAPI just requires the inclusion of the appropriate NVAPI header, typically with `#include "nvHLSLExtns.h` within your Slang source. As is required by NVAPI before the `#include` it is necessary to specify the slot and perhaps space usage. For example a typical direct NVAPI usage inside a Slang source file might contain something like...
14+
15+
```
16+
#define NV_SHADER_EXTN_SLOT u0
17+
#include "nvHLSLExtns.h"
18+
```
19+
20+
In order for the include to work, it is necessary for the include path to include the folder that contains the nvHLSLExtns.h and associated headers.
21+
22+
Implicit usage of NVAPI
23+
=======================
24+
25+
It is convenient and powerful to be able to directly use NVAPI calls, but will only work on such targets that support the mechansism, even if there is a way to support the functionality some other way.
26+
27+
Slang provides some cross platform features on HLSL based targets that are implemented via NVAPI. For example RWByteAddressBuffer atomics are supported on Vulkan, DX12 and CUDA. On DX12 they are made available via NVAPI, whilst CUDA and Vulkan have direct support. When compiling Slang code that uses RWByteAddressBuffer atomics Slang will emit HLSL code that use NVAPI. In order for the downstream compiler to be able to compile this HLSL it must be able to include the NVAPI header `nvHLSLExtns.h`.
28+
29+
It worth discussing briefly how this mechanism works. Slang has a 'prelude' mechanism for different source targets. The prelude is a piece of text that is inserted before the source that is output from compiling the input Slang source code. There is a default prelude for HLSL that is something like
30+
31+
```
32+
#ifdef SLANG_HLSL_ENABLE_NVAPI
33+
#include "nvHLSLExtns.h"
34+
#endif
35+
```
36+
37+
If there are any calls to NVAPI implicitly from Slang source, then the following is emitted before the prelude
38+
39+
```
40+
#define SLANG_HLSL_ENABLE_NVAPI 1
41+
#define NV_SHADER_EXTN_SLOT u0
42+
#define NV_SHADER_EXTN_REGISTER_SPACE space0
43+
```
44+
45+
Thus causing the prelude to include nvHLSLExtns.h, and specifying the slot and potentially the space as is required for inclusion of nvHLSLExtns.h.
46+
47+
The actual values for the slot and optionally the space, are found by Slang examining the values of those values at the end of preprocessing input Slang source files.
48+
49+
This means that if compile Slang source that has implicit use NVAPI, the slot and optionally the space must be defined. This can be achieved with a command line -D, throught the API or through having suitable `#define`s in the Slang source code.
50+
51+
It is worth noting if you *replace* the default HLSL prelude, and use NVAPI then it will be necessary to have something like the default HLSL prelude part of your custom prelude.
52+
53+
Downstream Compiler Include
54+
---------------------------
55+
56+
There is a subtle detail that is perhaps worth noting here around the downstream compiler and `#include`s. When Slang outputs HLSL it typically does not contain any `#include`, because all of the `#include` in the original source code have been handled by Slang. Slang then outputs everything required to compile to the downstream compiler *without* any `#include`. When NVAPI is used explicitly this is still the case - the NVAPI headers are consumed by Slang, and then Slang will output HLSL that does not contain any `#include`.
57+
58+
The astute reader may have noticed that the new default Slang HLSL prelude *does* contain an include. So when outputs NVAPI calls from implicit use, this #include will be enabled.
59+
60+
```
61+
#ifdef SLANG_HLSL_ENABLE_NVAPI
62+
#include "nvHLSLExtns.h"
63+
#endif
64+
```
65+
66+
This means that the *downstream* compiler (such as DXC and FXC) must be able to handle this include.
67+
68+
As it turns out all the includes specified to Slang (via command line -I or through the API), are passed down to the include handlers for FXC and DXC.
69+
70+
In the simplest use case where the path to `nvHLSLExtns.h` is specified in the include paths everything should 'just work' - as both Slang and the downstream compilers will see these include paths and so can handle the include.
71+
72+
Things are more complicated if there is mixed implicit/explitic NVAPI usage and in the Slang source the include path is set up such that NVAPI is included with
73+
74+
```
75+
#include "nvapi/nvHLSLExtns.h"
76+
```
77+
78+
This won't work directly with the implicit usage, as the downstream compiler includes as `"nvHLSLExtns.h"`. One way to work around this by altering the HLSL prelude such as the same `#include` is used.
79+
80+
Links
81+
-----
82+
83+
More details on how this works can be found in the following PR
84+
85+
* [Simplify workflow when using NVAPI #1556](https://github.com/shader-slang/slang/pull/1556)

docs/target-compatibility.md

+4-29
Original file line numberDiff line numberDiff line change
@@ -193,45 +193,20 @@ void RWByteAddressBuffer::InterlockedAddI64(uint byteAddress, int64_t valueToAdd
193193
194194
void RWByteAddressBuffer::InterlockedCompareExchangeU64(uint byteAddress, uint64_t compareValue, uint64_t value, out uint64_t outOriginalValue);
195195
196+
uint64_t RWByteAddressBuffer::InterlockedExchangeU64(uint byteAddress, uint64_t value);
197+
196198
uint64_t RWByteAddressBuffer::InterlockedMaxU64(uint byteAddress, uint64_t value);
197199
uint64_t RWByteAddressBuffer::InterlockedMinU64(uint byteAddress, uint64_t value);
198200
199201
uint64_t RWByteAddressBuffer::InterlockedAndU64(uint byteAddress, uint64_t value);
200202
uint64_t RWByteAddressBuffer::InterlockedOrU64(uint byteAddress, uint64_t value);
201203
uint64_t RWByteAddressBuffer::InterlockedXorU64(uint byteAddress, uint64_t value);
202-
```
203-
204-
On HLSL based targets this functionality is achieved using [NVAPI](https://developer.nvidia.com/nvapi). For this to work it is necessary to have NVAPI available on your system. The 'prelude' functionality in the Slang API allows for text to be inserted before any Slang code generated code is output. If the input source uses an NVAPI feature - like the methods above - it will output code that *assumes* that `nvHLSLExtns.h` is included. The following code from `render-test-main.cpp` sets up a suitable prelude for HLSL that includes `nvHLSLExtns.h` with an absolute path.
205-
206-
```
207-
String rootPath;
208-
SLANG_RETURN_ON_FAIL(TestToolUtil::getRootPath(exePath, rootPath));
209-
210-
String includePath;
211-
SLANG_RETURN_ON_FAIL(TestToolUtil::getIncludePath(rootPath, "external/nvapi/nvHLSLExtns.h", includePath));
212204
213-
StringBuilder buf;
214-
// We have to choose a slot that NVAPI will use.
215-
buf << "#define NV_SHADER_EXTN_SLOT " << options.nvapiRegister << "\n";
216-
217-
// Include the NVAPI header
218-
buf << "#include \"" << includePath << "\"\n\n";
219-
220-
session->setLanguagePrelude(SLANG_SOURCE_LANGUAGE_HLSL, buf.getBuffer());
221-
```
222-
223-
This sets the HLSL prelude to something like...
224205
225206
```
226-
#define NV_SHADER_EXTN_SLOT u0
227-
#include "d:/path/to/nvapi/nvHLSLExtns.h"
228-
```
229-
230-
Note the use of the *absolute* path to the file `nvHLSLExtns.h`. Doing so means the other includes that `nvHLSLExtns.h` includes look in the correct place without having to set up special include paths. As is required by using NVAPI, before the include it is necessary to specify what UAV will be used.
231-
232-
To use NVAPI it is nessary to specify a unordered access views (UAV) based 'u' register that will be used to communicate with NVAPI.
233207

234-
Note! Slang does not do any special handling around this, it will be necessary for application code to ensure the UAV is either guarenteed to not collide with what Slang assigns, or it's specified (but not used) in the Slang source. The u register number has to be specified also to the NVAPI runtime library.
208+
On HLSL based targets this functionality is achieved using [NVAPI](https://developer.nvidia.com/nvapi). Support for NVAPI is described
209+
in the separate [NVAPI Support](nvapi-support.md) document.
235210

236211
On Vulkan, for float the [`GL_EXT_shader_atomic_float`](https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_EXT_shader_atomic_float.html) extension is required. For int64 the [`GL_EXT_shader_atomic_int64`](https://raw.githubusercontent.com/KhronosGroup/GLSL/master/extensions/ext/GL_EXT_shader_atomic_int64.txt) extension is required.
237212

0 commit comments

Comments
 (0)