Skip to content

[NFC][HLSL][DXIL] Move D3D12.h enums and flags to DXILABI #143041

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

Closed
wants to merge 7 commits into from

Conversation

inbelic
Copy link
Contributor

@inbelic inbelic commented Jun 5, 2025

The DXILABI.h is intended to contain definitions of constants and enums that are required to remain stable for the sake of interpreting or constructing DXIL binaries.

The enums and flags corresponding to those defined in the D3D12 header fall under this definition. So it is better suited to have these values defined there.

It was also previously motivated here to have a location to define the D3D12_ROOT_SIGNATURE_VERSION such that clang/Basic/TargetOptions.h will not be dependent on FrontendHLSL.

While the previous pr claimed to have done so, it actually just obfuscated the dependency. This pr will correctly achieve this.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" backend:DirectX HLSL HLSL Language Support llvm:support labels Jun 5, 2025
@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-llvm-transforms
@llvm/pr-subscribers-llvm-support
@llvm/pr-subscribers-hlsl

@llvm/pr-subscribers-clang

Author: Finn Plummer (inbelic)

Changes

The DXILABI.h is intended to contain definitions of constants and enums that are required to remain stable for the sake of interpreting or constructing DXIL binaries.

The enums and flags corresponding to those defined in the D3D12 header fall under this definition. So it is better suited to have these values defined there.

It was also previously motivated here to have a location to define the D3D12_ROOT_SIGNATURE_VERSION such that clang/Basic/TargetOptions.h will not be dependent on FrontendHLSL.

While the previous pr claimed to have done so, it actually just obfuscated the dependency. This pr will correctly achieve this.


Patch is 23.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/143041.diff

