[clang] [llvm] [HLSL][RootSignature] Metadata generation of RootFlags, RootConstants, RootDescriptors (PR #142010)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 29 11:41:19 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)

<details>
<summary>Changes</summary>

Implements metadata generation of a Root Signature from its in-memory representation.

This pr handles RootFlags, RootConstants and RootDescriptors.

The metadata follows the format described [here](https://github.com/llvm/wg-hlsl/blob/main/proposals/0002-root-signature-in-clang.md#metadata-schema). 

- Implement `BuildRoot[Flags|Constants|Descriptors]` into `HLSLRootSignature.h`
- Add sample testcases demonstrating functionality

Note: there is no validation of metadata nodes as the `llvm::hlsl::rootsig::RootElement` that generates it will have already been validated.

First part of https://github.com/llvm/llvm-project/issues/126586.

---
Full diff: https://github.com/llvm/llvm-project/pull/142010.diff


3 Files Affected:

- (modified) clang/test/CodeGenHLSL/RootSignature.hlsl (+49-7) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+3) 
- (modified) llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp (+46) 


``````````diff
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl b/clang/test/CodeGenHLSL/RootSignature.hlsl
index 60e0dec175b8f..85f47727ce91f 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -1,16 +1,17 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: !dx.rootsignatures = !{![[#FIRST_ENTRY:]], ![[#SECOND_ENTRY:]]}
+// CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]], ![[#DT_ENTRY:]],
+// CHECK-SAME: ![[#RF_ENTRY:]], ![[#RC_ENTRY:]], ![[#RD_ENTRY:]]}
 
-// CHECK: ![[#FIRST_ENTRY]] = !{ptr @FirstEntry, ![[#EMPTY:]]}
+// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]]}
 // CHECK: ![[#EMPTY]] = !{}
 
 [shader("compute"), RootSignature("")]
 [numthreads(1,1,1)]
-void FirstEntry() {}
+void EmptyEntry() {}
 
-// CHECK: ![[#SECOND_ENTRY]] = !{ptr @SecondEntry, ![[#SECOND_RS:]]}
-// CHECK: ![[#SECOND_RS]] = !{![[#TABLE:]]}
+// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]]}
+// CHECK: ![[#DT_RS]] = !{![[#TABLE:]]}
 // CHECK: ![[#TABLE]] = !{!"DescriptorTable", i32 0, ![[#CBV:]], ![[#SRV:]]}
 // CHECK: ![[#CBV]] = !{!"CBV", i32 1, i32 0, i32 0, i32 -1, i32 4}
 // CHECK: ![[#SRV]] = !{!"SRV", i32 4, i32 42, i32 3, i32 32, i32 0}
@@ -22,10 +23,51 @@ void FirstEntry() {}
   ")"
 [shader("compute"), RootSignature(SampleDescriptorTable)]
 [numthreads(1,1,1)]
-void SecondEntry() {}
+void DescriptorTableEntry() {}
+
+// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]]}
+// CHECK: ![[#RF_RS]] = !{![[#ROOT_FLAGS:]]}
+// CHECK: ![[#ROOT_FLAGS]] = !{!"RootFlags", i32 2114}
+
+#define SampleRootFlags \
+  "RootFlags( " \
+  " Deny_Vertex_Shader_Root_Access | Allow_Stream_Output | " \
+  " sampler_heap_directly_indexed " \
+  ")"
+[shader("compute"), RootSignature(SampleRootFlags)]
+[numthreads(1,1,1)]
+void RootFlagsEntry() {}
+
+// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]]}
+// CHECK: ![[#RC_RS]] = !{![[#ROOT_CONSTANTS:]]}
+// CHECK: ![[#ROOT_CONSTANTS]] = !{!"RootConstants", i32 5, i32 1, i32 2, i32 1}
+
+#define SampleRootConstants \
+  "RootConstants(" \
+  " space = 2, " \
+  " visibility = Shader_Visibility_Pixel, " \
+  " b1, num32BitConstants = 1 " \
+  ")"
+[shader("compute"), RootSignature(SampleRootConstants)]
+[numthreads(1,1,1)]
+void RootConstantsEntry() {}
+
+// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]]}
+// CHECK: ![[#RD_RS]] = !{![[#ROOT_CBV:]], ![[#ROOT_UAV:]], ![[#ROOT_SRV:]]}
+// CHECK: ![[#ROOT_CBV]] = !{!"RootCBV", i32 0, i32 0, i32 0, i32 4}
+// CHECK: ![[#ROOT_UAV]] = !{!"RootUAV", i32 0, i32 0, i32 0, i32 2}
+// CHECK: ![[#ROOT_SRV]] = !{!"RootSRV", i32 0, i32 0, i32 0, i32 4}
+
+#define SampleRootDescriptors \
+  "CBV(b0), " \
+  "UAV(u0), " \
+  "SRV(t0)"
+[shader("compute"), RootSignature(SampleRootDescriptors)]
+[numthreads(1,1,1)]
+void RootDescriptorsEntry() {}
 
 // Sanity test to ensure no root is added for this function as there is only
 // two entries in !dx.roosignatures
 [shader("compute")]
 [numthreads(1,1,1)]
-void ThirdEntry() {}
+void NoRSEntry() {}
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index fd0abc9479469..d020dc413f0af 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -188,6 +188,9 @@ class MetadataBuilder {
 
 private:
   /// Define the various builders for the different metadata types
+  MDNode *BuildRootFlags(const RootFlags &Flags);
+  MDNode *BuildRootConstants(const RootConstants &Constants);
+  MDNode *BuildRootDescriptor(const RootDescriptor &Descriptor);
   MDNode *BuildDescriptorTable(const DescriptorTable &Table);
   MDNode *BuildDescriptorTableClause(const DescriptorTableClause &Clause);
 
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index ec0d130a6767c..cd606e61fcebf 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -171,6 +171,12 @@ void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements) {
 MDNode *MetadataBuilder::BuildRootSignature() {
   for (const RootElement &Element : Elements) {
     MDNode *ElementMD = nullptr;
+    if (const auto &Flags = std::get_if<RootFlags>(&Element))
+      ElementMD = BuildRootFlags(*Flags);
+    if (const auto &Constants = std::get_if<RootConstants>(&Element))
+      ElementMD = BuildRootConstants(*Constants);
+    if (const auto &Descriptor = std::get_if<RootDescriptor>(&Element))
+      ElementMD = BuildRootDescriptor(*Descriptor);
     if (const auto &Clause = std::get_if<DescriptorTableClause>(&Element))
       ElementMD = BuildDescriptorTableClause(*Clause);
     if (const auto &Table = std::get_if<DescriptorTable>(&Element))
@@ -187,6 +193,46 @@ MDNode *MetadataBuilder::BuildRootSignature() {
   return MDNode::get(Ctx, GeneratedMetadata);
 }
 
+MDNode *MetadataBuilder::BuildRootFlags(const RootFlags &Flags) {
+  IRBuilder<> Builder(Ctx);
+  return MDNode::get(Ctx, {
+                              MDString::get(Ctx, "RootFlags"),
+                              ConstantAsMetadata::get(
+                                  Builder.getInt32(llvm::to_underlying(Flags))),
+                          });
+}
+
+MDNode *MetadataBuilder::BuildRootConstants(const RootConstants &Constants) {
+  IRBuilder<> Builder(Ctx);
+  return MDNode::get(
+      Ctx, {
+               MDString::get(Ctx, "RootConstants"),
+               ConstantAsMetadata::get(
+                   Builder.getInt32(llvm::to_underlying(Constants.Visibility))),
+               ConstantAsMetadata::get(Builder.getInt32(Constants.Reg.Number)),
+               ConstantAsMetadata::get(Builder.getInt32(Constants.Space)),
+               ConstantAsMetadata::get(Builder.getInt32(
+                   Constants.Num32BitConstants)),
+           });
+}
+
+MDNode *MetadataBuilder::BuildRootDescriptor(const RootDescriptor &Descriptor) {
+  IRBuilder<> Builder(Ctx);
+  std::string Name;
+  llvm::raw_string_ostream OS(Name);
+  OS << "Root" << ClauseType(llvm::to_underlying(Descriptor.Type));
+  return MDNode::get(
+      Ctx, {
+               MDString::get(Ctx, OS.str()),
+               ConstantAsMetadata::get(
+                   Builder.getInt32(llvm::to_underlying(Descriptor.Visibility))),
+               ConstantAsMetadata::get(Builder.getInt32(Descriptor.Reg.Number)),
+               ConstantAsMetadata::get(Builder.getInt32(Descriptor.Space)),
+               ConstantAsMetadata::get(
+                   Builder.getInt32(llvm::to_underlying(Descriptor.Flags))),
+           });
+}
+
 MDNode *MetadataBuilder::BuildDescriptorTable(const DescriptorTable &Table) {
   IRBuilder<> Builder(Ctx);
   SmallVector<Metadata *> TableOperands;

``````````

</details>


https://github.com/llvm/llvm-project/pull/142010


More information about the cfe-commits mailing list