=============== 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 `_. 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