[llvm] [DirectX] Documenting Root Signature Binary representation (PR #131011)
Finn Plummer via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 13 11:20:04 PDT 2025
================
@@ -400,3 +400,258 @@ SFI0 Part
The SFI0 part encodes a 64-bit unsigned integer bitmask of the feature flags.
This denotes which optional features the shader requires. The flag values are
defined in `llvm/include/llvm/BinaryFormat/DXContainerConstants.def <https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/BinaryFormat/DXContainerConstants.def>`_.
+
+Root Signature (RTS0) Part
+--------------------------
+.. _RTS0:
+
+The Root Signature defines the interface between the shader and the pipeline,
+specifying which resources are bound to the shader and how they are accessed.
+This structure serves as a contract between the application and the GPU,
+establishing a layout for resource binding that both the shader compiler and
+the runtime can understand.
+
+The Root Signature consists of a header followed by a collection of root parameters
+and static samplers. The structure uses a versioned design with offset-based references
+to allow for flexible serialization and deserialization.
+
+Root Signature Header
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+ struct RootSignatureHeader {
+ uint32_t Version;
+ uint32_t NumParameters;
+ uint32_t ParametersOffset;
+ uint32_t NumStaticSamplers;
+ uint32_t StaticSamplerOffset;
+ uint32_t Flags;
+ }
+
+
+The `RootSignatureHeader` structure contains the top-level information about a root signature:
+
+#. **Version**: Specifies the version of the root signature format. This allows for backward
+ compatibility as the format evolves.
+#. **NumParameters**: The number of root parameters contained in this root signature.
+#. **ParametersOffset**: Byte offset from the beginning of RST0 section to the array of root
+ parameters header.
+#. **NumStaticSamplers**: The number of static samplers defined in the root signature.
+#. **StaticSamplerOffset**: Byte offset to the array of static samplers.
+#. **Flags**: Bit flags that define global behaviors for the root signature, such as whether
+ to deny vertex shader access to certain resources.
+
+This header allows readers to navigate the binary representation of the root signature by
+providing counts and offsets to locate each component within the serialized data.
+
+Root Parameter Header
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: c
+
+ struct RootParameterHeader {
+ dxbc::RootParameterType ParameterType;
+ dxbc::ShaderVisibility ShaderVisibility;
+ uint32_t ParameterOffset;
+ };
+
+
+Each root parameter in the signature is preceded by a `RootParameterHeader` that describes
+the parameter's basic attributes:
+
+#. **ParameterType**: Enumeration indicating what type of parameter this is (e.g., descriptor
+ table, constants, CBV, SRV, UAV).
+#. **ShaderVisibility**: Specifies which shader stages can access this parameter (e.g., all stages,
+ vertex shader only, pixel shader only).
+#. **ParameterOffset**: Byte offset to the specific parameter data structure
+ for this entry.
+
+The header uses a parameter type field rather than encoding the version of the parameter through
+size, allowing for a more explicit representation of the parameter's nature.
+
+Root Parameters
+~~~~~~~~~~~~~~~
+
+The Root Parameters section contains structured definitions for each type of root parameter that can
+be included in a root signature. Each structure corresponds to a specific parameter type as identified
+by the ``ParameterType`` field in the ``RootParameterHeader``.
+
+Root Constants
+~~~~~~~~~~~~~~
+
+.. code-block:: cpp
+
+ struct RootConstants {
+ uint32_t ShaderRegister;
+ uint32_t RegisterSpace;
+ uint32_t Num32BitValues;
+ };
+
+The ``RootConstants`` structure represents inline root constants that are directly embedded in the root
+signature and passed to the shader without requiring a constant buffer resource:
+
+#. **ShaderRegister**: The shader register (b#) where these constants are bound.
+#. **RegisterSpace**: The register space used for the binding.
+#. **Num32BitValues**: The number of 32-bit values included in this constant buffer.
+
+Root constants provide a fast way to pass small amounts of data directly to the shader without the
+overhead of creating and binding a constant buffer resource.
+
+Root Descriptor
+~~~~~~~~~~~~~~~
+
+Root descriptors provide a mechanism for binding individual resources to shader stages in the Direct3D 12
+rendering pipeline. They allow applications to specify how shader stages access specific GPU resources.
+
+.. code-block:: cpp
+
+ enum RootDescriptorFlags {
+ None = 0,
+ DataVolatile = 0x2,
+ DataStaticWhileSetAtExecute = 0x4,
+ DataStatic = 0x8,
+ }
+
+ // Version 1.0 Root Descriptor
+ struct RootDescriptor_V1_0 {
+ uint32_t ShaderRegister;
+ uint32_t RegisterSpace;
+ };
+
+ // Version 1.1 Root Descriptor
+ struct RootDescriptor_V1_1 {
+ uint32_t ShaderRegister;
+ uint32_t RegisterSpace;
+ // Bitfield of flags from the Flags enum
+ uint32_t Flags;
+ };
+
+Version 1.1 of Root Descriptors has introduced some flags that can hint the drivers into
+performing further code optimizations. For details, check
+`Direct X documentation <https://learn.microsoft.com/en-us/windows/win32/direct3d12/root-signature-version-1-1#static-and-volatile-flags>`_.
+
+Version 1.0 Root Descriptor
+'''''''''''''''''''''''''''
+The Version 1.0 RootDescriptor_V1_0 provides basic resource binding:
+
+#. **ShaderRegister**: The shader register where the descriptor is bound.
+#. **RegisterSpace**: The register space used for the binding.
+
+Version 1.1 Root Descriptor
+'''''''''''''''''''''''''''
+The Version 1.1 RootDescriptor_V1_1 extends the base structure with the following additional fields:
+
+#. **Flags**: Provides additional metadata about the descriptor's usage pattern.
+
+Root Descriptor Table
+~~~~~~~~~~~~~~~~~~~~~
+
+Descriptor tables function as containers that hold references to descriptors in descriptor heaps.
----------------
inbelic wrote:
Can we specify what the order of layout is here. Is the `RootDescriptorTable` struct also first/last? Can it be in any order? Is there any enforced order on the `DescriptorRange`s (I assume no but that is also noteworthy)
https://github.com/llvm/llvm-project/pull/131011
More information about the llvm-commits
mailing list