Skip to content

[Docs][DirectX] Add relevant documentation of Root Signature #149608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 245 additions & 0 deletions llvm/docs/DirectX/RootSignatures.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
===============
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
1 change: 1 addition & 0 deletions llvm/docs/DirectXUsage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ User Guide for the DirectX Target
DirectX/DXILArchitecture
DirectX/DXILOpTableGenDesign
DirectX/DXILResources
DirectX/RootSignatures

Introduction
============
Expand Down
Loading