summaryrefslogtreecommitdiffstats
path: root/docs/user-guide
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-03-17 15:17:28 -0700
committerGitHub <noreply@github.com>2024-03-17 15:17:28 -0700
commit667e209bc714761eb2f48b65f0153574bd0b65f2 (patch)
tree62629fe386ffd42b1a099cd8cb0023f0b303f137 /docs/user-guide
parentdb60d1910e60b6955496d86daee26467b6a363f1 (diff)
Remove out of date documentation on compilation API. (#3785)
* Remove out of date documentation on compilation API. * Update toc.
Diffstat (limited to 'docs/user-guide')
-rw-r--r--docs/user-guide/07-autodiff.html9
-rw-r--r--docs/user-guide/08-compiling.md22
-rw-r--r--docs/user-guide/09-reflection.md205
-rw-r--r--docs/user-guide/toc.html11
4 files changed, 247 insertions, 0 deletions
diff --git a/docs/user-guide/07-autodiff.html b/docs/user-guide/07-autodiff.html
new file mode 100644
index 000000000..b82e23b7f
--- /dev/null
+++ b/docs/user-guide/07-autodiff.html
@@ -0,0 +1,9 @@
+<html>
+
+<head>
+<meta http-equiv="refresh" content="0; url=https://shader-slang.com/slang/user-guide/autodiff" />
+</head>
+<body>
+<p>This page has been relocated. <a href="https://shader-slang.com/slang/user-guide/autodiff">Click here for the new page.</a></p>
+</body>
+</html> \ No newline at end of file
diff --git a/docs/user-guide/08-compiling.md b/docs/user-guide/08-compiling.md
index 391fe9f83..14f12ed4a 100644
--- a/docs/user-guide/08-compiling.md
+++ b/docs/user-guide/08-compiling.md
@@ -560,6 +560,8 @@ The details of how Slang computes layout, what guarantees it makes, and how to i
Because the layout computed for shader parameters may depend on the compilation target, the `getLayout()` method actually takes a `targetIndex` parameter that is the zero-based index of the target for which layout information is being queried.
This parameter defaults to zero as a convenience for the common case where applications use only a single compilation target at runtime.
+See [Using the Reflection API] chapter for more details on the reflection API.
+
### Linking
Before generating code, you must link the program to resolve all cross-module references. This can be done by calling
@@ -596,6 +598,26 @@ The `kernelBlob` output is a `slang::IBlob` that can be used to access the gener
In many cases `kernelBlob->getBufferPointer()` can be passed directly to the appropriate graphics API to load kernel code onto a GPU.
+## Multithreading
+
+The only functions which are currently thread safe are
+
+```C++
+SlangSession* spCreateSession(const char* deprecated);
+SlangResult slang_createGlobalSession(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession);
+SlangResult slang_createGlobalSessionWithoutStdLib(SlangInt apiVersion, slang::IGlobalSession** outGlobalSession);
+ISlangBlob* slang_getEmbeddedStdLib();
+SlangResult slang::createGlobalSession(slang::IGlobalSession** outGlobalSession);
+const char* spGetBuildTagString();
+```
+
+This assumes Slang has been built with the C++ multithreaded runtime, as is the default.
+
+All other functions and methods are not [reentrant](https://en.wikipedia.org/wiki/Reentrancy_(computing)) and can only execute on a single thread. More precisely function and methods can only be called on a *single* thread at *any one time*. This means for example a global session can be used across multiple threads, as long as some synchronisation enforces that only one thread can be in a Slang call at any one time.
+
+Much of the Slang API is available through [COM interfaces](https://en.wikipedia.org/wiki/Component_Object_Model). In strict COM interfaces should be atomically reference counted. Currently *MOST* Slang API COM interfaces are *NOT* atomic reference counted. One exception is the `ISlangSharedLibrary` interface when produced from [host-callable](cpu-target.md#host-callable). It is atomically reference counted, allowing it to persist and be used beyond the original compilation and be freed on a different thread.
+
+
## Compiler Options
Both the `SessionDesc`, `TargetDesc` structures contain fields that encodes a `CompilerOptionEntry` array for additional compiler options to apply on the session or the target. In additional,
diff --git a/docs/user-guide/09-reflection.md b/docs/user-guide/09-reflection.md
new file mode 100644
index 000000000..7e4efe23b
--- /dev/null
+++ b/docs/user-guide/09-reflection.md
@@ -0,0 +1,205 @@
+---
+layout: user-guide
+permalink: /user-guide/reflection
+---
+
+Using the Reflection API
+=========================
+
+Some applications need to perform reflection on shader parameters and their layout, whether at runtime or as part of an offline compilation tool.
+The Slang API allows layout to be queried on any program object represented by an `IComponentType` using `getLayout()`:
+
+```c++
+slang::ProgramLayout* layout = program->getLayout();
+```
+
+Please see the [Compiling Code with Slang](/user-guide/compiling) section on creating program objects.
+
+Note that just as with output code, the reflection object (and all other objects queried from it) is guaranteed to live as long as the request is alive, but no longer.
+Unlike the other data, there is no easy way to save the reflection data for later user (we do not currently implement serialization for reflection data).
+Applications are encouraged to extract whatever information they need before destroying the compilation request.
+
+For convenience (since the reflection API surface area is large), the Slang API provides a C++ wrapper interface around the reflection API, and this document will show code examples using those wrappers:
+
+```c++
+slang::ShaderReflection* shaderReflection = slang::ShaderReflection::get(request);
+```
+
+## Program Reflection
+
+When looking at the whole program (`slang::ShaderReflection`) we can enumerate global-scope shader parameters:
+
+```c++
+unsigned parameterCount = shaderReflection->getParameterCount();
+for(unsigned pp = 0; pp < parameterCount; pp++)
+{
+ slang::VariableLayoutReflection* parameter =
+ shaderReflection->getParameterByIndex(pp);
+ // ...
+}
+```
+
+We can also enumerate the compile entry points, in order to inspect their parameters:
+
+```c++
+SlangUInt entryPointCount = shaderRefelction->getEntryPointCount();
+for(SlangUInt ee = 0; ee < entryPointCount; ee++)
+{
+ slang::EntryPointReflection* entryPoint =
+ shaderReflection->getEntryPointByIndex(ee);
+ // ...
+}
+```
+
+Slang's reflection API does not currently expose by-name lookup of parameters, but this is obviously a desirable feature.
+
+## Variable Layouts
+
+In the Slang reflection API, we draw a distinction between a *variable* (a particular declaration in the code), from a *variable layout* which has been laid out according to some API-specific rules.
+It is possible for the same variable (e.g., a `struct` field) to be laid out multiple times, with different results (e.g., if the same `struct` type is used both for a `cbuffer` member and a varying shader `in` parameter).
+
+For most purposes, a `VariableLayoutReflection` represents what a shading language user thinks of as a "shader parameter."
+We can query a parameter for its name:
+
+```c++
+char const* parameterName = parameter->getName();
+```
+
+An application will typically want to know where a parameter got "bound."
+In the simple case, we can query this information directly:
+
+```c++
+slang::ParameterCategory category = parameter->getCategory();
+unsigned index = parameter->getBindingIndex();
+unsigned space = parameter->getBindingSpace() + parameter->getOffset(SLANG_PARAMETER_CATEGORY_REGISTER_SPACE);
+```
+
+For a simple global-scope "resource" parameter (e.g., HLSL `Texture2D t : register(t3)`) the `category` tells what kind of resource the parameter consumes (e.g., `slang::ParameterCategory::ShaderResource`), the `index` gives the register number (`3`), and `space` gives the register "space" (`0`) as added for D3D12.
+
+In the case of SPIR-V output a binding index corresponds to the `binding` layout qualifier, and the binding space corresponds to the `set`.
+The main difference from D3D is that the `category` will usually be `slang::ParameterCategory::DescriptorTableSlot`.
+
+Textures, samplers, and constant buffers all follow this same basic pattern.
+For uniform parameters (e.g., members of an HLSL `cbuffer`), the binding "space" is unused, the category is `slang::ParameterCategory::Uniform`, and the "index" is the byte offset of the parameter in its parent.
+
+The above are the simple cases, where a parameter only consumes a single kind of resource.
+In HLSL, however, we can do things like combine textures, samplers, and uniform values in a `struct` type, so given a parameter of such a type, the reflection API needs to be able to report appropriate layout information for each of the different categories of resource.
+
+If `getCategory()` returns `slang::ParameterCategory::Mixed`, then the user can query additional information:
+
+```c++
+unsigned categoryCount = parameter->getCategoryCount();
+for(unsigned cc = 0; cc < categoryCount; cc++)
+{
+ slang::ParameterCategory category = parameter->getCategoryByIndex(cc);
+
+ size_t offsetForCategory = parameter->getOffset(category);
+ size_t spaceForCategory = parameter->getBindingSpace(category)
+ + parameter->getOffset(SLANG_PARAMETER_CATEGORY_REGISTER_SPACE);
+
+ // ...
+}
+```
+
+A loop like this lets you enumerate all of the resource types consumed by a parameter, and get a starting offset (and space) for each category.
+
+## Type Layouts
+
+Just knowing where a shader parameter *starts* is only part of the story, of course.
+We also need to know how many resources (e.g., registers, bytes of uniform data, ...) it consumes, how many elements it occupies (if it is an array), and what "sub-parameters" it might include.
+
+For these kinds of queries, we need to look at the *type layout* of a parameter:
+
+```c++
+slang::TypeLayoutReflection* typeLayout = parameter->getTypeLayout();
+```
+
+Just as with the distinction between a variable and a variable layout, a type layout represents a particular type in the source code that has been laid out according to API-specific rules.
+A single type like `float[10]` might be laid out differently in different contexts (e.g., using GLSL `std140` vs. `std430` rules).
+
+The first thing we want to know about a type is its *kind*:
+
+```c++
+slang::TypeReflection::Kind kind = typeLayout->getKind();
+```
+
+The available cases for `slang::TypeReflection::Kind` include `Scalar`, `Vector`, `Array`, `Struct`, etc.
+
+For any type layout, you can query the resources it consumes, or a particular parameter category:
+
+```c++
+// query the number of bytes of constant-buffer storage used by a type layout
+size_t sizeInBytes = typeLayout->getSize(slang::ParameterCategory::Uniform);
+
+// query the number of HLSL `t` registers used by a type layout
+size_t tRegCount = typeLayout->getSize(slang::ParameterCategory::ShaderResource);
+```
+
+## Arrays
+
+If you have a type layout with kind `Array` you can query information about the number and type of elements:
+
+```c++
+size_t arrayElementCount = typeLayout->getElementCount();
+slang::TypeLayoutReflection* elementTypeLayout = typeLayout->getElementTypeLayout();
+sie_t arrayElementStride = typeLayout->getElementStride(category);
+```
+
+An array of unknown size will currently report zero elements.
+The "stride" of an array is the amount of resources (e.g., the number of bytes of uniform data) that need to be skipped between consecutive array elements.
+This need *not* be the same as `elementTypeLayout->getSize(category)`, and there are two notable cases to be aware of:
+
+- An array in a constant buffer may have a stride larger than the element size. E.g., a `float a[10]` in a D3D or `std140` constant buffer will have 4-byte elements, but a stride of 16.
+
+- An array of resources in Vulkan will have a stride of *zero* descriptor-table slots, because the entire array is allocated a single `binding`.
+
+## Structures
+
+If you have a type layout with kind `Struct`, you can query information about the fields:
+
+```c++
+unsigned fieldCount = typeLayout->getFieldCount();
+for(unsigned ff = 0; ff < fieldCount; ff++)
+{
+ VariableLayoutReflection* field = typeLayout->getFieldByIndex(ff);
+ // ...
+}
+```
+
+Each field is represented as a full variable layout, so application code can recursively extract full information.
+
+An important caveat to be aware of when recursing into structure types like this, is that the layout information on a field is relative to the start of the parent type layout, and not absolute.
+This is perhaps not surprising in the case of `slang::ParameterCategory::Uniform`: if you ask a field in a `struct` type for its byte offset, it will return the offset from the start of the `struct`.
+
+Where this can trip up users is when a `struct` type contains fields of other categories (e.g., a structure with a `Texture2D` in it).
+In these cases, the "binding index" of a structure field in a relative offset from whatever binding index is given to the parent structure.
+
+The basic rule is that no matter what category of binding resource (bytes, registers, etc.) you are talking about, the index/offset of `a.b.c` must be computed by adding together the offsets of `a`, `b` and `c`.
+
+## Entry Points
+
+Given an `EntryPointReflection` we can query its name and stage:
+
+```c++
+char const* entryPointName = entryPoint->getName();
+SlangStage stage = entryPoint->getStage();
+```
+
+You can also enumerate the parameters of the entry point (that is, those that were written as parameters of the entry-point function):
+
+```c++
+unsigned parameterCount = entryPoint->getParameterCount();
+for(unsigned pp = 0; pp < parameterCount; pp++)
+{
+ slang::VariableLayoutReflection* parameter =
+ entryPoint->getParameterByIndex(pp);
+ // ...
+}
+```
+
+In the case of a compute shader entry point, you can also query the user-specified thread-group size (if any):
+
+```c++
+SlangUInt threadGroupSize[3];
+entryPoint->getComputeThreadGruopSize(3, &threadGroupSize[0]);
+```
diff --git a/docs/user-guide/toc.html b/docs/user-guide/toc.html
index a696a3d61..ff64ba74e 100644
--- a/docs/user-guide/toc.html
+++ b/docs/user-guide/toc.html
@@ -100,10 +100,21 @@
<li data-link="compiling#concepts"><span>Concepts</span></li>
<li data-link="compiling#command-line-compilation-with-slangc"><span>Command-Line Compilation with `slangc`</span></li>
<li data-link="compiling#using-the-compilation-api"><span>Using the Compilation API</span></li>
+<li data-link="compiling#multithreading"><span>Multithreading</span></li>
<li data-link="compiling#compiler-options"><span>Compiler Options</span></li>
<li data-link="compiling#debugging"><span>Debugging</span></li>
</ul>
</li>
+<li data-link="reflection"><span>Using the Reflection API</span>
+<ul class="toc_list">
+<li data-link="reflection#program-reflection"><span>Program Reflection</span></li>
+<li data-link="reflection#variable-layouts"><span>Variable Layouts</span></li>
+<li data-link="reflection#type-layouts"><span>Type Layouts</span></li>
+<li data-link="reflection#arrays"><span>Arrays</span></li>
+<li data-link="reflection#structures"><span>Structures</span></li>
+<li data-link="reflection#entry-points"><span>Entry Points</span></li>
+</ul>
+</li>
<li data-link="targets"><span>Supported Compilation Targets</span>
<ul class="toc_list">
<li data-link="targets#background-and-terminology"><span>Background and Terminology</span></li>