| # Root Signatures | |
| ```{toctree} | |
| :hidden: true | |
| ``` | |
| ## Overview | |
| A root signature is used to describe what resources a shader needs access to | |
| and how they're organized and bound in the pipeline. The DirectX Container | |
| (DXContainer) contains a root signature part (RTS0), which stores this | |
| information in a binary format. To assist with the construction of, and | |
| interaction with, a root signature is represented as metadata | |
| (`dx.rootsignatures` ) in the LLVM IR. The metadata can then be converted to | |
| its binary form, as defined in | |
| [llvm/include/llvm/llvm/Frontend/HLSL/RootSignatureMetadata.h](https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Frontend/HLSL/RootSignatureMetadata.h). | |
| This document serves as a reference for the metadata representation of a root | |
| signature for users to interface with. | |
| ## Metadata Representation | |
| Consider the reference root signature, then the following sections describe the | |
| metadata representation of this root signature and the corresponding operands. | |
| ```HLSL | |
| RootFlags(ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT), | |
| RootConstants(b0, space = 1, num32Constants = 3), | |
| CBV(b1, flags = 0), | |
| StaticSampler( | |
| filter = FILTER_MIN_MAG_POINT_MIP_LINEAR, | |
| addressU = TEXTURE_ADDRESS_BORDER, | |
| ), | |
| DescriptorTable( | |
| visibility = VISIBILITY_ALL, | |
| SRV(t0, flags = DATA_STATIC_WHILE_SET_AT_EXECUTE), | |
| UAV( | |
| numDescriptors = 5, u1, space = 10, offset = 5, | |
| flags = DATA_VOLATILE | |
| ) | |
| ) | |
| ``` | |
| :::{note} | |
| A root signature does not necessarily have a unique metadata representation. | |
| Futher, a malformed root signature can be represented in the metadata format, | |
| (eg. mixing Sampler and non-Sampler descriptor ranges), and so it is the | |
| user's responsibility to verify that it is a well-formed root signature. | |
| ::: | |
| ## Named Root Signature Table | |
| ```LLVM | |
| !dx.rootsignatures = !{!0} | |
| ``` | |
| A named metadata node, `` dx.rootsignatures` `` is used to identify the root | |
| signature table. The table itself is a list of references to function/root | |
| signature pairs. | |
| ## Function/Root Signature Pair | |
| ```LLVM | |
| !1 = !{ptr @main, !2, i32 2 } | |
| ``` | |
| The function/root signature associates a function (the first operand) with a | |
| reference to a root signature (the second operand). The root signature version | |
| (the third operand) used for validation logic and binary format follows. | |
| ## Root Signature | |
| ```LLVM | |
| !2 = !{ !3, !4, !5, !6, !7 } | |
| ``` | |
| The root signature itself simply consists of a list of references to its root | |
| signature elements. | |
| ## Root Signature Element | |
| A root signature element is identified by the first operand, which is a string. | |
| The following root signature elements are defined: | |
| | Identifier String | Root Signature Element | | |
| | ----------------- | ---------------------- | | |
| | "RootFlags" | Root Flags | | |
| | "RootConstants" | Root Constants | | |
| | "RootCBV" | Root Descriptor | | |
| | "RootSRV" | Root Descriptor | | |
| | "RootUAV" | Root Descriptor | | |
| | "StaticSampler" | Static Sampler | | |
| | "DescriptorTable" | Descriptor Table | | |
| Below is listed the representation for each type of root signature element. | |
| ## Root Flags | |
| ```LLVM | |
| !3 = { !"RootFlags", i32 1 } | |
| ``` | |
| | Description | Type | | |
| | -------------------------------------------- | ---- | | |
| | [Root Signature Flags][root signature flags] | i32 | | |
| ## Root Constants | |
| ```LLVM | |
| !4 = { !"RootConstants", i32 0, i32 1, i32 2, i32 3 } | |
| ``` | |
| | Description | Type | | |
| | -------------------------------------- | ---- | | |
| | [Shader Visibility][shader visibility] | i32 | | |
| | Shader Register | i32 | | |
| | Register Space | i32 | | |
| | Number 32-bit Values | i32 | | |
| ## Root Descriptor | |
| As noted in the table above, the first operand will denote the type of | |
| root descriptor. | |
| ```LLVM | |
| !5 = { !"RootCBV", i32 0, i32 1, i32 0, i32 0 } | |
| ``` | |
| | Description | Type | | |
| | ---------------------------------------------- | ---- | | |
| | [Shader Visibility][shader visibility] | i32 | | |
| | Shader Register | i32 | | |
| | Register Space | i32 | | |
| | [Root Descriptor Flags][root descriptor flags] | i32 | | |
| ## Static Sampler | |
| ```LLVM | |
| !6 = !{ !"StaticSampler", i32 1, i32 4, ... }; remaining operands omitted for space | |
| ``` | |
| | Description | Type | | |
| | -------------------------------------- | ----- | | |
| | [Filter][filter] | i32 | | |
| | [AddressU][addressu] | i32 | | |
| | [AddressV][addressv] | i32 | | |
| | [AddressW][addressw] | i32 | | |
| | MipLODBias | float | | |
| | MaxAnisotropy | i32 | | |
| | [ComparisonFunc][comparisonfunc] | i32 | | |
| | [BorderColor][bordercolor] | i32 | | |
| | MinLOD | float | | |
| | MaxLOD | float | | |
| | ShaderRegister | i32 | | |
| | RegisterSpace | i32 | | |
| | [Shader Visibility][shader visibility] | i32 | | |
| ## Descriptor Table | |
| A descriptor table consists of a visibility and the remaining operands are a | |
| list of references to its descriptor ranges. | |
| :::{note} | |
| The term Descriptor Table Clause is synonymous with Descriptor Range when | |
| referencing the implementation details. | |
| ::: | |
| ```LLVM | |
| !7 = { !"DescriptorTable", i32 0, !8, !9 } | |
| ``` | |
| | Description | Type | | |
| | -------------------------------------- | ---------------- | | |
| | [Shader Visibility][shader visibility] | i32 | | |
| | Descriptor Range Elements | Descriptor Range | | |
| ## Descriptor Range | |
| Similar to a root descriptor, the first operand will denote the type of | |
| descriptor range. It is one of the following types: | |
| - "CBV" | |
| - "SRV" | |
| - "UAV" | |
| - "Sampler" | |
| ```LLVM | |
| !8 = !{ !"SRV", i32 1, i32 0, i32 0, i32 -1, i32 4 } | |
| !9 = !{ !"UAV", i32 5, i32 1, i32 10, i32 5, i32 2 } | |
| ``` | |
| | Description | Type | | |
| | ------------------------------------------------ | ---- | | |
| | Number of Descriptors in Range | i32 | | |
| | Shader Register | i32 | | |
| | Register Space | i32 | | |
| | [Offset][offset] | i32 | | |
| | [Descriptor Range Flags][descriptor range flags] | i32 | | |
| [addressu]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_texture_address_mode | |
| [addressv]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_texture_address_mode | |
| [addressw]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_texture_address_mode | |
| [bordercolor]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_static_border_color> | |
| [comparisonfunc]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_comparison_func> | |
| [descriptor range flags]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_descriptor_range_flags | |
| [filter]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_filter | |
| [offset]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_descriptor_range | |
| [root descriptor flags]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_root_descriptor_flags | |
| [root signature flags]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_root_signature_flags | |
| [shader visibility]: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_shader_visibility | |