
This pr adds documentation of root signatures for reference of an LLVM user. The target audience is an LLVM user that wants to build a custom tool, or front-end, that requires constructing a root signature part (RTS0) for a `DXContainer`. With that in mind, this pr adds documentation of the metadata representation of root signatures implemented in LLVM and utilized in Clang.
246 lines
7.2 KiB
ReStructuredText
246 lines
7.2 KiB
ReStructuredText
===============
|
|
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
|