8 Files Affected:

  • (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+19-19)
  • (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+8-7)
  • (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+1)
  • (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+18-138)
  • (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h (+1-1)
  • (modified) llvm/include/llvm/Support/DXILABI.h (+126)
  • (modified) llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp (+18-18)
  • (modified) llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp (+1)
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index afa2c4d8cfe50..066c43cc2be1e 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -71,7 +71,7 @@ class RootSignatureParser {
   // expected, or, there is a lexing error
 
   /// Root Element parse methods:
-  std::optional<llvm::hlsl::rootsig::RootFlags> parseRootFlags();
+  std::optional<llvm::dxil::RootFlags> parseRootFlags();
   std::optional<llvm::hlsl::rootsig::RootConstants> parseRootConstants();
   std::optional<llvm::hlsl::rootsig::RootDescriptor> parseRootDescriptor();
   std::optional<llvm::hlsl::rootsig::DescriptorTable> parseDescriptorTable();
@@ -86,15 +86,15 @@ class RootSignatureParser {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
     std::optional<uint32_t> Num32BitConstants;
     std::optional<uint32_t> Space;
-    std::optional<llvm::hlsl::rootsig::ShaderVisibility> Visibility;
+    std::optional<llvm::dxil::ShaderVisibility> Visibility;
   };
   std::optional<ParsedConstantParams> parseRootConstantParams();
 
   struct ParsedRootDescriptorParams {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
     std::optional<uint32_t> Space;
-    std::optional<llvm::hlsl::rootsig::ShaderVisibility> Visibility;
-    std::optional<llvm::hlsl::rootsig::RootDescriptorFlags> Flags;
+    std::optional<llvm::dxil::ShaderVisibility> Visibility;
+    std::optional<llvm::dxil::RootDescriptorFlags> Flags;
   };
   std::optional<ParsedRootDescriptorParams>
   parseRootDescriptorParams(RootSignatureToken::Kind RegType);
@@ -104,25 +104,25 @@ class RootSignatureParser {
     std::optional<uint32_t> NumDescriptors;
     std::optional<uint32_t> Space;
     std::optional<uint32_t> Offset;
-    std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags> Flags;
+    std::optional<llvm::dxil::DescriptorRangeFlags> Flags;
   };
   std::optional<ParsedClauseParams>
   parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
 
   struct ParsedStaticSamplerParams {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
-    std::optional<llvm::hlsl::rootsig::SamplerFilter> Filter;
-    std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressU;
-    std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressV;
-    std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressW;
+    std::optional<llvm::dxil::SamplerFilter> Filter;
+    std::optional<llvm::dxil::TextureAddressMode> AddressU;
+    std::optional<llvm::dxil::TextureAddressMode> AddressV;
+    std::optional<llvm::dxil::TextureAddressMode> AddressW;
     std::optional<float> MipLODBias;
     std::optional<uint32_t> MaxAnisotropy;
-    std::optional<llvm::hlsl::rootsig::ComparisonFunc> CompFunc;
-    std::optional<llvm::hlsl::rootsig::StaticBorderColor> BorderColor;
+    std::optional<llvm::dxil::ComparisonFunc> CompFunc;
+    std::optional<llvm::dxil::StaticBorderColor> BorderColor;
     std::optional<float> MinLOD;
     std::optional<float> MaxLOD;
     std::optional<uint32_t> Space;
-    std::optional<llvm::hlsl::rootsig::ShaderVisibility> Visibility;
+    std::optional<llvm::dxil::ShaderVisibility> Visibility;
   };
   std::optional<ParsedStaticSamplerParams> parseStaticSamplerParams();
 
@@ -132,16 +132,16 @@ class RootSignatureParser {
   std::optional<float> parseFloatParam();
 
   /// Parsing methods of various enums
-  std::optional<llvm::hlsl::rootsig::ShaderVisibility> parseShaderVisibility();
-  std::optional<llvm::hlsl::rootsig::SamplerFilter> parseSamplerFilter();
-  std::optional<llvm::hlsl::rootsig::TextureAddressMode>
+  std::optional<llvm::dxil::ShaderVisibility> parseShaderVisibility();
+  std::optional<llvm::dxil::SamplerFilter> parseSamplerFilter();
+  std::optional<llvm::dxil::TextureAddressMode>
   parseTextureAddressMode();
-  std::optional<llvm::hlsl::rootsig::ComparisonFunc> parseComparisonFunc();
-  std::optional<llvm::hlsl::rootsig::StaticBorderColor>
+  std::optional<llvm::dxil::ComparisonFunc> parseComparisonFunc();
+  std::optional<llvm::dxil::StaticBorderColor>
   parseStaticBorderColor();
-  std::optional<llvm::hlsl::rootsig::RootDescriptorFlags>
+  std::optional<llvm::dxil::RootDescriptorFlags>
   parseRootDescriptorFlags();
-  std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags>
+  std::optional<llvm::dxil::DescriptorRangeFlags>
   parseDescriptorRangeFlags();
 
   /// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index e510302c3aae0..4e01b23a48572 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -11,6 +11,7 @@
 #include "clang/Lex/LiteralSupport.h"
 
 using namespace llvm::hlsl::rootsig;
+using namespace llvm::dxil;
 
 namespace clang {
 namespace hlsl {
@@ -983,7 +984,7 @@ std::optional<float> RootSignatureParser::parseFloatParam() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::ShaderVisibility>
+std::optional<::ShaderVisibility>
 RootSignatureParser::parseShaderVisibility() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1009,7 +1010,7 @@ RootSignatureParser::parseShaderVisibility() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::SamplerFilter>
+std::optional<::SamplerFilter>
 RootSignatureParser::parseSamplerFilter() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1035,7 +1036,7 @@ RootSignatureParser::parseSamplerFilter() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::TextureAddressMode>
+std::optional<::TextureAddressMode>
 RootSignatureParser::parseTextureAddressMode() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1061,7 +1062,7 @@ RootSignatureParser::parseTextureAddressMode() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::ComparisonFunc>
+std::optional<::ComparisonFunc>
 RootSignatureParser::parseComparisonFunc() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1087,7 +1088,7 @@ RootSignatureParser::parseComparisonFunc() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::StaticBorderColor>
+std::optional<::StaticBorderColor>
 RootSignatureParser::parseStaticBorderColor() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1113,7 +1114,7 @@ RootSignatureParser::parseStaticBorderColor() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::RootDescriptorFlags>
+std::optional<::RootDescriptorFlags>
 RootSignatureParser::parseRootDescriptorFlags() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1152,7 +1153,7 @@ RootSignatureParser::parseRootDescriptorFlags() {
   return Flags;
 }
 
-std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags>
+std::optional<::DescriptorRangeFlags>
 RootSignatureParser::parseDescriptorRangeFlags() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 1e46ee35d5d49..67536440bbfec 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -25,6 +25,7 @@
 #include "gtest/gtest.h"
 
 using namespace clang;
+using namespace llvm::dxil;
 using namespace llvm::hlsl::rootsig;
 
 namespace {
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 2f028817b45b6..f73c12bba88a2 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -22,126 +22,6 @@ namespace llvm {
 namespace hlsl {
 namespace rootsig {
 
-// Definition of the various enumerations and flags. The definitions of all
-// values here correspond to their description in the d3d12.h header and are
-// carried over from their values in DXC. For reference:
-// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/
-
-enum class RootFlags : uint32_t {
-  None = 0,
-  AllowInputAssemblerInputLayout = 0x1,
-  DenyVertexShaderRootAccess = 0x2,
-  DenyHullShaderRootAccess = 0x4,
-  DenyDomainShaderRootAccess = 0x8,
-  DenyGeometryShaderRootAccess = 0x10,
-  DenyPixelShaderRootAccess = 0x20,
-  AllowStreamOutput = 0x40,
-  LocalRootSignature = 0x80,
-  DenyAmplificationShaderRootAccess = 0x100,
-  DenyMeshShaderRootAccess = 0x200,
-  CBVSRVUAVHeapDirectlyIndexed = 0x400,
-  SamplerHeapDirectlyIndexed = 0x800,
-  ValidFlags = 0x00000fff
-};
-
-enum class RootDescriptorFlags : unsigned {
-  None = 0,
-  DataVolatile = 0x2,
-  DataStaticWhileSetAtExecute = 0x4,
-  DataStatic = 0x8,
-  ValidFlags = 0xe,
-};
-
-enum class DescriptorRangeFlags : unsigned {
-  None = 0,
-  DescriptorsVolatile = 0x1,
-  DataVolatile = 0x2,
-  DataStaticWhileSetAtExecute = 0x4,
-  DataStatic = 0x8,
-  DescriptorsStaticKeepingBufferBoundsChecks = 0x10000,
-  ValidFlags = 0x1000f,
-  ValidSamplerFlags = DescriptorsVolatile,
-};
-
-enum class ShaderVisibility {
-  All = 0,
-  Vertex = 1,
-  Hull = 2,
-  Domain = 3,
-  Geometry = 4,
-  Pixel = 5,
-  Amplification = 6,
-  Mesh = 7,
-};
-
-// D3D12_FILTER enumeration:
-// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_filter
-enum class SamplerFilter {
-  MinMagMipPoint = 0,
-  MinMagPointMipLinear = 0x1,
-  MinPointMagLinearMipPoint = 0x4,
-  MinPointMagMipLinear = 0x5,
-  MinLinearMagMipPoint = 0x10,
-  MinLinearMagPointMipLinear = 0x11,
-  MinMagLinearMipPoint = 0x14,
-  MinMagMipLinear = 0x15,
-  Anisotropic = 0x55,
-  ComparisonMinMagMipPoint = 0x80,
-  ComparisonMinMagPointMipLinear = 0x81,
-  ComparisonMinPointMagLinearMipPoint = 0x84,
-  ComparisonMinPointMagMipLinear = 0x85,
-  ComparisonMinLinearMagMipPoint = 0x90,
-  ComparisonMinLinearMagPointMipLinear = 0x91,
-  ComparisonMinMagLinearMipPoint = 0x94,
-  ComparisonMinMagMipLinear = 0x95,
-  ComparisonAnisotropic = 0xd5,
-  MinimumMinMagMipPoint = 0x100,
-  MinimumMinMagPointMipLinear = 0x101,
-  MinimumMinPointMagLinearMipPoint = 0x104,
-  MinimumMinPointMagMipLinear = 0x105,
-  MinimumMinLinearMagMipPoint = 0x110,
-  MinimumMinLinearMagPointMipLinear = 0x111,
-  MinimumMinMagLinearMipPoint = 0x114,
-  MinimumMinMagMipLinear = 0x115,
-  MinimumAnisotropic = 0x155,
-  MaximumMinMagMipPoint = 0x180,
-  MaximumMinMagPointMipLinear = 0x181,
-  MaximumMinPointMagLinearMipPoint = 0x184,
-  MaximumMinPointMagMipLinear = 0x185,
-  MaximumMinLinearMagMipPoint = 0x190,
-  MaximumMinLinearMagPointMipLinear = 0x191,
-  MaximumMinMagLinearMipPoint = 0x194,
-  MaximumMinMagMipLinear = 0x195,
-  MaximumAnisotropic = 0x1d5
-};
-
-enum class TextureAddressMode {
-  Wrap = 1,
-  Mirror = 2,
-  Clamp = 3,
-  Border = 4,
-  MirrorOnce = 5
-};
-
-enum class ComparisonFunc : unsigned {
-  Never = 1,
-  Less = 2,
-  Equal = 3,
-  LessEqual = 4,
-  Greater = 5,
-  NotEqual = 6,
-  GreaterEqual = 7,
-  Always = 8
-};
-
-enum class StaticBorderColor {
-  TransparentBlack = 0,
-  OpaqueBlack = 1,
-  OpaqueWhite = 2,
-  OpaqueBlackUint = 3,
-  OpaqueWhiteUint = 4
-};
-
 // Definitions of the in-memory data layout structures
 
 // Models the different registers: bReg | tReg | uReg | sReg
@@ -156,7 +36,7 @@ struct RootConstants {
   uint32_t Num32BitConstants;
   Register Reg;
   uint32_t Space = 0;
-  ShaderVisibility Visibility = ShaderVisibility::All;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
 };
 
 enum class DescriptorType : uint8_t { SRV = 0, UAV, CBuffer };
@@ -165,17 +45,17 @@ struct RootDescriptor {
   DescriptorType Type;
   Register Reg;
   uint32_t Space = 0;
-  ShaderVisibility Visibility = ShaderVisibility::All;
-  RootDescriptorFlags Flags;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
+  dxil::RootDescriptorFlags Flags;
 
   void setDefaultFlags() {
     switch (Type) {
     case DescriptorType::CBuffer:
     case DescriptorType::SRV:
-      Flags = RootDescriptorFlags::DataStaticWhileSetAtExecute;
+      Flags = dxil::RootDescriptorFlags::DataStaticWhileSetAtExecute;
       break;
     case DescriptorType::UAV:
-      Flags = RootDescriptorFlags::DataVolatile;
+      Flags = dxil::RootDescriptorFlags::DataVolatile;
       break;
     }
   }
@@ -183,7 +63,7 @@ struct RootDescriptor {
 
 // Models the end of a descriptor table and stores its visibility
 struct DescriptorTable {
-  ShaderVisibility Visibility = ShaderVisibility::All;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
   // Denotes that the previous NumClauses in the RootElement array
   // are the clauses in the table.
   uint32_t NumClauses = 0;
@@ -199,19 +79,19 @@ struct DescriptorTableClause {
   uint32_t NumDescriptors = 1;
   uint32_t Space = 0;
   uint32_t Offset = DescriptorTableOffsetAppend;
-  DescriptorRangeFlags Flags;
+  dxil::DescriptorRangeFlags Flags;
 
   void setDefaultFlags() {
     switch (Type) {
     case ClauseType::CBuffer:
     case ClauseType::SRV:
-      Flags = DescriptorRangeFlags::DataStaticWhileSetAtExecute;
+      Flags = dxil::DescriptorRangeFlags::DataStaticWhileSetAtExecute;
       break;
     case ClauseType::UAV:
-      Flags = DescriptorRangeFlags::DataVolatile;
+      Flags = dxil::DescriptorRangeFlags::DataVolatile;
       break;
     case ClauseType::Sampler:
-      Flags = DescriptorRangeFlags::None;
+      Flags = dxil::DescriptorRangeFlags::None;
       break;
     }
   }
@@ -219,18 +99,18 @@ struct DescriptorTableClause {
 
 struct StaticSampler {
   Register Reg;
-  SamplerFilter Filter = SamplerFilter::Anisotropic;
-  TextureAddressMode AddressU = TextureAddressMode::Wrap;
-  TextureAddressMode AddressV = TextureAddressMode::Wrap;
-  TextureAddressMode AddressW = TextureAddressMode::Wrap;
+  dxil::SamplerFilter Filter = dxil::SamplerFilter::Anisotropic;
+  dxil::TextureAddressMode AddressU = dxil::TextureAddressMode::Wrap;
+  dxil::TextureAddressMode AddressV = dxil::TextureAddressMode::Wrap;
+  dxil::TextureAddressMode AddressW = dxil::TextureAddressMode::Wrap;
   float MipLODBias = 0.f;
   uint32_t MaxAnisotropy = 16;
-  ComparisonFunc CompFunc = ComparisonFunc::LessEqual;
-  StaticBorderColor BorderColor = StaticBorderColor::OpaqueWhite;
+  dxil::ComparisonFunc CompFunc = dxil::ComparisonFunc::LessEqual;
+  dxil::StaticBorderColor BorderColor = dxil::StaticBorderColor::OpaqueWhite;
   float MinLOD = 0.f;
   float MaxLOD = std::numeric_limits<float>::max();
   uint32_t Space = 0;
-  ShaderVisibility Visibility = ShaderVisibility::All;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
 };
 
 /// Models RootElement : RootFlags | RootConstants | RootParam
@@ -250,7 +130,7 @@ struct StaticSampler {
 /// RootElements in the array, and it holds a data member for the Visibility
 /// parameter.
 using RootElement =
-    std::variant<RootFlags, RootConstants, RootDescriptor, DescriptorTable,
+    std::variant<dxil::RootFlags, RootConstants, RootDescriptor, DescriptorTable,
                  DescriptorTableClause, StaticSampler>;
 
 } // namespace rootsig
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
index 6d959ad5bdc7f..865d8d3f5bf09 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
@@ -47,7 +47,7 @@ class MetadataBuilder {
 
 private:
   /// Define the various builders for the different metadata types
-  MDNode *BuildRootFlags(const RootFlags &Flags);
+  MDNode *BuildRootFlags(const dxil::RootFlags &Flags);
   MDNode *BuildRootConstants(const RootConstants &Constants);
   MDNode *BuildRootDescriptor(const RootDescriptor &Descriptor);
   MDNode *BuildDescriptorTable(const DescriptorTable &Table);
diff --git a/llvm/include/llvm/Support/DXILABI.h b/llvm/include/llvm/Support/DXILABI.h
index b479f7c73eba3..80c6b5041c96e 100644
--- a/llvm/include/llvm/Support/DXILABI.h
+++ b/llvm/include/llvm/Support/DXILABI.h
@@ -99,6 +99,132 @@ enum class SamplerFeedbackType : uint32_t {
 const unsigned MinWaveSize = 4;
 const unsigned MaxWaveSize = 128;
 
+// Definition of the various d3d12.h enumerations and flags. The definitions of
+// all values here correspond to their description in the d3d12.h header and
+// are carried over from their values in DXC. For reference:
+// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/
+
+// D3D12_ROOT_SIGNATURE_FLAGS
+enum class RootFlags : uint32_t {
+  None = 0,
+  AllowInputAssemblerInputLayout = 0x1,
+  DenyVertexShaderRootAccess = 0x2,
+  DenyHullShaderRootAccess = 0x4,
+  DenyDomainShaderRootAccess = 0x8,
+  DenyGeometryShaderRootAccess = 0x10,
+  DenyPixelShaderRootAccess = 0x20,
+  AllowStreamOutput = 0x40,
+  LocalRootSignature = 0x80,
+  DenyAmplificationShaderRootAccess = 0x100,
+  DenyMeshShaderRootAccess = 0x200,
+  CBVSRVUAVHeapDirectlyIndexed = 0x400,
+  SamplerHeapDirectlyIndexed = 0x800,
+  ValidFlags = 0x00000fff
+};
+
+// D3D12_ROOT_DESCRIPTOR_FLAGS
+enum class RootDescriptorFlags : unsigned {
+  None = 0,
+  DataVolatile = 0x2,
+  DataStaticWhileSetAtExecute = 0x4,
+  DataStatic = 0x8,
+  ValidFlags = 0xe,
+};
+
+// D3D12_DESCRIPTOR_RANGE_FLAGS
+enum class DescriptorRangeFlags : unsigned {
+  None = 0,
+  DescriptorsVolatile = 0x1,
+  DataVolatile = 0x2,
+  DataStaticWhileSetAtExecute = 0x4,
+  DataStatic = 0x8,
+  DescriptorsStaticKeepingBufferBoundsChecks = 0x10000,
+  ValidFlags = 0x1000f,
+  ValidSamplerFlags = DescriptorsVolatile,
+};
+
+// D3D12_SHADER_VISIBILITY
+enum class ShaderVisibility {
+  All = 0,
+  Vertex = 1,
+  Hull = 2,
+  Domain = 3,
+  Geometry = 4,
+  Pixel = 5,
+  Amplification = 6,
+  Mesh = 7,
+};
+
+// D3D12_FILTER
+enum class SamplerFilter {
+  MinMagMipPoint = 0,
+  MinMagPointMipLinear = 0x1,
+  MinPointMagLinearMipPoint = 0x4,
+  MinPointMagMipLinear = 0x5,
+  MinLinearMagMipPoint = 0x10,
+  MinLinearMagPointMipLinear = 0x11,
+  MinMagLinearMipPoint = 0x14,
+  MinMagMipLinear = 0x15,
+  Anisotropic = 0x55,
+  ComparisonMinMagMipPoint = 0x80,
+  ComparisonMinMagPointMipLinear = 0x81,
+  ComparisonMinPointMagLinearMipPoint = 0x84,
+  ComparisonMinPointMagMipLinear = 0x85,
+  ComparisonMinLinearMagMipPoint = 0x90,
+  ComparisonMinLinearMagPointMipLinear = 0x91,
+  ComparisonMinMagLinearMipPoint = 0x94,
+  ComparisonMinMagMipLinear = 0x95,
+  ComparisonAnisotropic = 0xd5,
+  MinimumMinMagMipPoint = 0x100,
+  MinimumMinMagPointMipLinear = 0x101,
+  MinimumMinPointMagLinearMipPoint = 0x104,
+  MinimumMinPointMagMipLinear = 0x105,
+  MinimumMinLinearMagMipPoint = 0x110,
+  MinimumMinLinearMagPointMipLinear = 0x111,
+  MinimumMinMagLinearMipPoint = 0x114,
+  MinimumMinMagMipLinear = 0x115,
+  MinimumAnisotropic = 0x155,
+  MaximumMinMagMipPoint = 0x180,
+  MaximumMinMagPointMipLinear = 0x181,
+  MaximumMinPointMagLinearMipPoint = 0x184,
+  MaximumMinPointMagMipLinear = 0x185,
+  MaximumMinLinearMagMipPoint = 0x190,
+  MaximumMinLinearMagPointMipLinear = 0x191,
+  MaximumMinMagLinearMipPoint = 0x194,
+  MaximumMinMagMipLinear = 0x195,
+  MaximumAnisotropic = 0x1d5
+};
+
+// D3D12_TEXTURE_ADDRESS_MODE
+enum class TextureAddressMode {
+  Wrap = 1,
+  Mirror = 2,
+  Clamp = 3,
+  Border = 4,
+  MirrorOnce = 5
+};
+
+// D3D12_COMPARISON_FUNC
+enum class ComparisonFunc : unsigned {
+  Never = 1,
+  Less = 2,
+  Equal = 3,
+  LessEqual = 4,
+  Greater = 5,
+  NotEqual = 6,
+  GreaterEqual = 7,
+  Always = 8
+};
+
+// D3D12_STATIC_BORDER_COLOR
+enum class StaticBorderColor {
+  TransparentBlack = 0,
+  OpaqueBlack = 1,
+  OpaqueWhite = 2,
+  OpaqueBlackUint = 3,
+  OpaqueWhiteUint = 4
+};
+
 } // namespace dxil
 } // namespace llvm
 
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
index 765a3bcbed7e2..2cc6371479351 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
@@ -40,30 +40,30 @@ static raw_ostream &operator<<(raw_o...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jun 5, 2025

@llvm/pr-subscribers-backend-directx

Author: Finn Plummer (inbelic)

Changes

The DXILABI.h is intended to contain definitions of constants and enums that are required to remain stable for the sake of interpreting or constructing DXIL binaries.

The enums and flags corresponding to those defined in the D3D12 header fall under this definition. So it is better suited to have these values defined there.

It was also previously motivated here to have a location to define the D3D12_ROOT_SIGNATURE_VERSION such that clang/Basic/TargetOptions.h will not be dependent on FrontendHLSL.

While the previous pr claimed to have done so, it actually just obfuscated the dependency. This pr will correctly achieve this.


Patch is 23.80 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/143041.diff

8 Files Affected:

  • (modified) clang/include/clang/Parse/ParseHLSLRootSignature.h (+19-19)
  • (modified) clang/lib/Parse/ParseHLSLRootSignature.cpp (+8-7)
  • (modified) clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp (+1)
  • (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h (+18-138)
  • (modified) llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h (+1-1)
  • (modified) llvm/include/llvm/Support/DXILABI.h (+126)
  • (modified) llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp (+18-18)
  • (modified) llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp (+1)
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index afa2c4d8cfe50..066c43cc2be1e 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -71,7 +71,7 @@ class RootSignatureParser {
   // expected, or, there is a lexing error
 
   /// Root Element parse methods:
-  std::optional<llvm::hlsl::rootsig::RootFlags> parseRootFlags();
+  std::optional<llvm::dxil::RootFlags> parseRootFlags();
   std::optional<llvm::hlsl::rootsig::RootConstants> parseRootConstants();
   std::optional<llvm::hlsl::rootsig::RootDescriptor> parseRootDescriptor();
   std::optional<llvm::hlsl::rootsig::DescriptorTable> parseDescriptorTable();
@@ -86,15 +86,15 @@ class RootSignatureParser {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
     std::optional<uint32_t> Num32BitConstants;
     std::optional<uint32_t> Space;
-    std::optional<llvm::hlsl::rootsig::ShaderVisibility> Visibility;
+    std::optional<llvm::dxil::ShaderVisibility> Visibility;
   };
   std::optional<ParsedConstantParams> parseRootConstantParams();
 
   struct ParsedRootDescriptorParams {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
     std::optional<uint32_t> Space;
-    std::optional<llvm::hlsl::rootsig::ShaderVisibility> Visibility;
-    std::optional<llvm::hlsl::rootsig::RootDescriptorFlags> Flags;
+    std::optional<llvm::dxil::ShaderVisibility> Visibility;
+    std::optional<llvm::dxil::RootDescriptorFlags> Flags;
   };
   std::optional<ParsedRootDescriptorParams>
   parseRootDescriptorParams(RootSignatureToken::Kind RegType);
@@ -104,25 +104,25 @@ class RootSignatureParser {
     std::optional<uint32_t> NumDescriptors;
     std::optional<uint32_t> Space;
     std::optional<uint32_t> Offset;
-    std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags> Flags;
+    std::optional<llvm::dxil::DescriptorRangeFlags> Flags;
   };
   std::optional<ParsedClauseParams>
   parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
 
   struct ParsedStaticSamplerParams {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
-    std::optional<llvm::hlsl::rootsig::SamplerFilter> Filter;
-    std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressU;
-    std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressV;
-    std::optional<llvm::hlsl::rootsig::TextureAddressMode> AddressW;
+    std::optional<llvm::dxil::SamplerFilter> Filter;
+    std::optional<llvm::dxil::TextureAddressMode> AddressU;
+    std::optional<llvm::dxil::TextureAddressMode> AddressV;
+    std::optional<llvm::dxil::TextureAddressMode> AddressW;
     std::optional<float> MipLODBias;
     std::optional<uint32_t> MaxAnisotropy;
-    std::optional<llvm::hlsl::rootsig::ComparisonFunc> CompFunc;
-    std::optional<llvm::hlsl::rootsig::StaticBorderColor> BorderColor;
+    std::optional<llvm::dxil::ComparisonFunc> CompFunc;
+    std::optional<llvm::dxil::StaticBorderColor> BorderColor;
     std::optional<float> MinLOD;
     std::optional<float> MaxLOD;
     std::optional<uint32_t> Space;
-    std::optional<llvm::hlsl::rootsig::ShaderVisibility> Visibility;
+    std::optional<llvm::dxil::ShaderVisibility> Visibility;
   };
   std::optional<ParsedStaticSamplerParams> parseStaticSamplerParams();
 
@@ -132,16 +132,16 @@ class RootSignatureParser {
   std::optional<float> parseFloatParam();
 
   /// Parsing methods of various enums
-  std::optional<llvm::hlsl::rootsig::ShaderVisibility> parseShaderVisibility();
-  std::optional<llvm::hlsl::rootsig::SamplerFilter> parseSamplerFilter();
-  std::optional<llvm::hlsl::rootsig::TextureAddressMode>
+  std::optional<llvm::dxil::ShaderVisibility> parseShaderVisibility();
+  std::optional<llvm::dxil::SamplerFilter> parseSamplerFilter();
+  std::optional<llvm::dxil::TextureAddressMode>
   parseTextureAddressMode();
-  std::optional<llvm::hlsl::rootsig::ComparisonFunc> parseComparisonFunc();
-  std::optional<llvm::hlsl::rootsig::StaticBorderColor>
+  std::optional<llvm::dxil::ComparisonFunc> parseComparisonFunc();
+  std::optional<llvm::dxil::StaticBorderColor>
   parseStaticBorderColor();
-  std::optional<llvm::hlsl::rootsig::RootDescriptorFlags>
+  std::optional<llvm::dxil::RootDescriptorFlags>
   parseRootDescriptorFlags();
-  std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags>
+  std::optional<llvm::dxil::DescriptorRangeFlags>
   parseDescriptorRangeFlags();
 
   /// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index e510302c3aae0..4e01b23a48572 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -11,6 +11,7 @@
 #include "clang/Lex/LiteralSupport.h"
 
 using namespace llvm::hlsl::rootsig;
+using namespace llvm::dxil;
 
 namespace clang {
 namespace hlsl {
@@ -983,7 +984,7 @@ std::optional<float> RootSignatureParser::parseFloatParam() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::ShaderVisibility>
+std::optional<::ShaderVisibility>
 RootSignatureParser::parseShaderVisibility() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1009,7 +1010,7 @@ RootSignatureParser::parseShaderVisibility() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::SamplerFilter>
+std::optional<::SamplerFilter>
 RootSignatureParser::parseSamplerFilter() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1035,7 +1036,7 @@ RootSignatureParser::parseSamplerFilter() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::TextureAddressMode>
+std::optional<::TextureAddressMode>
 RootSignatureParser::parseTextureAddressMode() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1061,7 +1062,7 @@ RootSignatureParser::parseTextureAddressMode() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::ComparisonFunc>
+std::optional<::ComparisonFunc>
 RootSignatureParser::parseComparisonFunc() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1087,7 +1088,7 @@ RootSignatureParser::parseComparisonFunc() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::StaticBorderColor>
+std::optional<::StaticBorderColor>
 RootSignatureParser::parseStaticBorderColor() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1113,7 +1114,7 @@ RootSignatureParser::parseStaticBorderColor() {
   return std::nullopt;
 }
 
-std::optional<llvm::hlsl::rootsig::RootDescriptorFlags>
+std::optional<::RootDescriptorFlags>
 RootSignatureParser::parseRootDescriptorFlags() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
@@ -1152,7 +1153,7 @@ RootSignatureParser::parseRootDescriptorFlags() {
   return Flags;
 }
 
-std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags>
+std::optional<::DescriptorRangeFlags>
 RootSignatureParser::parseDescriptorRangeFlags() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 1e46ee35d5d49..67536440bbfec 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -25,6 +25,7 @@
 #include "gtest/gtest.h"
 
 using namespace clang;
+using namespace llvm::dxil;
 using namespace llvm::hlsl::rootsig;
 
 namespace {
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 2f028817b45b6..f73c12bba88a2 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -22,126 +22,6 @@ namespace llvm {
 namespace hlsl {
 namespace rootsig {
 
-// Definition of the various enumerations and flags. The definitions of all
-// values here correspond to their description in the d3d12.h header and are
-// carried over from their values in DXC. For reference:
-// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/
-
-enum class RootFlags : uint32_t {
-  None = 0,
-  AllowInputAssemblerInputLayout = 0x1,
-  DenyVertexShaderRootAccess = 0x2,
-  DenyHullShaderRootAccess = 0x4,
-  DenyDomainShaderRootAccess = 0x8,
-  DenyGeometryShaderRootAccess = 0x10,
-  DenyPixelShaderRootAccess = 0x20,
-  AllowStreamOutput = 0x40,
-  LocalRootSignature = 0x80,
-  DenyAmplificationShaderRootAccess = 0x100,
-  DenyMeshShaderRootAccess = 0x200,
-  CBVSRVUAVHeapDirectlyIndexed = 0x400,
-  SamplerHeapDirectlyIndexed = 0x800,
-  ValidFlags = 0x00000fff
-};
-
-enum class RootDescriptorFlags : unsigned {
-  None = 0,
-  DataVolatile = 0x2,
-  DataStaticWhileSetAtExecute = 0x4,
-  DataStatic = 0x8,
-  ValidFlags = 0xe,
-};
-
-enum class DescriptorRangeFlags : unsigned {
-  None = 0,
-  DescriptorsVolatile = 0x1,
-  DataVolatile = 0x2,
-  DataStaticWhileSetAtExecute = 0x4,
-  DataStatic = 0x8,
-  DescriptorsStaticKeepingBufferBoundsChecks = 0x10000,
-  ValidFlags = 0x1000f,
-  ValidSamplerFlags = DescriptorsVolatile,
-};
-
-enum class ShaderVisibility {
-  All = 0,
-  Vertex = 1,
-  Hull = 2,
-  Domain = 3,
-  Geometry = 4,
-  Pixel = 5,
-  Amplification = 6,
-  Mesh = 7,
-};
-
-// D3D12_FILTER enumeration:
-// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_filter
-enum class SamplerFilter {
-  MinMagMipPoint = 0,
-  MinMagPointMipLinear = 0x1,
-  MinPointMagLinearMipPoint = 0x4,
-  MinPointMagMipLinear = 0x5,
-  MinLinearMagMipPoint = 0x10,
-  MinLinearMagPointMipLinear = 0x11,
-  MinMagLinearMipPoint = 0x14,
-  MinMagMipLinear = 0x15,
-  Anisotropic = 0x55,
-  ComparisonMinMagMipPoint = 0x80,
-  ComparisonMinMagPointMipLinear = 0x81,
-  ComparisonMinPointMagLinearMipPoint = 0x84,
-  ComparisonMinPointMagMipLinear = 0x85,
-  ComparisonMinLinearMagMipPoint = 0x90,
-  ComparisonMinLinearMagPointMipLinear = 0x91,
-  ComparisonMinMagLinearMipPoint = 0x94,
-  ComparisonMinMagMipLinear = 0x95,
-  ComparisonAnisotropic = 0xd5,
-  MinimumMinMagMipPoint = 0x100,
-  MinimumMinMagPointMipLinear = 0x101,
-  MinimumMinPointMagLinearMipPoint = 0x104,
-  MinimumMinPointMagMipLinear = 0x105,
-  MinimumMinLinearMagMipPoint = 0x110,
-  MinimumMinLinearMagPointMipLinear = 0x111,
-  MinimumMinMagLinearMipPoint = 0x114,
-  MinimumMinMagMipLinear = 0x115,
-  MinimumAnisotropic = 0x155,
-  MaximumMinMagMipPoint = 0x180,
-  MaximumMinMagPointMipLinear = 0x181,
-  MaximumMinPointMagLinearMipPoint = 0x184,
-  MaximumMinPointMagMipLinear = 0x185,
-  MaximumMinLinearMagMipPoint = 0x190,
-  MaximumMinLinearMagPointMipLinear = 0x191,
-  MaximumMinMagLinearMipPoint = 0x194,
-  MaximumMinMagMipLinear = 0x195,
-  MaximumAnisotropic = 0x1d5
-};
-
-enum class TextureAddressMode {
-  Wrap = 1,
-  Mirror = 2,
-  Clamp = 3,
-  Border = 4,
-  MirrorOnce = 5
-};
-
-enum class ComparisonFunc : unsigned {
-  Never = 1,
-  Less = 2,
-  Equal = 3,
-  LessEqual = 4,
-  Greater = 5,
-  NotEqual = 6,
-  GreaterEqual = 7,
-  Always = 8
-};
-
-enum class StaticBorderColor {
-  TransparentBlack = 0,
-  OpaqueBlack = 1,
-  OpaqueWhite = 2,
-  OpaqueBlackUint = 3,
-  OpaqueWhiteUint = 4
-};
-
 // Definitions of the in-memory data layout structures
 
 // Models the different registers: bReg | tReg | uReg | sReg
@@ -156,7 +36,7 @@ struct RootConstants {
   uint32_t Num32BitConstants;
   Register Reg;
   uint32_t Space = 0;
-  ShaderVisibility Visibility = ShaderVisibility::All;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
 };
 
 enum class DescriptorType : uint8_t { SRV = 0, UAV, CBuffer };
@@ -165,17 +45,17 @@ struct RootDescriptor {
   DescriptorType Type;
   Register Reg;
   uint32_t Space = 0;
-  ShaderVisibility Visibility = ShaderVisibility::All;
-  RootDescriptorFlags Flags;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
+  dxil::RootDescriptorFlags Flags;
 
   void setDefaultFlags() {
     switch (Type) {
     case DescriptorType::CBuffer:
     case DescriptorType::SRV:
-      Flags = RootDescriptorFlags::DataStaticWhileSetAtExecute;
+      Flags = dxil::RootDescriptorFlags::DataStaticWhileSetAtExecute;
       break;
     case DescriptorType::UAV:
-      Flags = RootDescriptorFlags::DataVolatile;
+      Flags = dxil::RootDescriptorFlags::DataVolatile;
       break;
     }
   }
@@ -183,7 +63,7 @@ struct RootDescriptor {
 
 // Models the end of a descriptor table and stores its visibility
 struct DescriptorTable {
-  ShaderVisibility Visibility = ShaderVisibility::All;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
   // Denotes that the previous NumClauses in the RootElement array
   // are the clauses in the table.
   uint32_t NumClauses = 0;
@@ -199,19 +79,19 @@ struct DescriptorTableClause {
   uint32_t NumDescriptors = 1;
   uint32_t Space = 0;
   uint32_t Offset = DescriptorTableOffsetAppend;
-  DescriptorRangeFlags Flags;
+  dxil::DescriptorRangeFlags Flags;
 
   void setDefaultFlags() {
     switch (Type) {
     case ClauseType::CBuffer:
     case ClauseType::SRV:
-      Flags = DescriptorRangeFlags::DataStaticWhileSetAtExecute;
+      Flags = dxil::DescriptorRangeFlags::DataStaticWhileSetAtExecute;
       break;
     case ClauseType::UAV:
-      Flags = DescriptorRangeFlags::DataVolatile;
+      Flags = dxil::DescriptorRangeFlags::DataVolatile;
       break;
     case ClauseType::Sampler:
-      Flags = DescriptorRangeFlags::None;
+      Flags = dxil::DescriptorRangeFlags::None;
       break;
     }
   }
@@ -219,18 +99,18 @@ struct DescriptorTableClause {
 
 struct StaticSampler {
   Register Reg;
-  SamplerFilter Filter = SamplerFilter::Anisotropic;
-  TextureAddressMode AddressU = TextureAddressMode::Wrap;
-  TextureAddressMode AddressV = TextureAddressMode::Wrap;
-  TextureAddressMode AddressW = TextureAddressMode::Wrap;
+  dxil::SamplerFilter Filter = dxil::SamplerFilter::Anisotropic;
+  dxil::TextureAddressMode AddressU = dxil::TextureAddressMode::Wrap;
+  dxil::TextureAddressMode AddressV = dxil::TextureAddressMode::Wrap;
+  dxil::TextureAddressMode AddressW = dxil::TextureAddressMode::Wrap;
   float MipLODBias = 0.f;
   uint32_t MaxAnisotropy = 16;
-  ComparisonFunc CompFunc = ComparisonFunc::LessEqual;
-  StaticBorderColor BorderColor = StaticBorderColor::OpaqueWhite;
+  dxil::ComparisonFunc CompFunc = dxil::ComparisonFunc::LessEqual;
+  dxil::StaticBorderColor BorderColor = dxil::StaticBorderColor::OpaqueWhite;
   float MinLOD = 0.f;
   float MaxLOD = std::numeric_limits<float>::max();
   uint32_t Space = 0;
-  ShaderVisibility Visibility = ShaderVisibility::All;
+  dxil::ShaderVisibility Visibility = dxil::ShaderVisibility::All;
 };
 
 /// Models RootElement : RootFlags | RootConstants | RootParam
@@ -250,7 +130,7 @@ struct StaticSampler {
 /// RootElements in the array, and it holds a data member for the Visibility
 /// parameter.
 using RootElement =
-    std::variant<RootFlags, RootConstants, RootDescriptor, DescriptorTable,
+    std::variant<dxil::RootFlags, RootConstants, RootDescriptor, DescriptorTable,
                  DescriptorTableClause, StaticSampler>;
 
 } // namespace rootsig
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
index 6d959ad5bdc7f..865d8d3f5bf09 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h
@@ -47,7 +47,7 @@ class MetadataBuilder {
 
 private:
   /// Define the various builders for the different metadata types
-  MDNode *BuildRootFlags(const RootFlags &Flags);
+  MDNode *BuildRootFlags(const dxil::RootFlags &Flags);
   MDNode *BuildRootConstants(const RootConstants &Constants);
   MDNode *BuildRootDescriptor(const RootDescriptor &Descriptor);
   MDNode *BuildDescriptorTable(const DescriptorTable &Table);
diff --git a/llvm/include/llvm/Support/DXILABI.h b/llvm/include/llvm/Support/DXILABI.h
index b479f7c73eba3..80c6b5041c96e 100644
--- a/llvm/include/llvm/Support/DXILABI.h
+++ b/llvm/include/llvm/Support/DXILABI.h
@@ -99,6 +99,132 @@ enum class SamplerFeedbackType : uint32_t {
 const unsigned MinWaveSize = 4;
 const unsigned MaxWaveSize = 128;
 
+// Definition of the various d3d12.h enumerations and flags. The definitions of
+// all values here correspond to their description in the d3d12.h header and
+// are carried over from their values in DXC. For reference:
+// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/
+
+// D3D12_ROOT_SIGNATURE_FLAGS
+enum class RootFlags : uint32_t {
+  None = 0,
+  AllowInputAssemblerInputLayout = 0x1,
+  DenyVertexShaderRootAccess = 0x2,
+  DenyHullShaderRootAccess = 0x4,
+  DenyDomainShaderRootAccess = 0x8,
+  DenyGeometryShaderRootAccess = 0x10,
+  DenyPixelShaderRootAccess = 0x20,
+  AllowStreamOutput = 0x40,
+  LocalRootSignature = 0x80,
+  DenyAmplificationShaderRootAccess = 0x100,
+  DenyMeshShaderRootAccess = 0x200,
+  CBVSRVUAVHeapDirectlyIndexed = 0x400,
+  SamplerHeapDirectlyIndexed = 0x800,
+  ValidFlags = 0x00000fff
+};
+
+// D3D12_ROOT_DESCRIPTOR_FLAGS
+enum class RootDescriptorFlags : unsigned {
+  None = 0,
+  DataVolatile = 0x2,
+  DataStaticWhileSetAtExecute = 0x4,
+  DataStatic = 0x8,
+  ValidFlags = 0xe,
+};
+
+// D3D12_DESCRIPTOR_RANGE_FLAGS
+enum class DescriptorRangeFlags : unsigned {
+  None = 0,
+  DescriptorsVolatile = 0x1,
+  DataVolatile = 0x2,
+  DataStaticWhileSetAtExecute = 0x4,
+  DataStatic = 0x8,
+  DescriptorsStaticKeepingBufferBoundsChecks = 0x10000,
+  ValidFlags = 0x1000f,
+  ValidSamplerFlags = DescriptorsVolatile,
+};
+
+// D3D12_SHADER_VISIBILITY
+enum class ShaderVisibility {
+  All = 0,
+  Vertex = 1,
+  Hull = 2,
+  Domain = 3,
+  Geometry = 4,
+  Pixel = 5,
+  Amplification = 6,
+  Mesh = 7,
+};
+
+// D3D12_FILTER
+enum class SamplerFilter {
+  MinMagMipPoint = 0,
+  MinMagPointMipLinear = 0x1,
+  MinPointMagLinearMipPoint = 0x4,
+  MinPointMagMipLinear = 0x5,
+  MinLinearMagMipPoint = 0x10,
+  MinLinearMagPointMipLinear = 0x11,
+  MinMagLinearMipPoint = 0x14,
+  MinMagMipLinear = 0x15,
+  Anisotropic = 0x55,
+  ComparisonMinMagMipPoint = 0x80,
+  ComparisonMinMagPointMipLinear = 0x81,
+  ComparisonMinPointMagLinearMipPoint = 0x84,
+  ComparisonMinPointMagMipLinear = 0x85,
+  ComparisonMinLinearMagMipPoint = 0x90,
+  ComparisonMinLinearMagPointMipLinear = 0x91,
+  ComparisonMinMagLinearMipPoint = 0x94,
+  ComparisonMinMagMipLinear = 0x95,
+  ComparisonAnisotropic = 0xd5,
+  MinimumMinMagMipPoint = 0x100,
+  MinimumMinMagPointMipLinear = 0x101,
+  MinimumMinPointMagLinearMipPoint = 0x104,
+  MinimumMinPointMagMipLinear = 0x105,
+  MinimumMinLinearMagMipPoint = 0x110,
+  MinimumMinLinearMagPointMipLinear = 0x111,
+  MinimumMinMagLinearMipPoint = 0x114,
+  MinimumMinMagMipLinear = 0x115,
+  MinimumAnisotropic = 0x155,
+  MaximumMinMagMipPoint = 0x180,
+  MaximumMinMagPointMipLinear = 0x181,
+  MaximumMinPointMagLinearMipPoint = 0x184,
+  MaximumMinPointMagMipLinear = 0x185,
+  MaximumMinLinearMagMipPoint = 0x190,
+  MaximumMinLinearMagPointMipLinear = 0x191,
+  MaximumMinMagLinearMipPoint = 0x194,
+  MaximumMinMagMipLinear = 0x195,
+  MaximumAnisotropic = 0x1d5
+};
+
+// D3D12_TEXTURE_ADDRESS_MODE
+enum class TextureAddressMode {
+  Wrap = 1,
+  Mirror = 2,
+  Clamp = 3,
+  Border = 4,
+  MirrorOnce = 5
+};
+
+// D3D12_COMPARISON_FUNC
+enum class ComparisonFunc : unsigned {
+  Never = 1,
+  Less = 2,
+  Equal = 3,
+  LessEqual = 4,
+  Greater = 5,
+  NotEqual = 6,
+  GreaterEqual = 7,
+  Always = 8
+};
+
+// D3D12_STATIC_BORDER_COLOR
+enum class StaticBorderColor {
+  TransparentBlack = 0,
+  OpaqueBlack = 1,
+  OpaqueWhite = 2,
+  OpaqueBlackUint = 3,
+  OpaqueWhiteUint = 4
+};
+
 } // namespace dxil
 } // namespace llvm
 
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
index 765a3bcbed7e2..2cc6371479351 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp
@@ -40,30 +40,30 @@ static raw_ostream &operator<<(raw_o...
[truncated]

Copy link
Contributor

@bogner bogner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense to me. As a follow up, we should look into whether BinaryFormat/DXContainer.h can get some of these enum values from here rather than duplicating their values.

// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/

// D3D12_ROOT_SIGNATURE_FLAGS
enum class RootFlags : uint32_t {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should generate this values using tablegen, like we do in llvm/BinaryFormat/DXContainerConstants.def. In obj2yaml/yaml2obj this file is reused to provide a nicer interface to set flags, see the example here:

#define ROOT_ELEMENT_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From the front-end use case, there hasn't and I don't expect there to be a use-case of defining such helper functions. So I think adding it will add unneeded complexity.

If you are planning to re-use it for the back-end then we could maybe do that then?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, there are scenarios in the binary format and testing that such table gen simplifies the code quite a bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From offline: we will re-address this when the use-case is immediately visible (when re-using in backend-end)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, I think we're putting this in the wrong place here. These values are all part of the DXContainer, and we have definitions of them in BinaryFormat/DXContainer.h. It should be reasonable to depend on BinaryFormat anywhere we're using these, so we should probably just get them from there directly.

@bogner bogner self-requested a review June 10, 2025 21:47
// https://learn.microsoft.com/en-us/windows/win32/api/d3d12/

// D3D12_ROOT_SIGNATURE_FLAGS
enum class RootFlags : uint32_t {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, I think we're putting this in the wrong place here. These values are all part of the DXContainer, and we have definitions of them in BinaryFormat/DXContainer.h. It should be reasonable to depend on BinaryFormat anywhere we're using these, so we should probably just get them from there directly.

@inbelic
Copy link
Contributor Author

inbelic commented Jun 10, 2025

I will mark this as draft until I re-update it to use the values from DXContainer.h. Some of the enums are not yet defined, so either we will wait until they are defined to refactor, or, we can define them here.

@inbelic inbelic marked this pull request as draft June 10, 2025 23:10
@inbelic
Copy link
Contributor Author

inbelic commented Jun 18, 2025

I will close this pr and create a new one to target once the StaticSampler and DescriptorTable back-end parsing is created.

@inbelic inbelic closed this Jun 18, 2025
@inbelic inbelic deleted the inbelic/rs-move-d3d-headers branch June 18, 2025 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:DirectX clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category HLSL HLSL Language Support llvm:support llvm:transforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants