| =============== |
| Root Signatures |
| =============== |
| |
| .. contents:: |
| :local: |
| |
| .. toctree:: |
| :hidden: |
| |
| 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. |
| |
| .. code-block:: 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 |
| ========================== |
| |
| .. code-block:: 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 |
| ============================ |
| |
| .. code-block:: 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 |
| ============== |
| |
| .. code-block:: 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 |
| ========== |
| |
| .. code-block:: LLVM |
| |
| !3 = { !"RootFlags", i32 1 } |
| |
| ======================= ==== |
| Description Type |
| ======================= ==== |
| `Root Signature Flags`_ i32 |
| ======================= ==== |
| |
| .. _Root Signature Flags: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_root_signature_flags |
| |
| Root Constants |
| ============== |
| |
| .. code-block:: LLVM |
| |
| !4 = { !"RootConstants", i32 0, i32 1, i32 2, i32 3 } |
| |
| ==================== ==== |
| Description Type |
| ==================== ==== |
| `Shader Visibility`_ i32 |
| Shader Register i32 |
| Register Space i32 |
| Number 32-bit Values i32 |
| ==================== ==== |
| |
| .. _Shader Visibility: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_shader_visibility |
| |
| Root Descriptor |
| =============== |
| |
| As noted in the table above, the first operand will denote the type of |
| root descriptor. |
| |
| .. code-block:: LLVM |
| |
| !5 = { !"RootCBV", i32 0, i32 1, i32 0, i32 0 } |
| |
| ======================== ==== |
| Description Type |
| ======================== ==== |
| `Shader Visibility`_ i32 |
| Shader Register i32 |
| Register Space i32 |
| `Root Descriptor Flags`_ i32 |
| ======================== ==== |
| |
| .. _Root Descriptor Flags: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_root_descriptor_flags |
| |
| Static Sampler |
| ============== |
| |
| .. code-block:: LLVM |
| |
| !6 = !{ !"StaticSampler", i32 1, i32 4, ... }; remaining operands omitted for space |
| |
| ==================== ===== |
| Description Type |
| ==================== ===== |
| `Filter`_ i32 |
| `AddressU`_ i32 |
| `AddressV`_ i32 |
| `AddressW`_ i32 |
| MipLODBias float |
| MaxAnisotropy i32 |
| `ComparisonFunc`_ i32 |
| `BorderColor`_ i32 |
| MinLOD float |
| MaxLOD float |
| ShaderRegister i32 |
| RegisterSpace i32 |
| `Shader Visibility`_ i32 |
| ==================== ===== |
| |
| .. _Filter: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_filter |
| .. _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 |
| .. _ComparisonFunc: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_comparison_func> |
| .. _BorderColor: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_static_border_color> |
| |
| 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. |
| |
| .. code-block:: LLVM |
| |
| !7 = { !"DescriptorTable", i32 0, !8, !9 } |
| |
| ========================= ================ |
| Description Type |
| ========================= ================ |
| `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" |
| |
| .. code-block:: 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`_ i32 |
| `Descriptor Range Flags`_ i32 |
| ============================== ==== |
| |
| .. _Offset: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_descriptor_range |
| .. _Descriptor Range Flags: https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_descriptor_range_flags |