Skip to content
85 changes: 85 additions & 0 deletions .github/workflows/sphinx-build-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Build Sphinx Documentation

on:
pull_request:
branches: [master]

jobs:
sphinx-build:
runs-on: ubuntu-latest
steps:
- name: Checkout shader-slang.github.io main branch
uses: actions/checkout@v4
with:
repository: aidanfnv/shader-slang.github.io
ref: fix/sphinx-warnings
path: docs-site
submodules: recursive

- name: Remove existing slang directory if present
run: rm -rf docs-site/docs/external/slang

- name: Checkout slang PR branch as submodule
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
repository: ${{ github.head_repository.full_name }}
path: docs-site/docs/external/slang
submodules: recursive

- name: Backup existing core-module-reference index.md
run: |
if [ -f docs-site/docs/external/core-module-reference/index.md ]; then
cp docs-site/docs/external/core-module-reference/index.md /tmp/core-module-index.md
fi

- name: Remove existing core-module-reference directory
run: rm -rf docs-site/docs/external/core-module-reference

- name: Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -y ninja-build libx11-dev

- name: Build slangc from PR
run: |
cd docs-site/docs/external/slang
# Disable LLVM for faster build since we only need slangc for docs
cmake --preset default --fresh -DSLANG_SLANG_LLVM_FLAVOR=DISABLE
cmake --build --preset release --target slangc

- name: Generate core module reference from PR
run: |
cd docs-site/docs/external
mkdir -p core-module-reference
cd core-module-reference
# Generate the core module documentation
../slang/build/Release/bin/slangc -compile-core-module -doc
# Restore the original index.md
cp /tmp/core-module-index.md index.md

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
cache: "pip"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r docs-site/requirements.txt

- name: Build Sphinx Documentation
run: |
cd docs-site/docs
# Run Sphinx build to catch issues
# -D build_toctree=True enables toctree processing to verify all docs are included
python -m sphinx -W -b html . _build/html

- name: Check for broken links to external sites
run: |
cd docs-site/docs
# Run linkcheck builder to find broken links
python -m sphinx -b linkcheck . _build/linkcheck
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2 changes: 1 addition & 1 deletion docs/building.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ For non-Windows platforms
```

For Windows
```cmd
```batch
emsdk.bat install latest
emsdk.bat activate latest
```
Expand Down
3 changes: 2 additions & 1 deletion docs/design/autodiff/ir-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,8 @@ for (int i = 0; i < 10; i++)
```

After AD passes, this results in the following code:
```C
<!-- This fails to be parsed by the "C" lexer -->
```

//// Primal context pass.

Expand Down
9 changes: 6 additions & 3 deletions docs/design/stdlib-intrinsics.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ The `.meta.slang` files look largely like Slang source files, but their contents

As an example, to produce an an array with values 0 to 9 we could write...

```slang
<!-- There is no "slang" lexer, and "hlsl" does not work here either -->
```

// Slang code
${{{{
Expand Down Expand Up @@ -142,7 +143,8 @@ Used to specify the IR opcode associated with a type. The IR opcode is listed as

As an example from the core module

```slang
<!-- There is no "slang" lexer, and "hlsl" does not work here either -->
```
__magic_type(HLSLByteAddressBufferType)
__intrinsic_type($(kIROp_HLSLByteAddressBufferType))
struct ByteAddressBuffer
Expand Down Expand Up @@ -204,7 +206,8 @@ Used to specify the GLSL version number that is required for the subsequent decl

For example

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
__glsl_version(430)
```

Expand Down
3 changes: 2 additions & 1 deletion docs/language-reference/06-statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ Compile-Time For Statement
A _compile-time for statement_ is used as an alternative to preprocessor techniques for loop unrolling.
It looks like:

