Root Signatures#
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.
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#
!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#
!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#
!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#
!3 = { !"RootFlags", i32 1 }
Description |
Type |
|---|---|
i32 |
Root Constants#
!4 = { !"RootConstants", i32 0, i32 1, i32 2, i32 3 }
Description |
Type |
|---|---|
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.
!5 = { !"RootCBV", i32 0, i32 1, i32 0, i32 0 }
Description |
Type |
|---|---|
i32 |
|
Shader Register |
i32 |
Register Space |
i32 |
i32 |
Static Sampler#
!6 = !{ !"StaticSampler", i32 1, i32 4, ... }; remaining operands omitted for space
Description |
Type |
|---|---|
i32 |
|
i32 |
|
i32 |
|
i32 |
|
MipLODBias |
float |
MaxAnisotropy |
i32 |
i32 |
|
i32 |
|
MinLOD |
float |
MaxLOD |
float |
ShaderRegister |
i32 |
RegisterSpace |
i32 |
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.
!7 = { !"DescriptorTable", i32 0, !8, !9 }
Description |
Type |
|---|---|
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”
!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 |
i32 |
|
i32 |