diff --git a/.github/workflows/sphinx-build-test.yml b/.github/workflows/sphinx-build-test.yml new file mode 100644 index 00000000000..e8d6d0e70b6 --- /dev/null +++ b/.github/workflows/sphinx-build-test.yml @@ -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 }} diff --git a/docs/building.md b/docs/building.md index b6e18ad2512..b135b956a5d 100644 --- a/docs/building.md +++ b/docs/building.md @@ -76,7 +76,7 @@ For non-Windows platforms ``` For Windows -```cmd +```batch emsdk.bat install latest emsdk.bat activate latest ``` diff --git a/docs/design/autodiff/ir-overview.md b/docs/design/autodiff/ir-overview.md index dd5f44f53ab..73ce06c9fbb 100644 --- a/docs/design/autodiff/ir-overview.md +++ b/docs/design/autodiff/ir-overview.md @@ -643,7 +643,8 @@ for (int i = 0; i < 10; i++) ``` After AD passes, this results in the following code: -```C + +``` //// Primal context pass. diff --git a/docs/design/stdlib-intrinsics.md b/docs/design/stdlib-intrinsics.md index 2ea50cd541f..46f08d4cc6e 100644 --- a/docs/design/stdlib-intrinsics.md +++ b/docs/design/stdlib-intrinsics.md @@ -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 + +``` // Slang code ${{{{ @@ -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 + +``` __magic_type(HLSLByteAddressBufferType) __intrinsic_type($(kIROp_HLSLByteAddressBufferType)) struct ByteAddressBuffer @@ -204,7 +206,8 @@ Used to specify the GLSL version number that is required for the subsequent decl For example -```slang + +```hlsl __glsl_version(430) ``` diff --git a/docs/language-reference/06-statements.md b/docs/language-reference/06-statements.md index 5c3b77ad457..7620bb45f6b 100644 --- a/docs/language-reference/06-statements.md +++ b/docs/language-reference/06-statements.md @@ -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 + +``` $for( in Range(, )) ``` diff --git a/docs/user-guide/03-convenience-features.md b/docs/user-guide/03-convenience-features.md index 3f659015b54..ab325a01fcd 100644 --- a/docs/user-guide/03-convenience-features.md +++ b/docs/user-guide/03-convenience-features.md @@ -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 + +```hlsl interface IVertex { property float3 position{get;} @@ -493,7 +494,8 @@ struct Vertex : 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 + +```hlsl [shader("vertex")] Vertex vertMain(VertexIn inputVertex) { @@ -604,7 +606,8 @@ to access the global descriptor heap or resource array in order to obtain the ac are not opaque handles, `DescriptorHandle` maps to `T` and will have the same size and alignment defined by the target. `DescriptorHandle` is declared as: -```slang + +```hlsl struct DescriptorHandle where T:IOpaqueDescriptor {} ``` where `IOpaqueDescriptor` is an interface implemented by all resource types, including textures, @@ -614,7 +617,8 @@ You may also write `Texture2D.Handle` as a short-hand of `DescriptorHandle` supports `operator *`, `operator ->`, and can implicitly convert to `T`, for example: -```slang + +```hlsl uniform StructuredBuffer> textures; uniform int textureIndex; @@ -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 + +```hlsl // All texture and buffer handles are defined in descriptor set 100. [vk::binding(0, 100)] __DynamicResource<__DynamicResourceKind.General> resourceHandles[]; @@ -713,7 +718,8 @@ Think about providing `getDescriptorFromHandle` as a way to override `operator-> The `IOpaqueDescriptor` interface is defined as: -```slang + +```hlsl interface IOpaqueDescriptor { /// The kind of the descriptor. @@ -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 + +```hlsl public enum BindlessDescriptorOptions { None = 0, /// Bind assuming regular binding model rules. @@ -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 + +```hlsl enum DescriptorKind { Unknown, /// Unknown descriptor kind. @@ -791,7 +799,8 @@ enum DescriptorAccess By default, the value of a `DescriptorHandle` 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 + +```hlsl void test(DescriptorHandle t) { nonuniform(t)->Sample(...); diff --git a/docs/user-guide/06-interfaces-generics.md b/docs/user-guide/06-interfaces-generics.md index 30efbada14b..e5215d2ef53 100644 --- a/docs/user-guide/06-interfaces-generics.md +++ b/docs/user-guide/06-interfaces-generics.md @@ -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 + +```hlsl interface IFoo { int getVal() { return 0; } @@ -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 + +```hlsl struct MyType2 : IFoo { // Explicitly mark `getVal` as `override` is needed diff --git a/docs/user-guide/a1-03-obfuscation.md b/docs/user-guide/a1-03-obfuscation.md index bafafee9a02..37fbed64395 100644 --- a/docs/user-guide/a1-03-obfuscation.md +++ b/docs/user-guide/a1-03-obfuscation.md @@ -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 + +```hlsl struct Thing { int a; @@ -87,7 +88,8 @@ int foo(Thing thing) In the source that uses this module -```slang + +```hlsl // This is fragile - needs match the definition in "module.slang" struct Thing { @@ -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 + +```hlsl struct Thing { int a; @@ -135,7 +138,8 @@ int foo(Thing thing) In the source that uses this module -```slang + +```hlsl // We can just declare Thing exists, as its usage is opaque. struct Thing; int foo(Thing thing); diff --git a/docs/user-guide/a1-04-interop.md b/docs/user-guide/a1-04-interop.md index 279325b407a..82c821a5852 100644 --- a/docs/user-guide/a1-04-interop.md +++ b/docs/user-guide/a1-04-interop.md @@ -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 + +``` [__requiresNVAPI] __glsl_extension(GL_EXT_shader_realtime_clock) uint2 getRealtimeClock() diff --git a/docs/user-guide/a2-01-spirv-target-specific.md b/docs/user-guide/a2-01-spirv-target-specific.md index 0f64a5e1b4a..87ca598b8b6 100644 --- a/docs/user-guide/a2-01-spirv-target-specific.md +++ b/docs/user-guide/a2-01-spirv-target-specific.md @@ -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 + +```hlsl void myVertexShader( uint instanceID : SV_InstanceID, // InstanceIndex - BaseInstance uint baseInstance : SV_StartInstanceLocation) // BaseInstance diff --git a/docs/user-guide/a2-02-metal-target-specific.md b/docs/user-guide/a2-02-metal-target-specific.md index 5d3e336db96..2ea84ce856b 100644 --- a/docs/user-guide/a2-02-metal-target-specific.md +++ b/docs/user-guide/a2-02-metal-target-specific.md @@ -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 + +```hlsl [outputtopology("triangle")] [numthreads(12, 1, 1)] void meshMain( @@ -161,7 +162,8 @@ using namespace metal; `ParameterBlock` values are translated into _Argument Buffers_ potentially containing nested resources. For example, this Slang code... -```slang + +```hlsl struct MyParameters { int x; @@ -194,7 +196,8 @@ struct MyParameters When targeting Metal, top-level nested struct parameters are automatically flattened. For example: -```slang + +```hlsl struct NestedStruct { float2 uv; @@ -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 + +```hlsl float4 main() : SV_Target { return float4(1,2,3,4); @@ -254,7 +258,8 @@ automatically performs the following conversions: For example: -```slang + +```hlsl RWTexture2D tex; tex[coord] = float2(1,2); // Automatically expanded to float4(1,2,0,0) ``` @@ -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; ``` diff --git a/source/slang/slang-doc-markdown-writer.cpp b/source/slang/slang-doc-markdown-writer.cpp index 2a215d6bd6b..ab5ca0f04d6 100644 --- a/source/slang/slang-doc-markdown-writer.cpp +++ b/source/slang/slang-doc-markdown-writer.cpp @@ -114,19 +114,19 @@ void DocMarkdownWriter::_appendAsBullets( auto& out = *m_builder; for (const auto& value : values) { - out << "#### "; if (value.decl) { // Add anchor ID for the decl. if (as(value.decl)) { - out << " getName()) << "\">"; + out << "(typeparam-" << getText(value.decl->getName()) << ")=\n"; } else { - out << " getName()) << "\">"; + out << "(decl-" << getText(value.decl->getName()) << ")=\n"; } } + out << "#### "; const String& name = value.name; auto path = findLinkForToken(m_currentPage, name); if (name.getLength()) @@ -2160,7 +2160,7 @@ String DocMarkdownWriter::translateToMarkdownWithLinks(String text, bool strictC sb.append(Path::getPathWithoutExt(Path::getRelativePath( Path::getParentDirectory(m_currentPage->path), page->path))); - sb.append(".html"); + sb.append(".md"); if (sectionName.getLength()) sb << "#" << sectionName; sb.append(")");