```hlsl
<!-- The "hlsl" lexer does not work here -->
```
$for( <name> in Range(<initial-value>, <upper-bound>)) <body statement>
```

Expand Down
27 changes: 18 additions & 9 deletions docs/user-guide/03-convenience-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,8 @@ specialized shader variant when it is not used by the shader.

For example, a common use case is to define the vertex shader output / fragment shader input:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
interface IVertex
{
property float3 position{get;}
Expand Down Expand Up @@ -493,7 +494,8 @@ struct Vertex<bool hasNormal, bool hasColor> : IVertex
In this example, `Vertex` type is parameterized on `hasNormal` and `hasColor`. If `hasNormal` is false, the `m_normal` field will be eliminated in the target code, allowing a specialized vertex shader to declare minimum output fields. For example, a vertex shader
can be defined as follows:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
[shader("vertex")]
Vertex<hasNormal, hasColor> vertMain<bool hasNormal, bool hasColor>(VertexIn inputVertex)
{
Expand Down Expand Up @@ -604,7 +606,8 @@ to access the global descriptor heap or resource array in order to obtain the ac
are not opaque handles, `DescriptorHandle<T>` maps to `T` and will have the same size and alignment defined by the target.

`DescriptorHandle<T>` is declared as:
```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
struct DescriptorHandle<T> where T:IOpaqueDescriptor {}
```
where `IOpaqueDescriptor` is an interface implemented by all resource types, including textures,
Expand All @@ -614,7 +617,8 @@ You may also write `Texture2D.Handle` as a short-hand of `DescriptorHandle<Textu

`DescriptorHandle<T>` supports `operator *`, `operator ->`, and can implicitly convert to `T`, for example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
uniform StructuredBuffer<DescriptorHandle<Texture2D>> textures;
uniform int textureIndex;

