:hidden: true
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.
Consider the reference root signature, then the following sections describe the metadata representation of this root signature and the corresponding operands.
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. :::
!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.
!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.
!2 = !{ !3, !4, !5, !6, !7 }
The root signature itself simply consists of a list of references to its root signature elements.
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.
!3 = { !"RootFlags", i32 1 }
| Description | Type |
|---|---|
| Root Signature Flags | i32 |
!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 |
As noted in the table above, the first operand will denote the type of root descriptor.
!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 |
!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 |
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. :::
!7 = { !"DescriptorTable", i32 0, !8, !9 }
| Description | Type |
|---|---|
| Shader Visibility | i32 |
| Descriptor Range Elements | Descriptor Range |
Similar to a root descriptor, the first operand will denote the type of descriptor range. It is one of the following types:
!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 |