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. It follows the same style as: 
https://github.com/llvm/llvm-project/pull/139633.

This pr handles `StaticSamplers`. It also handles converting the else-if chain 
into a `std::visit` to allow for future compiler warnings when adding 
additional `RootElement` variants.

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 `BuildStaticSampler` 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.

Resolves https://github.com/llvm/llvm-project/issues/126586

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


3 Files Affected:

- (modified) clang/test/CodeGenHLSL/RootSignature.hlsl (+35-1) 
- (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h (+1) 
- (modified) llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp (+66-16) 


``````````diff
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl 
b/clang/test/CodeGenHLSL/RootSignature.hlsl
index 34caa3eb6b714..ca843ffbb1ced 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -emit-llvm -o - %s | 
FileCheck %s
 
 // CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]], ![[#DT_ENTRY:]],
-// CHECK-SAME: ![[#RF_ENTRY:]], ![[#RC_ENTRY:]], ![[#RD_ENTRY:]]}
+// CHECK-SAME: ![[#RF_ENTRY:]], ![[#RC_ENTRY:]], ![[#RD_ENTRY:]], 
![[#SS_ENTRY:]]}
 
 // CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]]}
 // CHECK: ![[#EMPTY]] = !{}
@@ -66,6 +66,40 @@ void RootConstantsEntry() {}
 [numthreads(1,1,1)]
 void RootDescriptorsEntry() {}
 
+// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]]}
+// CHECK: ![[#SS_RS]] = !{![[#STATIC_SAMPLER:]]}
+
+// checking filter = 0x4
+// CHECK: ![[#STATIC_SAMPLER]] = !{!"StaticSampler", i32 4,
+
+// checking texture address[U|V|W]
+// CHECK-SAME: i32 2, i32 3, i32 5,
+
+// checking mipLODBias, maxAnisotropy, comparisonFunc, borderColor
+// CHECK-SAME: float 0x40403999A0000000, i32 9, i32 3, i32 2,
+
+// checking minLOD, maxLOD
+// CHECK-SAME: float -1.280000e+02, float 1.280000e+02,
+
+// checking register, space and visibility
+// CHECK-SAME: i32 42, i32 0, i32 0}
+
+#define SampleStaticSampler \
+  "StaticSampler(s42, " \
+  " filter = FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT, " \
+  " addressU = TEXTURE_ADDRESS_MIRROR, " \
+  " addressV = TEXTURE_ADDRESS_CLAMP, " \
+  " addressW = TEXTURE_ADDRESS_MIRRORONCE, " \
+  " mipLODBias = 32.45f, maxAnisotropy = 9, " \
+  " comparisonFunc = COMPARISON_EQUAL, " \
+  " borderColor = STATIC_BORDER_COLOR_OPAQUE_WHITE, " \
+  " minLOD = -128.f, maxLOD = 128.f, " \
+  " space = 0, visibility = SHADER_VISIBILITY_ALL, " \
+  ")"
+[shader("compute"), RootSignature(SampleStaticSampler)]
+[numthreads(1,1,1)]
+void StaticSamplerEntry() {}
+
 // Sanity test to ensure no root is added for this function as there is only
 // two entries in !dx.roosignatures
 [shader("compute")]
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h 
b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
index 365197a4dfdb5..6d959ad5bdc7f 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
@@ -52,6 +52,7 @@ class MetadataBuilder {
   MDNode *BuildRootDescriptor(const RootDescriptor &Descriptor);
   MDNode *BuildDescriptorTable(const DescriptorTable &Table);
   MDNode *BuildDescriptorTableClause(const DescriptorTableClause &Clause);
+  MDNode *BuildStaticSampler(const StaticSampler &Sampler);
 
   llvm::LLVMContext &Ctx;
   ArrayRef<RootElement> Elements;
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp 
b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
index aa1f1957d9cbe..0a866374bf5dc 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
@@ -169,25 +169,44 @@ void dumpRootElements(raw_ostream &OS, 
ArrayRef<RootElement> Elements) {
   OS << "}";
 }
 
+namespace {
+
+// We use the OverloadBuild with std::visit to ensure the compiler catches if a
+// new RootElement variant type is added but it's metadata generation isn't
+// handled.
+template <class... Ts> struct OverloadedBuild : Ts... {
+  using Ts::operator()...;
+};
+template <class... Ts> OverloadedBuild(Ts...) -> OverloadedBuild<Ts...>;
+
+} // namespace
+
 MDNode *MetadataBuilder::BuildRootSignature() {
+  const auto Visitor = OverloadedBuild{
+      [this](const RootFlags &Flags) -> MDNode * {
+        return BuildRootFlags(Flags);
+      },
+      [this](const RootConstants &Constants) -> MDNode * {
+        return BuildRootConstants(Constants);
+      },
+      [this](const RootDescriptor &Descriptor) -> MDNode * {
+        return BuildRootDescriptor(Descriptor);
+      },
+      [this](const DescriptorTableClause &Clause) -> MDNode * {
+        return BuildDescriptorTableClause(Clause);
+      },
+      [this](const DescriptorTable &Table) -> MDNode * {
+        return BuildDescriptorTable(Table);
+      },
+      [this](const StaticSampler &Sampler) -> MDNode * {
+        return BuildStaticSampler(Sampler);
+      },
+  };
+
   for (const RootElement &Element : Elements) {
-    MDNode *ElementMD = nullptr;
-    if (const auto &Flags = std::get_if<RootFlags>(&Element))
-      ElementMD = BuildRootFlags(*Flags);
-    else if (const auto &Constants = std::get_if<RootConstants>(&Element))
-      ElementMD = BuildRootConstants(*Constants);
-    else if (const auto &Descriptor = std::get_if<RootDescriptor>(&Element))
-      ElementMD = BuildRootDescriptor(*Descriptor);
-    else if (const auto &Clause = std::get_if<DescriptorTableClause>(&Element))
-      ElementMD = BuildDescriptorTableClause(*Clause);
-    else if (const auto &Table = std::get_if<DescriptorTable>(&Element))
-      ElementMD = BuildDescriptorTable(*Table);
-
-    // FIXME(#126586): remove once all RootElemnt variants are handled in a
-    // visit or otherwise
+    MDNode *ElementMD = std::visit(Visitor, Element);
     assert(ElementMD != nullptr &&
-           "Constructed an unhandled root element type.");
-
+           "Root Element must be initialized and validated");
     GeneratedMetadata.push_back(ElementMD);
   }
 
@@ -274,6 +293,37 @@ MDNode *MetadataBuilder::BuildDescriptorTableClause(
            });
 }
 
+MDNode *MetadataBuilder::BuildStaticSampler(const StaticSampler &Sampler) {
+  IRBuilder<> Builder(Ctx);
+  Metadata *Operands[] = {
+      MDString::get(Ctx, "StaticSampler"),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.Filter))),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.AddressU))),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.AddressV))),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.AddressW))),
+      
ConstantAsMetadata::get(llvm::ConstantFP::get(llvm::Type::getFloatTy(Ctx),
+                                                    Sampler.MipLODBias)),
+      ConstantAsMetadata::get(Builder.getInt32(Sampler.MaxAnisotropy)),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.CompFunc))),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.BorderColor))),
+      ConstantAsMetadata::get(
+          llvm::ConstantFP::get(llvm::Type::getFloatTy(Ctx), Sampler.MinLOD)),
+      ConstantAsMetadata::get(
+          llvm::ConstantFP::get(llvm::Type::getFloatTy(Ctx), Sampler.MaxLOD)),
+      ConstantAsMetadata::get(Builder.getInt32(Sampler.Reg.Number)),
+      ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
+      ConstantAsMetadata::get(
+          Builder.getInt32(llvm::to_underlying(Sampler.Visibility))),
+  };
+  return MDNode::get(Ctx, Operands);
+}
+
 } // namespace rootsig
 } // namespace hlsl
 } // namespace llvm

``````````

</details>


https://github.com/llvm/llvm-project/pull/142642
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to