Expand Down Expand Up @@ -683,7 +687,8 @@ Default behavior assigns binding-indicies based on descriptor types:
Users can override the default behavior of convering from bindless handle to resource handle, by providing a
`getDescriptorFromHandle` in user code. For example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
// All texture and buffer handles are defined in descriptor set 100.
[vk::binding(0, 100)]
__DynamicResource<__DynamicResourceKind.General> resourceHandles[];
Expand Down Expand Up @@ -713,7 +718,8 @@ Think about providing `getDescriptorFromHandle` as a way to override `operator->

The `IOpaqueDescriptor` interface is defined as:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
interface IOpaqueDescriptor
{
/// The kind of the descriptor.
Expand All @@ -726,7 +732,8 @@ The user can call `defaultGetDescriptorFromHandle` function from their implement
`getDescriptorFromHandle` to dispatch to the default behavior.

Additionally, `defaultGetDescriptorFromHandle()` takes an optional argument whose type is `constexpr BindlessDescriptorOptions`. This parameter allows to specify alternative standard presets for how bindless-indexes are assigned. Note that this is currently only relevant to SPIRV:
```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
public enum BindlessDescriptorOptions
{
None = 0, /// Bind assuming regular binding model rules.
Expand Down Expand Up @@ -765,7 +772,8 @@ public enum BindlessDescriptorOptions
The `kind` and `descriptorAccess` constants allows user code to fetch resources from different locations depending on the type and access of the resource being requested. The `DescriptorKind` and
`DescriptorAccess` enums are defined as:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
enum DescriptorKind
{
Unknown, /// Unknown descriptor kind.
Expand All @@ -791,7 +799,8 @@ enum DescriptorAccess
By default, the value of a `DescriptorHandle<T>` object is assumed to be dynamically uniform across all
execution threads. If this is not the case, the user is required to mark the `DescriptorHandle` as `nonuniform`
*immediately* before dereferencing it:
```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
void test(DescriptorHandle<Texture2D> t)
{
nonuniform(t)->Sample(...);
Expand Down
6 changes: 4 additions & 2 deletions docs/user-guide/06-interfaces-generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ In this case, the definition of `MyType` must satisfy the requirements from both

Interface methods can have a default implementation, which will be used if a conforming type doesn't provide an overriding implementation. For example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
interface IFoo
{
int getVal() { return 0; }
Expand All @@ -60,7 +61,8 @@ struct MyType : IFoo {}

A concrete type that provides its overriding implementation to an interface method requirement that has a default implementation must be explicitly marked as 'override'. For example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
struct MyType2 : IFoo
{
// Explicitly mark `getVal` as `override` is needed
Expand Down
12 changes: 8 additions & 4 deletions docs/user-guide/a1-03-obfuscation.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ This means that `-r` is *NOT* enough to be able access the functionality of the

For example, in "module.slang"

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
struct Thing
{
int a;
Expand All @@ -87,7 +88,8 @@ int foo(Thing thing)

In the source that uses this module

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
// This is fragile - needs match the definition in "module.slang"
struct Thing
{
Expand Down Expand Up @@ -115,7 +117,8 @@ void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)

If the type `Thing` is only used opaquely then it would only be necessary to declare that it exists. For example in "module-opaque.slang"

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
struct Thing
{
int a;
Expand All @@ -135,7 +138,8 @@ int foo(Thing thing)

In the source that uses this module

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
// We can just declare Thing exists, as its usage is opaque.
struct Thing;
int foo(Thing thing);
Expand Down
3 changes: 2 additions & 1 deletion docs/user-guide/a1-04-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ The strings in `__requirePrelude` are deduplicated: the same prelude string will

## Managing Cross-Platform Code
If you are defining an intrinsic function that maps to multiple targets in different ways, you can use `__target_switch` construct to manage the target-specific definitions. For example, here is a snippet from the Slang core module that defines `getRealtimeClock`:
```hlsl
<!-- The "hlsl" lexer does not work here -->
```
[__requiresNVAPI]
__glsl_extension(GL_EXT_shader_realtime_clock)
uint2 getRealtimeClock()
Expand Down
3 changes: 2 additions & 1 deletion docs/user-guide/a2-01-spirv-target-specific.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ This matches the behavior of D3D where `SV_InstanceID` and `SV_VertexID` starts
If you need direct access to `InstanceIndex` and `VertexIndex` values, use `SV_VulkanInstanceID` and `SV_VulkanVertexID` semantic names. These are supported for all targets except HLSL.
Alternatively you can use parameters with `SV_InstanceID`(or `SV_VertexID`) and `SV_StartInstanceLocation`(or `SV_StartVertexLocation`) semantics:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
void myVertexShader(
uint instanceID : SV_InstanceID, // InstanceIndex - BaseInstance
uint baseInstance : SV_StartInstanceLocation) // BaseInstance
Expand Down
17 changes: 11 additions & 6 deletions docs/user-guide/a2-02-metal-target-specific.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,8 @@ the translation of matrix operations to maintain correct semantics:

Mesh shaders can be targeted using the following types and syntax. The same as task/mesh shaders generally in Slang.

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
[outputtopology("triangle")]
[numthreads(12, 1, 1)]
void meshMain(
Expand Down Expand Up @@ -161,7 +162,8 @@ using namespace metal;
`ParameterBlock` values are translated into _Argument Buffers_ potentially
containing nested resources. For example, this Slang code...

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
struct MyParameters
{
int x;
Expand Down Expand Up @@ -194,7 +196,8 @@ struct MyParameters
When targeting Metal, top-level nested struct parameters are automatically
flattened. For example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
struct NestedStruct
{
float2 uv;
Expand Down Expand Up @@ -223,7 +226,8 @@ struct InputStruct
Non-struct return values from entry points are automatically wrapped in a
struct with appropriate semantics. For example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
float4 main() : SV_Target
{
return float4(1,2,3,4);
Expand Down Expand Up @@ -254,7 +258,8 @@ automatically performs the following conversions:

For example:

```slang
<!-- There is no "slang" lexer, so "hlsl" will be used here instead -->
```hlsl
RWTexture2D<float2> tex;
tex[coord] = float2(1,2); // Automatically expanded to float4(1,2,0,0)
```
Expand Down Expand Up @@ -298,7 +303,7 @@ const int a = 2;

Translates to:

```metal
```csharp
constant int fc_a_0 [[function_constant(7)]];
constant int a_0 = is_function_constant_defined(fc_a_0) ? fc_a_0 : 2;
```
Loading
Loading