From b8d178e455a37e8322a8576cb2b49d674a3d11f9 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Mon, 15 Apr 2024 13:41:12 -0700 Subject: [PATCH 1/4] [Doc][DirectX backend] Add documentation for root signature This patch adds documentation for root signature serialization format. For issue #55116 --- llvm/docs/DirectX/RootSignature.rst | 190 ++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 llvm/docs/DirectX/RootSignature.rst diff --git a/llvm/docs/DirectX/RootSignature.rst b/llvm/docs/DirectX/RootSignature.rst new file mode 100644 index 0000000000000..9611cb0150de3 --- /dev/null +++ b/llvm/docs/DirectX/RootSignature.rst @@ -0,0 +1,190 @@ +=================================== +Root Signature Serialization format +=================================== + +.. contents:: + :local: + +Serialized format +================= + +The root signature will be serialized into a binary format and saved in 'RTS0' +part of DXContainer. +The binary format is a sequence of bytes that can be used to create a root +signature object in the Direct3D 12 API. The binary format is defined by the +`D3D12_ROOT_SIGNATURE_DESC (for rootsig_1_0) +`_ +or `D3D12_ROOT_SIGNATURE_DESC1 (for rootsig_1_1) +`_ +structure in the Direct3D 12 API. (With the pointers translated to offsets.) + +It will be look like this: + +.. code-block:: c++ + + namespace dxbc { + namespace SerializedRootSignature { + namespace v_1_0 { + + struct DxilContainerDescriptorRange { + uint32_t RangeType; + uint32_t NumDescriptors; + uint32_t BaseShaderRegister; + uint32_t RegisterSpace; + uint32_t OffsetInDescriptorsFromTableStart; + }; + + struct ContainerRootDescriptor { + uint32_t ShaderRegister; + uint32_t RegisterSpace; + }; + } + namespace v_1_1 { + + struct ContainerDescriptorRange { + uint32_t RangeType; + uint32_t NumDescriptors; + uint32_t BaseShaderRegister; + uint32_t RegisterSpace; + uint32_t Flags; + uint32_t OffsetInDescriptorsFromTableStart; + }; + + struct ContainerRootDescriptor { + uint32_t ShaderRegister; + uint32_t RegisterSpace; + uint32_t Flags; + }; + } + + struct ContainerRootDescriptorTable { + uint32_t NumDescriptorRanges; + uint32_t DescriptorRangesOffset; + }; + + struct RootConstants { + uint32_t ShaderRegister; + uint32_t RegisterSpace = 0; + uint32_t Num32BitValues; + }; + + struct ContainerRootParameter { + uint32_t ParameterType; + uint32_t ShaderVisibility; + uint32_t PayloadOffset; + }; + + struct StaticSamplerDesc { + Filter Filter = Filter::ANISOTROPIC; + TextureAddressMode AddressU = TextureAddressMode::Wrap; + TextureAddressMode AddressV = TextureAddressMode::Wrap; + TextureAddressMode AddressW = TextureAddressMode::Wrap; + float MipLODBias = 0.f; + uint32_t MaxAnisotropy = 16; + ComparisonFunc ComparisonFunc = ComparisonFunc::LessEqual; + StaticBorderColor BorderColor = StaticBorderColor::OpaqueWhite; + float MinLOD = 0.f; + float MaxLOD = MaxLOD; + uint32_t ShaderRegister; + uint32_t RegisterSpace = 0; + ShaderVisibility ShaderVisibility = ShaderVisibility::All; + }; + + struct ContainerRootSignatureDesc { + uint32_t Version; + uint32_t NumParameters; + uint32_t RootParametersOffset; + uint32_t NumStaticSamplers; + uint32_t StaticSamplersOffset; + uint32_t Flags; + }; + } + } + + +The binary representation begins with a **ContainerRootSignatureDesc** +object. + +The object is succeeded by an array of **ContainerRootParameter** objects +located at **ContainerRootSignatureDesc::RootParametersOffset**, which +corresponds to the size of **ContainerRootSignatureDesc**. + +Next, there is an array of **StaticSamplerDesc** at +**ContainerRootSignatureDesc::StaticSamplersOffset**. + +Following this, an array of **ContainerDescriptorRange** is presented, +which encompasses the descriptor ranges for all +**ContainerRootDescriptorTable** objects. + +Subsequently, a detailed object (**RootConstants**, +**ContainerRootDescriptorTable**, or +**ContainerRootDescriptor**, depending on the parameter +type) for each **ContainerRootParameter** in the **ContainerRootParameter** +array. With **ContainerRootParameter.PayloadOffset** pointing to the +detailed object. + +In cases where the detailed object is a **ContainerRootDescriptorTable**, +**ContainerRootDescriptorTable.DescriptorRangesOffset** will point to an array +of **ContainerDescriptorRange**. + +.. code-block:: + + #define RS "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \ + "DENY_VERTEX_SHADER_ROOT_ACCESS), " \ + "CBV(b0, space = 1, flags = DATA_STATIC), " \ + "SRV(t0), " \ + "UAV(u0), " \ + "DescriptorTable( CBV(b1), " \ + " SRV(t1, numDescriptors = 8, " \ + " flags = DESCRIPTORS_VOLATILE), " \ + " UAV(u1, numDescriptors = unbounded, " \ + " flags = DESCRIPTORS_VOLATILE)), " \ + "DescriptorTable(Sampler(s0, space=1, numDescriptors = 4)), " \ + "RootConstants(num32BitConstants=3, b10), " \ + "StaticSampler(s1)," \ + "StaticSampler(s2, " \ + " addressU = TEXTURE_ADDRESS_CLAMP, " \ + " filter = FILTER_MIN_MAG_MIP_LINEAR )" + + [RootSignature(MyRS)] + float4 main(float4 coord : COORD) : SV_Target + { + … + } + + +The layout could be look like this for the MyRS in above example: + +.. code-block:: c++ + + struct SerializedRS { + ContainerRootSignatureDesc RSDesc; + ContainerRootParameter rootParameters[6]; + StaticSamplerDesc samplers[2]; + + ContainerDescriptorRange ranges[3]; + + // Extra part for each RootParameter in rootParameters. + // RootConstants/RootDescriptorTable/RootDescriptor dependent on ParameterType. + + struct { + + RootConstants b0; + + ContainerRootDescriptor t1; + + ContainerRootDescriptor u1; + + ContainerRootDescriptor tab0; // tab0.DescriptorRangesOffset points to ranges[0] + // tab0.NumDescriptorRanges = 2 + + ContainerRootDescriptor tab1; // tab1.DescriptorRangesOffset points to ranges[2] + // tab1.NumDescriptorRanges = 1 + + RootConstants b10; + + }; + + + }; + From a62120913d44cc4298a468d0de4df9159f5380b6 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Mon, 15 Apr 2024 13:46:17 -0700 Subject: [PATCH 2/4] Link root signature doc --- llvm/docs/DirectXUsage.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/docs/DirectXUsage.rst b/llvm/docs/DirectXUsage.rst index 79543e19bd34b..4b0fefd26540c 100644 --- a/llvm/docs/DirectXUsage.rst +++ b/llvm/docs/DirectXUsage.rst @@ -14,6 +14,7 @@ User Guide for the DirectX Target :hidden: DirectX/DXILArchitecture + DirectX/RootSignature Introduction ============ From df3ad05505fe10fd7c63c07b7c4672c4049ea1de Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Mon, 15 Apr 2024 22:59:36 -0400 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Damyan Pepper --- llvm/docs/DirectX/RootSignature.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/docs/DirectX/RootSignature.rst b/llvm/docs/DirectX/RootSignature.rst index 9611cb0150de3..ba7eaa3c45c1d 100644 --- a/llvm/docs/DirectX/RootSignature.rst +++ b/llvm/docs/DirectX/RootSignature.rst @@ -18,7 +18,7 @@ or `D3D12_ROOT_SIGNATURE_DESC1 (for rootsig_1_1) `_ structure in the Direct3D 12 API. (With the pointers translated to offsets.) -It will be look like this: +It will look like this: .. code-block:: c++ @@ -105,7 +105,7 @@ It will be look like this: The binary representation begins with a **ContainerRootSignatureDesc** object. -The object is succeeded by an array of **ContainerRootParameter** objects +The object is followed by an array of **ContainerRootParameter** objects located at **ContainerRootSignatureDesc::RootParametersOffset**, which corresponds to the size of **ContainerRootSignatureDesc**. From 5af32b3686b32573e2008c50eaa384fac27a7c6b Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 16 Apr 2024 07:57:23 -0700 Subject: [PATCH 4/4] Fix the type for layout. --- llvm/docs/DirectX/RootSignature.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/docs/DirectX/RootSignature.rst b/llvm/docs/DirectX/RootSignature.rst index ba7eaa3c45c1d..34baed674dccd 100644 --- a/llvm/docs/DirectX/RootSignature.rst +++ b/llvm/docs/DirectX/RootSignature.rst @@ -169,16 +169,16 @@ The layout could be look like this for the MyRS in above example: struct { - RootConstants b0; + ContainerRootDescriptor b0; ContainerRootDescriptor t1; ContainerRootDescriptor u1; - ContainerRootDescriptor tab0; // tab0.DescriptorRangesOffset points to ranges[0] + ContainerRootDescriptorTable tab0; // tab0.DescriptorRangesOffset points to ranges[0] // tab0.NumDescriptorRanges = 2 - ContainerRootDescriptor tab1; // tab1.DescriptorRangesOffset points to ranges[2] + ContainerRootDescriptorTable tab1; // tab1.DescriptorRangesOffset points to ranges[2] // tab1.NumDescriptorRanges = 1 RootConstants b10;