[llvm] [DirectX] Updating DXContainer Yaml to represent Root Signature 1.2 (PR #159659)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 24 12:24:22 PDT 2025
https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/159659
>From 787c77638092b06e7648f03660a4429dc602aac6 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 18 Sep 2025 14:16:25 -0700
Subject: [PATCH 1/6] adding yaml representation and updating write logic
---
llvm/include/llvm/BinaryFormat/DXContainer.h | 24 ++++++++
.../BinaryFormat/DXContainerConstants.def | 10 +++
.../llvm/MC/DXContainerRootSignature.h | 1 +
.../include/llvm/ObjectYAML/DXContainerYAML.h | 5 ++
llvm/lib/BinaryFormat/DXContainer.cpp | 9 +++
.../HLSL/RootSignatureValidations.cpp | 4 +-
llvm/lib/MC/DXContainerRootSignature.cpp | 7 ++-
llvm/lib/ObjectYAML/DXContainerEmitter.cpp | 3 +
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 12 ++++
.../ObjectYAML/DXContainerYAMLTest.cpp | 61 +++++++++++++++++++
10 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index c04380667a640..a08cfff4b4974 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -185,6 +185,15 @@ enum class DescriptorRangeFlags : uint32_t {
LLVM_ABI ArrayRef<EnumEntry<DescriptorRangeFlags>> getDescriptorRangeFlags();
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) Enum = Num,
+enum class StaticSamplerFlags : uint32_t {
+#include "DXContainerConstants.def"
+
+ LLVM_MARK_AS_BITMASK_ENUM(NonNormalizedCoordinates)
+};
+
+LLVM_ABI ArrayRef<EnumEntry<StaticSamplerFlags>> getStaticSamplerFlags();
+
#define ROOT_PARAMETER(Val, Enum) Enum = Val,
enum class RootParameterType : uint32_t {
#include "DXContainerConstants.def"
@@ -813,6 +822,21 @@ struct DescriptorRange {
}
};
} // namespace v2
+namespace v3 {
+struct StaticSampler : public v1::StaticSampler {
+ uint32_t Flags;
+
+ StaticSampler() = default;
+ explicit StaticSampler(v1::StaticSampler &Base)
+ : v1::StaticSampler(Base), Flags(0U) {}
+
+ void swapBytes() {
+ v1::StaticSampler::swapBytes();
+ sys::swapByteOrder(Flags);
+ }
+};
+
+} // namespace v3
} // namespace RTS0
// D3D_ROOT_SIGNATURE_VERSION
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 889653611d79a..f576d958037cd 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -104,6 +104,16 @@ DESCRIPTOR_RANGE_FLAG(0x10000, DescriptorsStaticKeepingBufferBoundsChecks, DESCR
#undef DESCRIPTOR_RANGE_FLAG
#endif // DESCRIPTOR_RANGE_FLAG
+// STATIC_SAMPLER_FLAG(flag value, name, flag).
+#ifdef STATIC_SAMPLER_FLAG
+
+STATIC_SAMPLER_FLAG(0x0, None, SAMPLER_FLAG_NONE)
+STATIC_SAMPLER_FLAG(0x1, UintBorderColor, SAMPLER_FLAG_UINT_BORDER_COLOR)
+STATIC_SAMPLER_FLAG(0x2, NonNormalizedCoordinates, SAMPLER_FLAG_NON_NORMALIZED_COORDINATES)
+
+#undef STATIC_SAMPLER_FLAG
+#endif // STATIC_SAMPLER_FLAG
+
#ifdef ROOT_PARAMETER
ROOT_PARAMETER(0, DescriptorTable)
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 54677ef70244f..2a76e81fefc5f 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -74,6 +74,7 @@ struct StaticSampler {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
dxbc::ShaderVisibility ShaderVisibility;
+ uint32_t Flags;
};
struct RootParametersContainer {
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 62bfee7693db1..b5b110d0f59a1 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -178,6 +178,11 @@ struct StaticSamplerYamlDesc {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
dxbc::ShaderVisibility ShaderVisibility;
+
+ LLVM_ABI uint32_t getEncodedFlags() const;
+
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) bool Enum = false;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
};
struct RootSignatureYamlDesc {
diff --git a/llvm/lib/BinaryFormat/DXContainer.cpp b/llvm/lib/BinaryFormat/DXContainer.cpp
index 36d10d0b63078..c06a3e34653f0 100644
--- a/llvm/lib/BinaryFormat/DXContainer.cpp
+++ b/llvm/lib/BinaryFormat/DXContainer.cpp
@@ -89,6 +89,15 @@ ArrayRef<EnumEntry<DescriptorRangeFlags>> dxbc::getDescriptorRangeFlags() {
return ArrayRef(DescriptorRangeFlagNames);
}
+static const EnumEntry<StaticSamplerFlags> StaticSamplerFlagNames[] = {
+#define STATIC_SAMPLER_FLAG(Val, Enum, Flag) {#Enum, StaticSamplerFlags::Enum},
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+};
+
+ArrayRef<EnumEntry<StaticSamplerFlags>> dxbc::getStaticSamplerFlags() {
+ return ArrayRef(StaticSamplerFlagNames);
+}
+
#define SHADER_VISIBILITY(Val, Enum) {#Enum, ShaderVisibility::Enum},
static const EnumEntry<ShaderVisibility> ShaderVisibilityValues[] = {
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 0970977b5064f..8c298f0685286 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -20,7 +20,9 @@ namespace rootsig {
bool verifyRootFlag(uint32_t Flags) { return (Flags & ~0xfff) == 0; }
-bool verifyVersion(uint32_t Version) { return (Version == 1 || Version == 2); }
+bool verifyVersion(uint32_t Version) {
+ return (Version == 1 || Version == 2 || Version == 3);
+}
bool verifyRegisterValue(uint32_t RegisterValue) {
return RegisterValue != ~0U;
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index b9ebb7a9e789c..13784e7c86684 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -33,7 +33,9 @@ static uint32_t rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,
size_t RootSignatureDesc::getSize() const {
uint32_t StaticSamplersOffset = computeStaticSamplersOffset();
size_t StaticSamplersSize =
- StaticSamplers.size() * sizeof(dxbc::RTS0::v1::StaticSampler);
+ (Version > 2 ? sizeof(dxbc::RTS0::v3::StaticSampler)
+ : sizeof(dxbc::RTS0::v1::StaticSampler)) *
+ StaticSamplers.size();
return size_t(StaticSamplersOffset) + StaticSamplersSize;
}
@@ -171,6 +173,9 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
support::endian::write(BOS, S.ShaderRegister, llvm::endianness::little);
support::endian::write(BOS, S.RegisterSpace, llvm::endianness::little);
support::endian::write(BOS, S.ShaderVisibility, llvm::endianness::little);
+
+ if (Version > 2)
+ support::endian::write(BOS, S.Flags, llvm::endianness::little);
}
assert(Storage.size() == getSize());
OS.write(Storage.data(), Storage.size());
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index 910383816f43b..b00e45d912be1 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -343,6 +343,9 @@ Error DXContainerWriter::writeParts(raw_ostream &OS) {
NewSampler.RegisterSpace = Param.RegisterSpace;
NewSampler.ShaderVisibility = Param.ShaderVisibility;
+ if (RS.Version > 2)
+ NewSampler.Flags = Param.getEncodedFlags();
+
RS.StaticSamplers.push_back(NewSampler);
}
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 22674b1ceb734..39f42fb4dc839 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -245,6 +245,15 @@ uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
return Flags;
}
+uint32_t DXContainerYAML::StaticSamplerYamlDesc::getEncodedFlags() const {
+ uint64_t Flags = 0;
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
+ if (Enum) \
+ Flags |= (uint32_t)dxbc::StaticSamplerFlags::Enum;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ return Flags;
+}
+
uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
uint64_t Flag = 0;
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
@@ -512,6 +521,9 @@ void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
IO.mapRequired("ShaderRegister", S.ShaderRegister);
IO.mapRequired("RegisterSpace", S.RegisterSpace);
IO.mapRequired("ShaderVisibility", S.ShaderVisibility);
+
+#define STATIC_SAMPLER_FLAG_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
+#include "llvm/BinaryFormat/DXContainerConstants.def"
}
void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index b0ad208625436..eee0b64e4b866 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -526,3 +526,64 @@ TEST(RootSignature, ParseStaticSamplers) {
EXPECT_EQ(Storage.size(), 144u);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 144u) == 0);
}
+
+TEST(RootSignature, ParseStaticSamplersV13) {
+ SmallString<128> Storage;
+
+ // First read a fully explicit yaml with all sizes and offsets provided
+ ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+Header:
+ Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ Version:
+ Major: 1
+ Minor: 0
+ PartCount: 1
+ PartOffsets: [ 60 ]
+Parts:
+ - Name: RTS0
+ Size: 76
+ RootSignature:
+ Version: 3
+ NumRootParameters: 0
+ RootParametersOffset: 24
+ NumStaticSamplers: 1
+ StaticSamplersOffset: 24
+ Parameters: []
+ Samplers:
+ - Filter: MinLinearMagMipPoint
+ AddressU: Wrap
+ AddressV: Mirror
+ AddressW: MirrorOnce
+ MipLODBias: 1.23
+ MaxAnisotropy: 20
+ ComparisonFunc: LessEqual
+ BorderColor: TransparentBlack
+ MinLOD: 4.56
+ MaxLOD: 8.90
+ ShaderRegister: 31
+ RegisterSpace: 32
+ ShaderVisibility: Mesh
+ SAMPLER_FLAG_UINT_BORDER_COLOR: true
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+ )"));
+
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
+ 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x01};
+
+ EXPECT_EQ(Storage.size(), 148U);
+ EXPECT_TRUE(memcmp(Buffer, Storage.data(), 148U) == 0);
+}
>From 57fd710107c459b53e2f9fe2c3f0de3f24d6b064 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 18 Sep 2025 16:54:27 -0700
Subject: [PATCH 2/6] fix test
---
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 4 ++--
llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 39f42fb4dc839..42074731c4e16 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -521,8 +521,8 @@ void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
IO.mapRequired("ShaderRegister", S.ShaderRegister);
IO.mapRequired("RegisterSpace", S.RegisterSpace);
IO.mapRequired("ShaderVisibility", S.ShaderVisibility);
-
-#define STATIC_SAMPLER_FLAG_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
+ IO.mapOptional(#Flag, S.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index eee0b64e4b866..db9861f0149a4 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -528,7 +528,7 @@ TEST(RootSignature, ParseStaticSamplers) {
}
TEST(RootSignature, ParseStaticSamplersV13) {
- SmallString<128> Storage;
+ SmallString<160> Storage;
// First read a fully explicit yaml with all sizes and offsets provided
ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
@@ -575,14 +575,14 @@ TEST(RootSignature, ParseStaticSamplersV13) {
0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
- 0x01};
+ 0x01, 0x00, 0x00, 0x00};
EXPECT_EQ(Storage.size(), 148U);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 148U) == 0);
>From d72adfe11a56a57e970f28b7ff0725c316ec8900 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Fri, 19 Sep 2025 10:46:53 -0700
Subject: [PATCH 3/6] adding missing test
---
.../RootSignature-Invalid-Version.ll | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Invalid-Version.ll
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Invalid-Version.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Invalid-Version.ll
new file mode 100644
index 0000000000000..26867e6d7ec25
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-Invalid-Version.ll
@@ -0,0 +1,20 @@
+; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
+
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+
+; CHECK: error: Invalid value for Version: 4
+; CHECK-NOT: Root Signature Definitions
+define void @main() #0 {
+entry:
+ ret void
+}
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+
+!dx.rootsignatures = !{!2, !3, !4, !5} ; list of function/root signature pairs
+!2 = !{ ptr @main, !6, i32 1 } ; function, root signature
+!3 = !{ ptr @main, !6, i32 4 } ; function, root signature
+!4 = !{ ptr @main, !6, i32 2 } ; function, root signature
+!5 = !{ ptr @main, !6, i32 3 } ; function, root signature
+!6 = !{ } ; list of root signature elements
>From ddf99455e409897f245c38dc98234f43ff51325b Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 24 Sep 2025 11:45:28 -0700
Subject: [PATCH 4/6] changing size and remove untested parameters
---
llvm/include/llvm/BinaryFormat/DXContainer.h | 1 +
.../ObjectYAML/DXContainerYAMLTest.cpp | 26 ++++++-------------
2 files changed, 9 insertions(+), 18 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index a08cfff4b4974..08a7ddb6929f5 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -822,6 +822,7 @@ struct DescriptorRange {
}
};
} // namespace v2
+
namespace v3 {
struct StaticSampler : public v1::StaticSampler {
uint32_t Flags;
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index db9861f0149a4..1b21fe01dfca9 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -528,7 +528,7 @@ TEST(RootSignature, ParseStaticSamplers) {
}
TEST(RootSignature, ParseStaticSamplersV13) {
- SmallString<160> Storage;
+ SmallString<128> Storage;
// First read a fully explicit yaml with all sizes and offsets provided
ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
@@ -551,19 +551,9 @@ TEST(RootSignature, ParseStaticSamplersV13) {
StaticSamplersOffset: 24
Parameters: []
Samplers:
- - Filter: MinLinearMagMipPoint
- AddressU: Wrap
- AddressV: Mirror
- AddressW: MirrorOnce
- MipLODBias: 1.23
- MaxAnisotropy: 20
- ComparisonFunc: LessEqual
- BorderColor: TransparentBlack
- MinLOD: 4.56
- MaxLOD: 8.90
- ShaderRegister: 31
+ - ShaderRegister: 31
RegisterSpace: 32
- ShaderVisibility: Mesh
+ ShaderVisibility: All
SAMPLER_FLAG_UINT_BORDER_COLOR: true
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
@@ -577,11 +567,11 @@ TEST(RootSignature, ParseStaticSamplersV13) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
- 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x7f,
+ 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00};
EXPECT_EQ(Storage.size(), 148U);
>From 284901cb5c5664a8213254773dc3401e59a2c119 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 24 Sep 2025 11:47:22 -0700
Subject: [PATCH 5/6] adding suggested comment
---
llvm/include/llvm/MC/DXContainerRootSignature.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 2a76e81fefc5f..514e74b92d101 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -74,6 +74,7 @@ struct StaticSampler {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
dxbc::ShaderVisibility ShaderVisibility;
+ // Version 3 onwards:
uint32_t Flags;
};
>From 73e6bb53cf5d71b3cf0f4914207782d7636af0f5 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 24 Sep 2025 12:24:05 -0700
Subject: [PATCH 6/6] addressing inbelic comments
---
.../Frontend/HLSL/RootSignatureValidations.h | 2 ++
.../llvm/MC/DXContainerRootSignature.h | 2 +-
.../Frontend/HLSL/RootSignatureMetadata.cpp | 7 +++++++
.../HLSL/RootSignatureValidations.cpp | 15 +++++++++++++++
llvm/lib/MC/DXContainerRootSignature.cpp | 10 +++++-----
...otSignature-StaticSamplers-Invalid-Flag.ll | 19 +++++++++++++++++++
6 files changed, 49 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll
diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
index ea96094b18300..46a6e6eac379e 100644
--- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
+++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h
@@ -33,6 +33,8 @@ LLVM_ABI bool verifyRangeType(uint32_t Type);
LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version,
dxil::ResourceClass Type,
dxbc::DescriptorRangeFlags FlagsVal);
+LLVM_ABI bool verifyStaticSamplerFlags(uint32_t Version,
+ dxbc::StaticSamplerFlags Flags);
LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors);
LLVM_ABI bool verifyMipLODBias(float MipLODBias);
LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy);
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 514e74b92d101..2b08b2439d2c0 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -75,7 +75,7 @@ struct StaticSampler {
uint32_t RegisterSpace;
dxbc::ShaderVisibility ShaderVisibility;
// Version 3 onwards:
- uint32_t Flags;
+ uint32_t Flags = 0;
};
struct RootParametersContainer {
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..417169576f5d9 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -651,6 +651,13 @@ Error MetadataParser::validateRootSignature(
joinErrors(std::move(DeferredErrs),
make_error<RootSignatureValidationError<uint32_t>>(
"RegisterSpace", Sampler.RegisterSpace));
+
+ if (!hlsl::rootsig::verifyStaticSamplerFlags(
+ RSD.Version, dxbc::StaticSamplerFlags(Sampler.Flags)))
+ DeferredErrs =
+ joinErrors(std::move(DeferredErrs),
+ make_error<RootSignatureValidationError<uint32_t>>(
+ "Static Sampler Flag", Sampler.Flags));
}
return DeferredErrs;
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 8c298f0685286..ef1021417414b 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -113,6 +113,21 @@ bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type,
return (Flags & ~Mask) == FlagT::None;
}
+bool verifyStaticSamplerFlags(uint32_t Version,
+ dxbc::StaticSamplerFlags Flags) {
+
+ if (Version <= 2)
+ return Flags == dxbc::StaticSamplerFlags::None;
+
+ assert(Version == 3 && "Provided invalid root signature version");
+
+ dxbc::StaticSamplerFlags Mask =
+ dxbc::StaticSamplerFlags::NonNormalizedCoordinates |
+ dxbc::StaticSamplerFlags::UintBorderColor |
+ dxbc::StaticSamplerFlags::None;
+ return (Flags | Mask) == Mask;
+}
+
bool verifyNumDescriptors(uint32_t NumDescriptors) {
return NumDescriptors > 0;
}
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index 13784e7c86684..2338370d84389 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -32,12 +32,12 @@ static uint32_t rewriteOffsetToCurrentByte(raw_svector_ostream &Stream,
size_t RootSignatureDesc::getSize() const {
uint32_t StaticSamplersOffset = computeStaticSamplersOffset();
- size_t StaticSamplersSize =
- (Version > 2 ? sizeof(dxbc::RTS0::v3::StaticSampler)
- : sizeof(dxbc::RTS0::v1::StaticSampler)) *
- StaticSamplers.size();
+ size_t StaticSamplersSize = sizeof(dxbc::RTS0::v1::StaticSampler);
+ if (Version > 2)
+ StaticSamplersSize = sizeof(dxbc::RTS0::v3::StaticSampler);
- return size_t(StaticSamplersOffset) + StaticSamplersSize;
+ return size_t(StaticSamplersOffset) +
+ (StaticSamplersSize * StaticSamplers.size());
}
uint32_t RootSignatureDesc::computeRootParametersOffset() const {
diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll
new file mode 100644
index 0000000000000..fa5bf12e2b8cd
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll
@@ -0,0 +1,19 @@
+; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s
+
+
+target triple = "dxil-unknown-shadermodel6.0-compute"
+
+; CHECK: error: Invalid value for ShaderVisibility: 666
+; CHECK-NOT: Root Signature Definitions
+
+define void @main() #0 {
+entry:
+ ret void
+}
+attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }
+
+
+!dx.rootsignatures = !{!2} ; list of function/root signature pairs
+!2 = !{ ptr @main, !3, i32 2 } ; function, root signature
+!3 = !{ !5 } ; list of root signature elements
+!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 666 }
More information about the llvm-commits
mailing list