[clang] [llvm] [HLSL] Update Frontend to support version 1.2 of root signature (PR #160616)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 1 13:08:49 PDT 2025
https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/160616
>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 01/25] 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 02/25] 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 03/25] 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 fefd58c2ab1044ac51c546b6bc6df968eb5edaa8 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Fri, 19 Sep 2025 12:48:11 -0700
Subject: [PATCH 04/25] fix test
---
llvm/include/llvm/Object/DXContainer.h | 57 ++++++++++++++++-------
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 16 ++++++-
llvm/unittests/Object/DXContainerTest.cpp | 16 ++++---
3 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 9bc1918852335..e3e532f6635a4 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -123,25 +123,26 @@ template <typename T> struct ViewArray {
};
namespace DirectX {
+
+template <typename T> Expected<T> readParameter(StringRef Data) {
+ T Struct;
+ if (sizeof(T) != Data.size())
+ return make_error<GenericBinaryError>(
+ "Reading structure out of file bounds", object_error::parse_failed);
+
+ memcpy(&Struct, Data.data(), sizeof(T));
+ // DXContainer is always little endian
+ if (sys::IsBigEndianHost)
+ Struct.swapBytes();
+ return Struct;
+}
+
struct RootParameterView {
const dxbc::RTS0::v1::RootParameterHeader &Header;
StringRef ParamData;
RootParameterView(const dxbc::RTS0::v1::RootParameterHeader &H, StringRef P)
: Header(H), ParamData(P) {}
-
- template <typename T> Expected<T> readParameter() {
- T Struct;
- if (sizeof(T) != ParamData.size())
- return make_error<GenericBinaryError>(
- "Reading structure out of file bounds", object_error::parse_failed);
-
- memcpy(&Struct, ParamData.data(), sizeof(T));
- // DXContainer is always little endian
- if (sys::IsBigEndianHost)
- Struct.swapBytes();
- return Struct;
- }
};
struct RootConstantView : RootParameterView {
@@ -151,7 +152,7 @@ struct RootConstantView : RootParameterView {
}
llvm::Expected<dxbc::RTS0::v1::RootConstants> read() {
- return readParameter<dxbc::RTS0::v1::RootConstants>();
+ return readParameter<dxbc::RTS0::v1::RootConstants>(ParamData);
}
};
@@ -167,7 +168,8 @@ struct RootDescriptorView : RootParameterView {
llvm::Expected<dxbc::RTS0::v2::RootDescriptor> read(uint32_t Version) {
if (Version == 1) {
- auto Descriptor = readParameter<dxbc::RTS0::v1::RootDescriptor>();
+ auto Descriptor =
+ readParameter<dxbc::RTS0::v1::RootDescriptor>(ParamData);
if (Error E = Descriptor.takeError())
return E;
return dxbc::RTS0::v2::RootDescriptor(*Descriptor);
@@ -176,9 +178,10 @@ struct RootDescriptorView : RootParameterView {
return make_error<GenericBinaryError>("Invalid Root Signature version: " +
Twine(Version),
object_error::parse_failed);
- return readParameter<dxbc::RTS0::v2::RootDescriptor>();
+ return readParameter<dxbc::RTS0::v2::RootDescriptor>(ParamData);
}
};
+
template <typename T> struct DescriptorTable {
uint32_t NumRanges;
uint32_t RangesOffset;
@@ -247,8 +250,26 @@ class RootSignature {
llvm::iterator_range<param_header_iterator> param_headers() const {
return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
}
- llvm::iterator_range<samplers_iterator> samplers() const {
- return llvm::make_range(StaticSamplers.begin(), StaticSamplers.end());
+ llvm::Expected<dxbc::RTS0::v3::StaticSampler> getSampler(uint32_t Loc) const {
+ if (Loc >= getNumStaticSamplers())
+ return parseFailed("Static sampler index out of range");
+
+ auto SamplerSize = (Version <= 2) ? sizeof(dxbc::RTS0::v1::StaticSampler)
+ : sizeof(dxbc::RTS0::v3::StaticSampler);
+
+ StringRef Buff = PartData.substr(StaticSamplersOffset + (Loc * SamplerSize),
+ SamplerSize);
+ if (Version < 3) {
+ auto Sampler = readParameter<dxbc::RTS0::v1::StaticSampler>(Buff);
+ if (Error E = Sampler.takeError())
+ return E;
+ return dxbc::RTS0::v3::StaticSampler(*Sampler);
+ }
+ if (Version != 3)
+ return make_error<GenericBinaryError>("Invalid Root Signature version: " +
+ Twine(Version),
+ object_error::parse_failed);
+ return readParameter<dxbc::RTS0::v3::StaticSampler>(Buff);
}
uint32_t getFlags() const { return Flags; }
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 42074731c4e16..6f24b7d2573ec 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -163,7 +163,13 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
- for (const auto &S : Data.samplers()) {
+ for (uint32_t Loc = 0; Loc < Data.getNumStaticSamplers(); ++Loc) {
+ llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler =
+ Data.getSampler(Loc);
+ if (Error E = MaybeSampler.takeError())
+ return std::move(E);
+ const llvm::dxbc::RTS0::v3::StaticSampler &S = *MaybeSampler;
+
if (!dxbc::isValidSamplerFilter(S.Filter))
return createStringError(std::errc::invalid_argument,
"Invalid value for static sampler filter");
@@ -209,6 +215,14 @@ DXContainerYAML::RootSignatureYamlDesc::create(
NewS.RegisterSpace = S.RegisterSpace;
NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);
+ if (Version > 2) {
+ if (Version > 1) {
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
+ NewS.Enum = \
+ (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ }
+ }
RootSigDesc.StaticSamplers.push_back(NewS);
}
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 396d060a75bfd..f2a7bdfdcd75a 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1165,11 +1165,11 @@ TEST(RootSignature, ParseStaticSamplers) {
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, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 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,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 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, 0x07, 0x00, 0x00, 0x00};
DXContainer C =
llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
@@ -1179,12 +1179,14 @@ TEST(RootSignature, ParseStaticSamplers) {
const auto &RS = MaybeRS.value();
ASSERT_EQ(RS.getVersion(), 2u);
ASSERT_EQ(RS.getNumParameters(), 0u);
- ASSERT_EQ(RS.getRootParametersOffset(), 0u);
+ ASSERT_EQ(RS.getRootParametersOffset(), 24u);
ASSERT_EQ(RS.getNumStaticSamplers(), 1u);
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
- auto Sampler = *RS.samplers().begin();
+ auto MaybeSamplerView = RS.getSampler(0);
+ ASSERT_THAT_ERROR(MaybeSamplerView.takeError(), Succeeded());
+ const auto &Sampler = *MaybeSamplerView;
ASSERT_EQ(Sampler.Filter, 10u);
ASSERT_EQ(Sampler.AddressU, 1u);
>From 1d0cbd39875a84c983106678c8b857d8157bfa51 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 10:28:12 -0700
Subject: [PATCH 05/25] adding samplers_iterator
---
llvm/include/llvm/Object/DXContainer.h | 70 +++++++++++++++++------
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 5 +-
llvm/unittests/Object/DXContainerTest.cpp | 2 +-
3 files changed, 56 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e3e532f6635a4..e3913ece842bc 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -223,6 +223,28 @@ static Error parseFailed(const Twine &Msg) {
class RootSignature {
private:
+ struct samplers_iterator {
+ const RootSignature *Parent = nullptr;
+ uint32_t Index = 0;
+
+ llvm::Expected<dxbc::RTS0::v3::StaticSampler> operator*() const {
+ return Parent->getSampler(Index);
+ }
+
+ samplers_iterator &operator++() {
+ ++Index;
+ return *this;
+ }
+
+ bool operator==(const samplers_iterator &Other) const {
+ return Parent == Other.Parent && Index == Other.Index;
+ }
+
+ bool operator!=(const samplers_iterator &Other) const {
+ return !(*this == Other);
+ }
+ };
+
uint32_t Version;
uint32_t NumParameters;
uint32_t RootParametersOffset;
@@ -233,23 +255,6 @@ class RootSignature {
StringRef PartData;
ViewArray<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
- using param_header_iterator =
- ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
- using samplers_iterator = ViewArray<dxbc::RTS0::v1::StaticSampler>::iterator;
-
-public:
- RootSignature(StringRef PD) : PartData(PD) {}
-
- LLVM_ABI Error parse();
- uint32_t getVersion() const { return Version; }
- uint32_t getNumParameters() const { return NumParameters; }
- uint32_t getRootParametersOffset() const { return RootParametersOffset; }
- uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
- uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
- uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
- llvm::iterator_range<param_header_iterator> param_headers() const {
- return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
- }
llvm::Expected<dxbc::RTS0::v3::StaticSampler> getSampler(uint32_t Loc) const {
if (Loc >= getNumStaticSamplers())
return parseFailed("Static sampler index out of range");
@@ -271,6 +276,37 @@ class RootSignature {
object_error::parse_failed);
return readParameter<dxbc::RTS0::v3::StaticSampler>(Buff);
}
+
+ using param_header_iterator =
+ ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
+
+public:
+ RootSignature(StringRef PD) : PartData(PD) {}
+
+ LLVM_ABI Error parse();
+ uint32_t getVersion() const { return Version; }
+ uint32_t getNumParameters() const { return NumParameters; }
+ uint32_t getRootParametersOffset() const { return RootParametersOffset; }
+ uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
+ uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
+ uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
+
+ samplers_iterator samplers_begin() const {
+ return samplers_iterator{this, 0};
+ }
+
+ samplers_iterator samplers_end() const {
+ return samplers_iterator{this, getNumStaticSamplers()};
+ }
+
+ llvm::iterator_range<samplers_iterator> samplers() const {
+ return llvm::make_range(samplers_begin(), samplers_end());
+ }
+
+ llvm::iterator_range<param_header_iterator> param_headers() const {
+ return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
+ }
+
uint32_t getFlags() const { return Flags; }
llvm::Expected<RootParameterView>
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 6f24b7d2573ec..91f86caaa4005 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -163,9 +163,8 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
- for (uint32_t Loc = 0; Loc < Data.getNumStaticSamplers(); ++Loc) {
- llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler =
- Data.getSampler(Loc);
+ for (llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler :
+ Data.samplers()) {
if (Error E = MaybeSampler.takeError())
return std::move(E);
const llvm::dxbc::RTS0::v3::StaticSampler &S = *MaybeSampler;
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 923df70f44194..fe898c430b8a3 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1184,7 +1184,7 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
- auto MaybeSamplerView = RS.getSampler(0);
+ auto MaybeSamplerView = *RS.samplers().begin();
ASSERT_THAT_ERROR(MaybeSamplerView.takeError(), Succeeded());
const auto &Sampler = *MaybeSamplerView;
>From e530bcc1b81b300a12ada139c54553b84ab89a03 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 11:29:55 -0700
Subject: [PATCH 06/25] this was easier than I thought
---
llvm/include/llvm/Object/DXContainer.h | 62 ++---------------------
llvm/lib/Object/DXContainer.cpp | 13 +++--
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 6 +--
llvm/unittests/Object/DXContainerTest.cpp | 49 ++++++++++++++++--
4 files changed, 61 insertions(+), 69 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e3913ece842bc..0bfc5cec48da4 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -223,28 +223,6 @@ static Error parseFailed(const Twine &Msg) {
class RootSignature {
private:
- struct samplers_iterator {
- const RootSignature *Parent = nullptr;
- uint32_t Index = 0;
-
- llvm::Expected<dxbc::RTS0::v3::StaticSampler> operator*() const {
- return Parent->getSampler(Index);
- }
-
- samplers_iterator &operator++() {
- ++Index;
- return *this;
- }
-
- bool operator==(const samplers_iterator &Other) const {
- return Parent == Other.Parent && Index == Other.Index;
- }
-
- bool operator!=(const samplers_iterator &Other) const {
- return !(*this == Other);
- }
- };
-
uint32_t Version;
uint32_t NumParameters;
uint32_t RootParametersOffset;
@@ -253,32 +231,11 @@ class RootSignature {
uint32_t Flags;
ViewArray<dxbc::RTS0::v1::RootParameterHeader> ParametersHeaders;
StringRef PartData;
- ViewArray<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
-
- llvm::Expected<dxbc::RTS0::v3::StaticSampler> getSampler(uint32_t Loc) const {
- if (Loc >= getNumStaticSamplers())
- return parseFailed("Static sampler index out of range");
-
- auto SamplerSize = (Version <= 2) ? sizeof(dxbc::RTS0::v1::StaticSampler)
- : sizeof(dxbc::RTS0::v3::StaticSampler);
-
- StringRef Buff = PartData.substr(StaticSamplersOffset + (Loc * SamplerSize),
- SamplerSize);
- if (Version < 3) {
- auto Sampler = readParameter<dxbc::RTS0::v1::StaticSampler>(Buff);
- if (Error E = Sampler.takeError())
- return E;
- return dxbc::RTS0::v3::StaticSampler(*Sampler);
- }
- if (Version != 3)
- return make_error<GenericBinaryError>("Invalid Root Signature version: " +
- Twine(Version),
- object_error::parse_failed);
- return readParameter<dxbc::RTS0::v3::StaticSampler>(Buff);
- }
+ ViewArray<dxbc::RTS0::v3::StaticSampler> StaticSamplers;
using param_header_iterator =
ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
+ using samplers_iterator = ViewArray<dxbc::RTS0::v3::StaticSampler>::iterator;
public:
RootSignature(StringRef PD) : PartData(PD) {}
@@ -290,21 +247,12 @@ class RootSignature {
uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
-
- samplers_iterator samplers_begin() const {
- return samplers_iterator{this, 0};
- }
-
- samplers_iterator samplers_end() const {
- return samplers_iterator{this, getNumStaticSamplers()};
+ llvm::iterator_range<param_header_iterator> param_headers() const {
+ return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
}
llvm::iterator_range<samplers_iterator> samplers() const {
- return llvm::make_range(samplers_begin(), samplers_end());
- }
-
- llvm::iterator_range<param_header_iterator> param_headers() const {
- return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
+ return llvm::make_range(StaticSamplers.begin(), StaticSamplers.end());
}
uint32_t getFlags() const { return Flags; }
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index 031b9414f4c1a..b7da8316840f0 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include <cstddef>
+
#include "llvm/Object/DXContainer.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
@@ -276,10 +278,13 @@ Error DirectX::RootSignature::parse() {
RootParametersOffset,
NumParameters * sizeof(dxbc::RTS0::v1::RootParameterHeader));
- StaticSamplers.Stride = sizeof(dxbc::RTS0::v1::StaticSampler);
- StaticSamplers.Data = PartData.substr(
- StaticSamplersOffset,
- NumStaticSamplers * sizeof(dxbc::RTS0::v1::StaticSampler));
+ StaticSamplers.Stride = (Version <= 2)
+ ? sizeof(dxbc::RTS0::v1::StaticSampler)
+ : sizeof(dxbc::RTS0::v3::StaticSampler);
+
+ StaticSamplers.Data = PartData.substr(StaticSamplersOffset,
+ static_cast<size_t>(NumStaticSamplers) *
+ StaticSamplers.Stride);
return Error::success();
}
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 91f86caaa4005..2fde1b86247f8 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -163,11 +163,7 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
- for (llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler :
- Data.samplers()) {
- if (Error E = MaybeSampler.takeError())
- return std::move(E);
- const llvm::dxbc::RTS0::v3::StaticSampler &S = *MaybeSampler;
+ for (const auto &S : Data.samplers()) {
if (!dxbc::isValidSamplerFilter(S.Filter))
return createStringError(std::errc::invalid_argument,
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index fe898c430b8a3..76b2aed5bb591 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1184,9 +1184,7 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
- auto MaybeSamplerView = *RS.samplers().begin();
- ASSERT_THAT_ERROR(MaybeSamplerView.takeError(), Succeeded());
- const auto &Sampler = *MaybeSamplerView;
+ auto Sampler = *RS.samplers().begin();
ASSERT_EQ(Sampler.Filter, 10u);
ASSERT_EQ(Sampler.AddressU, 1u);
@@ -1202,4 +1200,49 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(Sampler.RegisterSpace, 32u);
ASSERT_EQ(Sampler.ShaderVisibility, 7u);
}
+ {
+ 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, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 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, 0x00, 0x00, 0x00};
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<148>(Buffer)));
+
+ auto MaybeRS = C.getRootSignature();
+ ASSERT_TRUE(MaybeRS.has_value());
+ const auto &RS = MaybeRS.value();
+ ASSERT_EQ(RS.getVersion(), 3U);
+ ASSERT_EQ(RS.getNumParameters(), 0U);
+ ASSERT_EQ(RS.getRootParametersOffset(), 0U);
+ ASSERT_EQ(RS.getNumStaticSamplers(), 1U);
+ ASSERT_EQ(RS.getStaticSamplersOffset(), 24U);
+ ASSERT_EQ(RS.getFlags(), 17U);
+
+ auto Sampler = *RS.samplers().begin();
+
+ ASSERT_EQ(Sampler.Filter, 10U);
+ ASSERT_EQ(Sampler.AddressU, 1U);
+ ASSERT_EQ(Sampler.AddressV, 2U);
+ ASSERT_EQ(Sampler.AddressW, 5U);
+ ASSERT_FLOAT_EQ(Sampler.MipLODBias, 1.23F);
+ ASSERT_EQ(Sampler.MaxAnisotropy, 20U);
+ ASSERT_EQ(Sampler.ComparisonFunc, 4U);
+ ASSERT_EQ(Sampler.BorderColor, 0U);
+ ASSERT_FLOAT_EQ(Sampler.MinLOD, 4.56F);
+ ASSERT_FLOAT_EQ(Sampler.MaxLOD, 8.9F);
+ ASSERT_EQ(Sampler.ShaderRegister, 31U);
+ ASSERT_EQ(Sampler.RegisterSpace, 32U);
+ ASSERT_EQ(Sampler.ShaderVisibility, 7U);
+ ASSERT_EQ(Sampler.Flags, 1U);
+ }
}
>From 79ea587527552aaf93110098b526a88edbce620b Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 12:17:34 -0700
Subject: [PATCH 07/25] adding new test
---
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 2 -
.../RootSignature-StaticSamplers1.3.yaml | 65 +++++++++++++++++++
2 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 2fde1b86247f8..806722be0813d 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -211,12 +211,10 @@ DXContainerYAML::RootSignatureYamlDesc::create(
NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);
if (Version > 2) {
- if (Version > 1) {
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
NewS.Enum = \
(S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
- }
}
RootSigDesc.StaticSamplers.push_back(NewS);
}
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml
new file mode 100644
index 0000000000000..1623b05def009
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml
@@ -0,0 +1,65 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !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: 80
+ 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
+
+#CHECK: - Name: RTS0
+#CHECK-NEXT: Size: 80
+#CHECK-NEXT: RootSignature:
+#CHECK-NEXT: Version: 3
+#CHECK-NEXT: NumRootParameters: 0
+#CHECK-NEXT: RootParametersOffset: 24
+#CHECK-NEXT: NumStaticSamplers: 1
+#CHECK-NEXT: StaticSamplersOffset: 24
+#CHECK-NEXT: Parameters: []
+#CHECK-NEXT: Samplers:
+#CHECK-NEXT: - Filter: MinLinearMagMipPoint
+#CHECK-NEXT: AddressU: Wrap
+#CHECK-NEXT: AddressV: Mirror
+#CHECK-NEXT: AddressW: MirrorOnce
+#CHECK-NEXT: MipLODBias: 1.23
+#CHECK-NEXT: MaxAnisotropy: 20
+#CHECK-NEXT: ComparisonFunc: LessEqual
+#CHECK-NEXT: BorderColor: TransparentBlack
+#CHECK-NEXT: MinLOD: 4.56
+#CHECK-NEXT: MaxLOD: 8.9
+#CHECK-NEXT: ShaderRegister: 31
+#CHECK-NEXT: RegisterSpace: 32
+#CHECK-NEXT: ShaderVisibility: Mesh
+#CHECK-NEXT: SAMPLER_FLAG_UINT_BORDER_COLOR: true
+#CHECK-NEXT: AllowInputAssemblerInputLayout: true
+#CHECK-NEXT: DenyGeometryShaderRootAccess: true
>From 905d5d39d93e35a512537bec76566abefc79ce27 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 12:32:25 -0700
Subject: [PATCH 08/25] clean up
---
llvm/include/llvm/Object/DXContainer.h | 33 +++++++++++------------
llvm/lib/Object/DXContainer.cpp | 2 --
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 1 -
llvm/unittests/Object/DXContainerTest.cpp | 2 +-
4 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 0bfc5cec48da4..6f10401dd2ba2 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -124,25 +124,25 @@ template <typename T> struct ViewArray {
namespace DirectX {
-template <typename T> Expected<T> readParameter(StringRef Data) {
- T Struct;
- if (sizeof(T) != Data.size())
- return make_error<GenericBinaryError>(
- "Reading structure out of file bounds", object_error::parse_failed);
-
- memcpy(&Struct, Data.data(), sizeof(T));
- // DXContainer is always little endian
- if (sys::IsBigEndianHost)
- Struct.swapBytes();
- return Struct;
-}
-
struct RootParameterView {
const dxbc::RTS0::v1::RootParameterHeader &Header;
StringRef ParamData;
RootParameterView(const dxbc::RTS0::v1::RootParameterHeader &H, StringRef P)
: Header(H), ParamData(P) {}
+
+ template <typename T> Expected<T> readParameter() {
+ T Struct;
+ if (sizeof(T) != ParamData.size())
+ return make_error<GenericBinaryError>(
+ "Reading structure out of file bounds", object_error::parse_failed);
+
+ memcpy(&Struct, ParamData.data(), sizeof(T));
+ // DXContainer is always little endian
+ if (sys::IsBigEndianHost)
+ Struct.swapBytes();
+ return Struct;
+ }
};
struct RootConstantView : RootParameterView {
@@ -152,7 +152,7 @@ struct RootConstantView : RootParameterView {
}
llvm::Expected<dxbc::RTS0::v1::RootConstants> read() {
- return readParameter<dxbc::RTS0::v1::RootConstants>(ParamData);
+ return readParameter<dxbc::RTS0::v1::RootConstants>();
}
};
@@ -168,8 +168,7 @@ struct RootDescriptorView : RootParameterView {
llvm::Expected<dxbc::RTS0::v2::RootDescriptor> read(uint32_t Version) {
if (Version == 1) {
- auto Descriptor =
- readParameter<dxbc::RTS0::v1::RootDescriptor>(ParamData);
+ auto Descriptor = readParameter<dxbc::RTS0::v1::RootDescriptor>();
if (Error E = Descriptor.takeError())
return E;
return dxbc::RTS0::v2::RootDescriptor(*Descriptor);
@@ -178,7 +177,7 @@ struct RootDescriptorView : RootParameterView {
return make_error<GenericBinaryError>("Invalid Root Signature version: " +
Twine(Version),
object_error::parse_failed);
- return readParameter<dxbc::RTS0::v2::RootDescriptor>(ParamData);
+ return readParameter<dxbc::RTS0::v2::RootDescriptor>();
}
};
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index b7da8316840f0..7b7b8d88c63fc 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -6,8 +6,6 @@
//
//===----------------------------------------------------------------------===//
-#include <cstddef>
-
#include "llvm/Object/DXContainer.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 806722be0813d..bfb3837707f0a 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -164,7 +164,6 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
for (const auto &S : Data.samplers()) {
-
if (!dxbc::isValidSamplerFilter(S.Filter))
return createStringError(std::errc::invalid_argument,
"Invalid value for static sampler filter");
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 76b2aed5bb591..7fec8addc8d52 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1172,7 +1172,7 @@ TEST(RootSignature, ParseStaticSamplers) {
0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
DXContainer C =
- llvm::cantFail(DXContainer::create(getMemoryBuffer<144>(Buffer)));
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
auto MaybeRS = C.getRootSignature();
ASSERT_TRUE(MaybeRS.has_value());
>From b73bf248c1225498e6372d25f8e75ce6a03d5489 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 12:33:59 -0700
Subject: [PATCH 09/25] clean up
---
llvm/include/llvm/Object/DXContainer.h | 4 ----
1 file changed, 4 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 6f10401dd2ba2..5a5a4dbaae2ad 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -123,7 +123,6 @@ template <typename T> struct ViewArray {
};
namespace DirectX {
-
struct RootParameterView {
const dxbc::RTS0::v1::RootParameterHeader &Header;
StringRef ParamData;
@@ -180,7 +179,6 @@ struct RootDescriptorView : RootParameterView {
return readParameter<dxbc::RTS0::v2::RootDescriptor>();
}
};
-
template <typename T> struct DescriptorTable {
uint32_t NumRanges;
uint32_t RangesOffset;
@@ -249,11 +247,9 @@ class RootSignature {
llvm::iterator_range<param_header_iterator> param_headers() const {
return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
}
-
llvm::iterator_range<samplers_iterator> samplers() const {
return llvm::make_range(StaticSamplers.begin(), StaticSamplers.end());
}
-
uint32_t getFlags() const { return Flags; }
llvm::Expected<RootParameterView>
>From bc393fda07547bbd8abc24701c8bfc3495db2e89 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 16:49:12 -0700
Subject: [PATCH 10/25] adding flags to static sampler parser
---
.../clang/Lex/HLSLRootSignatureTokenKinds.def | 8 +++
.../clang/Parse/ParseHLSLRootSignature.h | 3 +
clang/lib/Parse/ParseHLSLRootSignature.cpp | 61 +++++++++++++++++++
.../Lex/LexHLSLRootSignatureTest.cpp | 3 +
.../llvm/Frontend/HLSL/HLSLRootSignature.h | 1 +
llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp | 2 +-
6 files changed, 77 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index a5cfeb34b2b51..1d7f7adbe076f 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -65,6 +65,9 @@
#ifndef STATIC_BORDER_COLOR_ENUM
#define STATIC_BORDER_COLOR_ENUM(NAME, LIT) ENUM(NAME, LIT)
#endif
+#ifndef STATIC_SAMPLER_FLAG_ENUM
+#define STATIC_SAMPLER_FLAG_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
// General Tokens:
TOK(invalid, "invalid identifier")
@@ -228,6 +231,10 @@ STATIC_BORDER_COLOR_ENUM(OpaqueWhite, "STATIC_BORDER_COLOR_OPAQUE_WHITE")
STATIC_BORDER_COLOR_ENUM(OpaqueBlackUint, "STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT")
STATIC_BORDER_COLOR_ENUM(OpaqueWhiteUint, "STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT")
+// Root Descriptor Flag Enums:
+STATIC_SAMPLER_FLAG_ENUM(UintBorderColor, "UINT_BORDER_COLOR")
+STATIC_SAMPLER_FLAG_ENUM(NonNormalizedCoordinates, "NON_NORMALIZED_COORDINATES")
+
#undef STATIC_BORDER_COLOR_ENUM
#undef COMPARISON_FUNC_ENUM
#undef TEXTURE_ADDRESS_MODE_ENUM
@@ -237,6 +244,7 @@ STATIC_BORDER_COLOR_ENUM(OpaqueWhiteUint, "STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT
#undef DESCRIPTOR_RANGE_FLAG_ENUM_OFF
#undef DESCRIPTOR_RANGE_FLAG_ENUM_ON
#undef ROOT_DESCRIPTOR_FLAG_ENUM
+#undef STATIC_SAMPLER_FLAG_ENUM
#undef ROOT_FLAG_ENUM
#undef DESCRIPTOR_RANGE_OFFSET_ENUM
#undef UNBOUNDED_ENUM
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index b06846fd83c09..8f91d7cd7b031 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -130,6 +130,7 @@ class RootSignatureParser {
std::optional<float> MaxLOD;
std::optional<uint32_t> Space;
std::optional<llvm::dxbc::ShaderVisibility> Visibility;
+ std::optional<llvm::dxbc::StaticSamplerFlags> Flags;
};
std::optional<ParsedStaticSamplerParams> parseStaticSamplerParams();
@@ -153,6 +154,8 @@ class RootSignatureParser {
parseRootDescriptorFlags(RootSignatureToken::Kind Context);
std::optional<llvm::dxbc::DescriptorRangeFlags>
parseDescriptorRangeFlags(RootSignatureToken::Kind Context);
+ std::optional<llvm::dxbc::StaticSamplerFlags>
+ parseStaticSamplerFlags(RootSignatureToken::Kind Context);
/// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
/// 32-bit integer
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 3b16efb1f1199..5677365688413 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -485,6 +485,9 @@ std::optional<StaticSampler> RootSignatureParser::parseStaticSampler() {
if (Params->Visibility.has_value())
Sampler.Visibility = Params->Visibility.value();
+ if (Params->Flags.has_value())
+ Sampler.Flags = Params->Flags.value();
+
return Sampler;
}
@@ -926,6 +929,20 @@ RootSignatureParser::parseStaticSamplerParams() {
if (!Visibility.has_value())
return std::nullopt;
Params.Visibility = Visibility;
+ } else if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
+ // `flags` `=` UINT_BORDER_COLOR
+ if (Params.Flags.has_value()) {
+ reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ auto Flags = parseStaticSamplerFlags(TokenKind::kw_flags);
+ if (!Flags.has_value())
+ return std::nullopt;
+ Params.Flags = Flags;
} else {
consumeNextToken(); // let diagnostic be at the start of invalid token
reportDiag(diag::err_hlsl_invalid_token)
@@ -1255,6 +1272,50 @@ RootSignatureParser::parseDescriptorRangeFlags(TokenKind Context) {
return Flags;
}
+std::optional<llvm::dxbc::StaticSamplerFlags>
+RootSignatureParser::parseStaticSamplerFlags(TokenKind Context) {
+ assert(CurToken.TokKind == TokenKind::pu_equal &&
+ "Expects to only be invoked starting at given keyword");
+
+ // Handle the edge-case of '0' to specify no flags set
+ if (tryConsumeExpectedToken(TokenKind::int_literal)) {
+ if (!verifyZeroFlag()) {
+ reportDiag(diag::err_hlsl_rootsig_non_zero_flag);
+ return std::nullopt;
+ }
+ return llvm::dxbc::StaticSamplerFlags::None;
+ }
+
+ TokenKind Expected[] = {
+#define STATIC_SAMPLER_FLAG_ENUM(NAME, LIT) TokenKind::en_##NAME,
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ };
+
+ std::optional<llvm::dxbc::StaticSamplerFlags> Flags;
+
+ do {
+ if (tryConsumeExpectedToken(Expected)) {
+ switch (CurToken.TokKind) {
+#define STATIC_SAMPLER_FLAG_ENUM(NAME, LIT) \
+ case TokenKind::en_##NAME: \
+ Flags = maybeOrFlag<llvm::dxbc::StaticSamplerFlags>( \
+ Flags, llvm::dxbc::StaticSamplerFlags::NAME); \
+ break;
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ default:
+ llvm_unreachable("Switch for consumed enum token was not provided");
+ }
+ } else {
+ consumeNextToken(); // consume token to point at invalid token
+ reportDiag(diag::err_hlsl_invalid_token)
+ << /*value=*/1 << /*value of*/ Context;
+ return std::nullopt;
+ }
+ } while (tryConsumeExpectedToken(TokenKind::pu_or));
+
+ return Flags;
+}
+
std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
// Parse the numeric value and do semantic checks on its specification
clang::NumericLiteralParser Literal(
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index 01f8d4f97b092..82f19686167da 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -226,6 +226,9 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
STATIC_BORDER_COLOR_OPAQUE_WHITE
STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT
STATIC_BORDER_COLOR_OPAQUE_WHITE_UINT
+
+ UINT_BORDER_COLOR
+ NON_NORMALIZED_COORDINATES
)cc";
hlsl::RootSignatureLexer Lexer(Source);
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 87777fddc9157..37224d8a94527 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -131,6 +131,7 @@ struct StaticSampler {
float MaxLOD = std::numeric_limits<float>::max();
uint32_t Space = 0;
dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All;
+ dxbc::StaticSamplerFlags Flags = dxbc::StaticSamplerFlags::None;
};
/// Models RootElement : RootFlags | RootConstants | RootParam
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 92c62b83fadb0..f9129adb4a4f9 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -172,7 +172,7 @@ raw_ostream &operator<<(raw_ostream &OS, const StaticSampler &Sampler) {
<< ", borderColor = " << Sampler.BorderColor
<< ", minLOD = " << Sampler.MinLOD << ", maxLOD = " << Sampler.MaxLOD
<< ", space = " << Sampler.Space << ", visibility = " << Sampler.Visibility
- << ")";
+ << ", flags = " << Sampler.Flags << ")";
return OS;
}
>From e8f7b949d921c8d180d38a923fd307e70f55d711 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 23 Sep 2025 18:34:39 +0000
Subject: [PATCH 11/25] add tests
---
clang/test/CodeGenHLSL/RootSignature.hlsl | 5 +--
.../Parse/ParseHLSLRootSignatureTest.cpp | 34 ++++++++++++++++++-
.../Frontend/HLSL/RootSignatureMetadata.cpp | 1 +
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl b/clang/test/CodeGenHLSL/RootSignature.hlsl
index bc40bdd79ce59..eaff3a9e73305 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -82,8 +82,8 @@ void RootDescriptorsEntry() {}
// 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}
+// checking register, space, visibility and flag
+// CHECK-SAME: i32 42, i32 0, i32 0, i32 1}
#define SampleStaticSampler \
"StaticSampler(s42, " \
@@ -96,6 +96,7 @@ void RootDescriptorsEntry() {}
" borderColor = STATIC_BORDER_COLOR_OPAQUE_WHITE, " \
" minLOD = -128.f, maxLOD = 128.f, " \
" space = 0, visibility = SHADER_VISIBILITY_ALL, " \
+ " flags = UINT_BORDER_COLOR" \
")"
[shader("compute"), RootSignature(SampleStaticSampler)]
[numthreads(1,1,1)]
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 9b9f5dd8a63bb..f7e9d2d32c3f4 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -263,7 +263,8 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
filter = FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT,
maxLOD = 9000, addressU = TEXTURE_ADDRESS_MIRROR,
comparisonFunc = COMPARISON_NOT_EQUAL,
- borderColor = STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT
+ borderColor = STATIC_BORDER_COLOR_OPAQUE_BLACK_UINT,
+ flags = 0
)
)cc";
@@ -336,6 +337,37 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
ASSERT_TRUE(Consumer->isSatisfied());
}
+TEST_F(ParseHLSLRootSignatureTest, ValidStaticSamplerFlagsTest) {
+ const llvm::StringLiteral Source = R"cc(
+ StaticSampler(s0, flags = UINT_BORDER_COLOR | NON_NORMALIZED_COORDINATES)
+ )cc";
+
+ auto Ctx = createMinimalASTContext();
+ StringLiteral *Signature = wrapSource(Ctx, Source);
+
+ TrivialModuleLoader ModLoader;
+ auto PP = createPP(Source, ModLoader);
+
+ hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Signature, *PP);
+
+ // Test no diagnostics produced
+ Consumer->setNoDiag();
+
+ ASSERT_FALSE(Parser.parse());
+
+ auto Elements = Parser.getElements();
+ ASSERT_EQ(Elements.size(), 1u);
+
+ RootElement Elem = Elements[0].getElement();
+ ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
+ auto ValidStaticSamplerFlags =
+ llvm::dxbc::StaticSamplerFlags::NonNormalizedCoordinates |
+ llvm::dxbc::StaticSamplerFlags::UintBorderColor;
+ ASSERT_EQ(std::get<StaticSampler>(Elem).Flags, ValidStaticSamplerFlags);
+
+ ASSERT_TRUE(Consumer->isSatisfied());
+}
+
TEST_F(ParseHLSLRootSignatureTest, ValidParseFloatsTest) {
const llvm::StringLiteral Source = R"cc(
StaticSampler(s0, mipLODBias = 0),
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
index f29f2c7602fc6..e2a1f242bfc8e 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp
@@ -212,6 +212,7 @@ MDNode *MetadataBuilder::BuildStaticSampler(const StaticSampler &Sampler) {
ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)),
ConstantAsMetadata::get(
Builder.getInt32(to_underlying(Sampler.Visibility))),
+ ConstantAsMetadata::get(Builder.getInt32(to_underlying(Sampler.Flags))),
};
return MDNode::get(Ctx, Operands);
}
>From 589668e1c87b45e4a551451c7ae0c745b8dad625 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Wed, 24 Sep 2025 05:51:24 +0000
Subject: [PATCH 12/25] adding more test
---
llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index 1eb03f16527ec..abdd8a6a21112 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -266,7 +266,8 @@ TEST(HLSLRootSignatureTest, DefaultStaticSamplerDump) {
"minLOD = 0.000000e+00, "
"maxLOD = 3.402823e+38, "
"space = 0, "
- "visibility = All"
+ "visibility = All, "
+ "flags = 0x0"
")";
EXPECT_EQ(Out, Expected);
}
@@ -287,6 +288,7 @@ TEST(HLSLRootSignatureTest, DefinedStaticSamplerDump) {
Sampler.MaxLOD = 32.0f;
Sampler.Space = 7;
Sampler.Visibility = llvm::dxbc::ShaderVisibility::Domain;
+ Sampler.Flags = llvm::dxbc::StaticSamplerFlags::NonNormalizedCoordinates;
std::string Out;
llvm::raw_string_ostream OS(Out);
@@ -305,7 +307,8 @@ TEST(HLSLRootSignatureTest, DefinedStaticSamplerDump) {
"minLOD = 1.000000e+00, "
"maxLOD = 3.200000e+01, "
"space = 7, "
- "visibility = Domain"
+ "visibility = Domain, "
+ "flags = 0x2"
")";
EXPECT_EQ(Out, Expected);
}
>From e8b973fb9c0a3fccefc1299448c7c3bd322e52a2 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 25 Sep 2025 10:21:11 -0700
Subject: [PATCH 13/25] adding operator << to print StaticSamplerFlags
---
llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index f9129adb4a4f9..5dbec8063dd77 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -113,6 +113,14 @@ static raw_ostream &operator<<(raw_ostream &OS,
return OS;
}
+static raw_ostream &operator<<(raw_ostream &OS,
+ const llvm::dxbc::StaticSamplerFlags &Flags) {
+ printFlags(OS, Flags, dxbc::getStaticSamplerFlags());
+
+ return OS;
+}
+
+
raw_ostream &operator<<(raw_ostream &OS, const dxbc::RootFlags &Flags) {
OS << "RootFlags(";
printFlags(OS, Flags, dxbc::getRootFlags());
>From 190cfcde07640fc9d6f06171dd4d8f8d5b664765 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 25 Sep 2025 10:21:35 -0700
Subject: [PATCH 14/25] updating comment with inbelic suggestion
---
clang/lib/Parse/ParseHLSLRootSignature.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 5677365688413..7be6eecc520b1 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -930,7 +930,7 @@ RootSignatureParser::parseStaticSamplerParams() {
return std::nullopt;
Params.Visibility = Visibility;
} else if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
- // `flags` `=` UINT_BORDER_COLOR
+ // `flags` `=` STATIC_SAMPLE_FLAGS
if (Params.Flags.has_value()) {
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
return std::nullopt;
>From 79e9564613c700c9f1dbee8e7aa2b052ab6ff72d Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 25 Sep 2025 10:21:52 -0700
Subject: [PATCH 15/25] format
---
llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
index 5dbec8063dd77..2b33e560d74ac 100644
--- a/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
+++ b/llvm/lib/Frontend/HLSL/HLSLRootSignature.cpp
@@ -120,7 +120,6 @@ static raw_ostream &operator<<(raw_ostream &OS,
return OS;
}
-
raw_ostream &operator<<(raw_ostream &OS, const dxbc::RootFlags &Flags) {
OS << "RootFlags(";
printFlags(OS, Flags, dxbc::getRootFlags());
>From 1b1c37dfb518f7d5d2a5180b73100e2d1326c3a0 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 25 Sep 2025 12:32:34 -0700
Subject: [PATCH 16/25] fix test
---
llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
index abdd8a6a21112..451c376219c38 100644
--- a/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
+++ b/llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp
@@ -267,7 +267,7 @@ TEST(HLSLRootSignatureTest, DefaultStaticSamplerDump) {
"maxLOD = 3.402823e+38, "
"space = 0, "
"visibility = All, "
- "flags = 0x0"
+ "flags = None"
")";
EXPECT_EQ(Out, Expected);
}
@@ -308,7 +308,7 @@ TEST(HLSLRootSignatureTest, DefinedStaticSamplerDump) {
"maxLOD = 3.200000e+01, "
"space = 7, "
"visibility = Domain, "
- "flags = 0x2"
+ "flags = NonNormalizedCoordinates"
")";
EXPECT_EQ(Out, Expected);
}
>From daa5714d7506b8482a9c43247ccb9bbbf2820591 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 25 Sep 2025 12:33:20 -0700
Subject: [PATCH 17/25] update Root Signature Version flag
---
clang/include/clang/Basic/LangOptions.h | 2 +-
clang/include/clang/Driver/Options.td | 8 ++++----
clang/lib/AST/TextNodeDumper.cpp | 3 +++
clang/lib/Driver/ToolChains/HLSL.cpp | 2 +-
clang/test/AST/HLSL/RootSignature-Target-AST.hlsl | 10 +++++++++-
clang/test/AST/HLSL/RootSignatures-AST.hlsl | 10 +++++++++-
clang/test/AST/HLSL/rootsignature-define-ast.hlsl | 6 +++---
clang/test/CodeGenHLSL/RootSignature-Target.hlsl | 2 +-
clang/test/CodeGenHLSL/RootSignature.hlsl | 12 ++++++------
clang/test/Driver/dxc_rootsig-define.hlsl | 2 +-
llvm/include/llvm/BinaryFormat/DXContainer.h | 1 +
llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h | 4 ++--
llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp | 2 +-
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 2 +-
14 files changed, 43 insertions(+), 23 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index a8943df5b39aa..280746fd4edeb 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -550,7 +550,7 @@ class LangOptions : public LangOptionsBase {
/// The HLSL root signature version for dxil.
llvm::dxbc::RootSignatureVersion HLSLRootSigVer =
- llvm::dxbc::RootSignatureVersion::V1_1;
+ llvm::dxbc::RootSignatureVersion::V1_2;
/// The HLSL root signature that will be used to overide the root signature
/// used for the shader entry point.
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 16e1c396fedbe..c1b8928cf0528 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -9456,7 +9456,7 @@ def target_profile : DXCJoinedOrSeparate<"T">, MetaVarName<"<profile>">,
"lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x,"
"ms_6_5, ms_6_6, ms_6_7,"
"as_6_5, as_6_6, as_6_7,"
- "rootsig_1_0, rootsig_1_1">;
+ "rootsig_1_0, rootsig_1_1, rootsig_1_2">;
def emit_pristine_llvm : DXCFlag<"emit-pristine-llvm">,
HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all."
"Same as -S + -emit-llvm + -disable-llvm-passes.">;
@@ -9469,10 +9469,10 @@ def fdx_rootsignature_version :
Group<dxc_Group>,
Visibility<[ClangOption, CC1Option]>,
HelpText<"Root Signature Version">,
- Values<"rootsig_1_0,rootsig_1_1">,
+ Values<"rootsig_1_0,rootsig_1_1,rootsig_1_2">,
NormalizedValuesScope<"llvm::dxbc::RootSignatureVersion">,
- NormalizedValues<["V1_0", "V1_1"]>,
- MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_1">;
+ NormalizedValues<["V1_0", "V1_1", "V1_2"]>,
+ MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_2">;
def dxc_rootsig_ver :
Separate<["/", "-"], "force-rootsig-ver">,
Alias<fdx_rootsignature_version>,
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 8f7fe3bea4e8f..cf5e9147ad78b 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -3095,6 +3095,9 @@ void TextNodeDumper::VisitHLSLRootSignatureDecl(
case llvm::dxbc::RootSignatureVersion::V1_1:
OS << "1.1";
break;
+ case llvm::dxbc::RootSignatureVersion::V1_2:
+ OS << "1.2";
+ break;
}
OS << ", ";
llvm::hlsl::rootsig::dumpRootElements(OS, D->getRootElements());
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index f4858e4c960de..2869549e6b3f0 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -64,7 +64,7 @@ bool isLegalShaderModel(Triple &T) {
} break;
case Triple::EnvironmentType::RootSignature:
VersionTuple MinVer(1, 0);
- VersionTuple MaxVer(1, 1);
+ VersionTuple MaxVer(1, 2);
return MinVer <= Version && Version <= MaxVer;
}
return false;
diff --git a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
index 91441e32e047d..b5c71a86b7e48 100644
--- a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
+++ b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
@@ -1,10 +1,16 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
+// RUN: -fdx-rootsignature-version=rootsig_1_1 \
// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
// RUN: -fdx-rootsignature-version=rootsig_1_0 \
// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_0
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
+// RUN: -fdx-rootsignature-version=rootsig_1_2 \
+// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_2
+
+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
// RUN: -D CmdRS='"UAV(u0)"'\
// RUN: -hlsl-entry CmdRS -disable-llvm-passes -o - %s | FileCheck %s --check-prefix=CMD
@@ -12,17 +18,19 @@
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[ENTRY_RS_DECL:__hlsl_rootsig_decl_\d*]]
// CHECK-V1_0-SAME: version: 1.0,
// CHECK-V1_1-SAME: version: 1.1,
+// CHECK-V1_2-SAME: version: 1.2,
// CHECK-SAME: RootElements{
// CHECK-SAME: RootCBV(b0,
// CHECK-SAME: space = 0, visibility = All,
// CHECK-V1_0-SAME: flags = DataVolatile
// CHECK-V1_1-SAME: flags = DataStaticWhileSetAtExecute
+// CHECK-V1_2-SAME: flags = DataStaticWhileSetAtExecute
// CHECK-SAME: )
// CHECK-SAME: }
#define EntryRootSig "CBV(b0)"
// CMD: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CMD_RS_DECL:__hlsl_rootsig_decl_\d*]]
-// CMD-SAME: version: 1.1,
+// CMD-SAME: version: 1.2,
// CMD-SAME: RootElements{
// CMD-SAME: RootUAV(u0, space = 0, visibility = All, flags = DataVolatile)
// CMD-SAME: }
diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl
index 32da1f14853b0..f0c1a0d4ad58b 100644
--- a/clang/test/AST/HLSL/RootSignatures-AST.hlsl
+++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl
@@ -1,11 +1,14 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
-// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1
+// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_2
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
// RUN: -fdx-rootsignature-version=rootsig_1_0 \
// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_0
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
// RUN: -fdx-rootsignature-version=rootsig_1_1 \
// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
+// RUN: -fdx-rootsignature-version=rootsig_1_2 \
+// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_2
// This test ensures that the sample root signature is parsed without error and
// the Attr AST Node is created succesfully. If an invalid root signature was
@@ -31,6 +34,7 @@
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[SAMPLE_RS_DECL:__hlsl_rootsig_decl_\d*]]
// CHECK-V1_0: version: 1.0,
// CHECK-V1_1: version: 1.1,
+// CHECK-V1_2: version: 1.2,
// CHECK-SAME: RootElements{
// CHECK-SAME: RootFlags(AllowInputAssemblerInputLayout | DenyVertexShaderRootAccess),
// CHECK-SAME: RootCBV(b0,
@@ -62,6 +66,7 @@
// CHECK-SAME: s0, numDescriptors = 4, space = 1, offset = DescriptorTableOffsetAppend,
// CHECK-V1_0-SAME: flags = DescriptorsVolatile
// CHECK-V1_1-SAME: flags = None
+// CHECK-V1_2-SAME: flags = None
// CHECK-SAME: ),
// CHECK-SAME: DescriptorTable(
// CHECK-SAME: numClauses = 1, visibility = All
@@ -73,6 +78,9 @@
// CHECK-SAME: s1, filter = Anisotropic, addressU = Wrap, addressV = Wrap, addressW = Wrap,
// CHECK-SAME: mipLODBias = 0.000000e+00, maxAnisotropy = 16, comparisonFunc = LessEqual,
// CHECK-SAME: borderColor = OpaqueWhite, minLOD = 0.000000e+00, maxLOD = 3.402823e+38, space = 0, visibility = All
+// CHECK-V1_0-SAME: flags = None
+// CHECK-V1_1-SAME: flags = None
+// CHECK-V1_2-SAME: flags = None
// CHECK-SAME: )}
// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]]
diff --git a/clang/test/AST/HLSL/rootsignature-define-ast.hlsl b/clang/test/AST/HLSL/rootsignature-define-ast.hlsl
index 9c17cbc9ad2eb..508670175d1f5 100644
--- a/clang/test/AST/HLSL/rootsignature-define-ast.hlsl
+++ b/clang/test/AST/HLSL/rootsignature-define-ast.hlsl
@@ -21,13 +21,13 @@
#define SampleUAV "UAV(u0)"
// CMD: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CMD_DECL:__hlsl_rootsig_decl_\d*]]
-// CMD-SAME: version: 1.1, RootElements{
+// CMD-SAME: version: 1.2, RootElements{
// CMD-SAME: RootSRV(t0,
// CMD-SAME: space = 0, visibility = All, flags = DataStaticWhileSetAtExecute
// CMD-SAME: )}
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CBV_DECL:__hlsl_rootsig_decl_\d*]]
-// CHECK-SAME: version: 1.1, RootElements{
+// CHECK-SAME: version: 1.2, RootElements{
// CHECK-SAME: RootCBV(b0,
// CHECK-SAME: space = 0, visibility = All, flags = DataStaticWhileSetAtExecute
// CHECK-SAME: )}
@@ -41,7 +41,7 @@
void cbv_main() {}
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[UAV_DECL:__hlsl_rootsig_decl_\d*]]
-// CHECK-SAME: version: 1.1, RootElements{
+// CHECK-SAME: version: 1.2, RootElements{
// CHECK-SAME: RootUAV(u0,
// CHECK-SAME: space = 0, visibility = All, flags = DataVolatile
// CHECK-SAME: )}
diff --git a/clang/test/CodeGenHLSL/RootSignature-Target.hlsl b/clang/test/CodeGenHLSL/RootSignature-Target.hlsl
index 50e6bae6786f0..b1b88081ded8c 100644
--- a/clang/test/CodeGenHLSL/RootSignature-Target.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature-Target.hlsl
@@ -2,7 +2,7 @@
// RUN: -hlsl-entry EntryRS -emit-llvm -o - %s | FileCheck %s
// CHECK: !dx.rootsignatures = !{![[#ENTRY:]]}
-// CHECK: ![[#ENTRY]] = !{null, ![[#ENTRY_RS:]], i32 2}
+// CHECK: ![[#ENTRY]] = !{null, ![[#ENTRY_RS:]], i32 3}
// CHECK: ![[#ENTRY_RS]] = !{![[#ROOT_CBV:]]}
// CHECK: ![[#ROOT_CBV]] = !{!"RootCBV", i32 0, i32 0, i32 0, i32 4}
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl b/clang/test/CodeGenHLSL/RootSignature.hlsl
index eaff3a9e73305..da257ed9f5734 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -3,14 +3,14 @@
// CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]], ![[#DT_ENTRY:]],
// CHECK-SAME: ![[#RF_ENTRY:]], ![[#RC_ENTRY:]], ![[#RD_ENTRY:]], ![[#SS_ENTRY:]]}
-// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]], i32 2}
+// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]], i32 3}
// CHECK: ![[#EMPTY]] = !{}
[shader("compute"), RootSignature("")]
[numthreads(1,1,1)]
void EmptyEntry() {}
-// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]], i32 2}
+// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]], i32 3}
// CHECK: ![[#DT_RS]] = !{![[#TABLE:]]}
// CHECK: ![[#TABLE]] = !{!"DescriptorTable", i32 0, ![[#CBV:]], ![[#SRV:]]}
// CHECK: ![[#CBV]] = !{!"CBV", i32 1, i32 0, i32 0, i32 -1, i32 4}
@@ -25,7 +25,7 @@ void EmptyEntry() {}
[numthreads(1,1,1)]
void DescriptorTableEntry() {}
-// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]], i32 2}
+// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]], i32 3}
// CHECK: ![[#RF_RS]] = !{![[#ROOT_FLAGS:]]}
// CHECK: ![[#ROOT_FLAGS]] = !{!"RootFlags", i32 2114}
@@ -38,7 +38,7 @@ void DescriptorTableEntry() {}
[numthreads(1,1,1)]
void RootFlagsEntry() {}
-// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]], i32 2}
+// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]], i32 3}
// CHECK: ![[#RC_RS]] = !{![[#ROOT_CONSTANTS:]]}
// CHECK: ![[#ROOT_CONSTANTS]] = !{!"RootConstants", i32 5, i32 1, i32 2, i32 1}
@@ -52,7 +52,7 @@ void RootFlagsEntry() {}
[numthreads(1,1,1)]
void RootConstantsEntry() {}
-// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]], i32 2}
+// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]], i32 3}
// 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 42, i32 3, i32 2}
@@ -66,7 +66,7 @@ void RootConstantsEntry() {}
[numthreads(1,1,1)]
void RootDescriptorsEntry() {}
-// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]], i32 2}
+// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]], i32 3}
// CHECK: ![[#SS_RS]] = !{![[#STATIC_SAMPLER:]]}
// checking filter = 0x4
diff --git a/clang/test/Driver/dxc_rootsig-define.hlsl b/clang/test/Driver/dxc_rootsig-define.hlsl
index 40c3e127f94d5..f9eb8c2e4c1ea 100644
--- a/clang/test/Driver/dxc_rootsig-define.hlsl
+++ b/clang/test/Driver/dxc_rootsig-define.hlsl
@@ -18,7 +18,7 @@
#define NotEmptyRS "CBV(b0)"
// CHECK: !dx.rootsignatures = !{![[#ENTRY:]]}
-// CHECK: ![[#ENTRY]] = !{ptr @main, ![[#RS:]], i32 2}
+// CHECK: ![[#ENTRY]] = !{ptr @main, ![[#RS:]], i32 3}
// REG: ![[#RS]] = !{![[#CBV:]]}
// REG: ![[#CBV]] = !{!"RootCBV"
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index a08cfff4b4974..8b0f8fab24c66 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -843,6 +843,7 @@ struct StaticSampler : public v1::StaticSampler {
enum class RootSignatureVersion {
V1_0 = 0x1,
V1_1 = 0x2,
+ V1_2 = 0x3,
};
} // namespace dxbc
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 37224d8a94527..c5d89106a8537 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -56,7 +56,7 @@ struct RootDescriptor {
return;
}
- assert(Version == llvm::dxbc::RootSignatureVersion::V1_1 &&
+ assert((Version == llvm::dxbc::RootSignatureVersion::V1_1 || Version == llvm::dxbc::RootSignatureVersion::V1_2) &&
"Specified an invalid root signature version");
switch (Type) {
case dxil::ResourceClass::CBuffer:
@@ -100,7 +100,7 @@ struct DescriptorTableClause {
return;
}
- assert(Version == dxbc::RootSignatureVersion::V1_1 &&
+ assert((Version == dxbc::RootSignatureVersion::V1_1 || Version == dxbc::RootSignatureVersion::V1_2) &&
"Specified an invalid root signature version");
switch (Type) {
case dxil::ResourceClass::CBuffer:
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 8c298f0685286..0ce2aaf51bfd6 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -40,7 +40,7 @@ bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal) {
if (Version == 1)
return Flags == FlagT::DataVolatile;
- assert(Version == 2 && "Provided invalid root signature version");
+ assert((Version == 2 || Version == 3) && "Provided invalid root signature version");
// The data-specific flags are mutually exclusive.
FlagT DataFlags = FlagT::DataVolatile | FlagT::DataStatic |
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index bfb3837707f0a..f268aa85a705e 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -154,7 +154,7 @@ DXContainerYAML::RootSignatureYamlDesc::create(
if (Error E = readDescriptorRanges<dxbc::RTS0::v1::DescriptorRange>(
Header, RootSigDesc, DTV))
return std::move(E);
- } else if (Version == 2) {
+ } else if (Version == 2 || Version == 3) {
if (Error E = readDescriptorRanges<dxbc::RTS0::v2::DescriptorRange>(
Header, RootSigDesc, DTV))
return std::move(E);
>From 11770c5cefcddddb984e88029d06d9729e6ea7ff Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Thu, 25 Sep 2025 13:23:39 -0700
Subject: [PATCH 18/25] fix objcopy test
---
clang/test/Driver/dxc_frs.hlsl | 2 +-
clang/test/Driver/dxc_rootsignature_target.hlsl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/test/Driver/dxc_frs.hlsl b/clang/test/Driver/dxc_frs.hlsl
index 767cab604c829..9fa568901db81 100644
--- a/clang/test/Driver/dxc_frs.hlsl
+++ b/clang/test/Driver/dxc_frs.hlsl
@@ -3,7 +3,7 @@
// Test to demonstrate extracting the root signature to the specified
// output file with /Frs.
-// CHECK: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.obj" "{{.*}}.dxo" "--extract-section=RTS0={{.*}}.rs.dxo"
+// CHECK: "{{.*}}/llvm-objcopy{{(.exe)?}}" "{{.*}}.obj" "{{.*}}.{{(dxo|obj)}}" "--extract-section=RTS0={{.*}}.rs.dxo"
[shader("compute"), RootSignature("")]
[numthreads(1,1,1)]
diff --git a/clang/test/Driver/dxc_rootsignature_target.hlsl b/clang/test/Driver/dxc_rootsignature_target.hlsl
index 08cd1ab00089b..784523707746d 100644
--- a/clang/test/Driver/dxc_rootsignature_target.hlsl
+++ b/clang/test/Driver/dxc_rootsignature_target.hlsl
@@ -3,6 +3,6 @@
// CMDS: "{{.*}}clang{{.*}}" "-cc1"
// CMDS-SAME: "-triple" "dxilv1.1-unknown-shadermodel1.1-rootsignature"
// CMDS-SAME: "-hlsl-entry" "EntryRS"
-// CMDS: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.dxo" "--only-section=RTS0"
+// CMDS: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.{{(dxo|obj)}}" "--only-section=RTS0"
#define EntryRS "UAV(u0)"
>From c3746341bdf20e1c0bc803c9801291a7f0573ba3 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Fri, 26 Sep 2025 11:10:02 -0700
Subject: [PATCH 19/25] foramt
---
llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h | 6 ++++--
llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp | 2 +-
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index c5d89106a8537..edee6a7dec6fc 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -56,7 +56,8 @@ struct RootDescriptor {
return;
}
- assert((Version == llvm::dxbc::RootSignatureVersion::V1_1 || Version == llvm::dxbc::RootSignatureVersion::V1_2) &&
+ assert((Version == llvm::dxbc::RootSignatureVersion::V1_1 ||
+ Version == llvm::dxbc::RootSignatureVersion::V1_2) &&
"Specified an invalid root signature version");
switch (Type) {
case dxil::ResourceClass::CBuffer:
@@ -100,7 +101,8 @@ struct DescriptorTableClause {
return;
}
- assert((Version == dxbc::RootSignatureVersion::V1_1 || Version == dxbc::RootSignatureVersion::V1_2) &&
+ assert((Version == dxbc::RootSignatureVersion::V1_1 ||
+ Version == dxbc::RootSignatureVersion::V1_2) &&
"Specified an invalid root signature version");
switch (Type) {
case dxil::ResourceClass::CBuffer:
diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
index 653305165cad5..8a2b03d9ede8b 100644
--- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
+++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp
@@ -40,7 +40,7 @@ bool verifyRootDescriptorFlag(uint32_t Version, uint32_t FlagsVal) {
if (Version == 1)
return Flags == FlagT::DataVolatile;
- assert((Version == 2 || Version == 3) && "Provided invalid root signature version");
+ assert((Version <= 3) && "Provided invalid root signature version");
// The data-specific flags are mutually exclusive.
FlagT DataFlags = FlagT::DataVolatile | FlagT::DataStatic |
>From 0e80c63edc917834386dbe040027c6daf6eb3605 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Fri, 26 Sep 2025 11:42:22 -0700
Subject: [PATCH 20/25] addressing comments from bogner
---
clang/include/clang/Driver/Options.td | 2 +-
clang/test/AST/HLSL/RootSignature-Target-AST.hlsl | 8 ++++----
clang/test/Driver/dxc_frs.hlsl | 2 +-
clang/test/Driver/dxc_rootsignature_target.hlsl | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e701110d8f688..096df56d0f183 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -9489,7 +9489,7 @@ def fdx_rootsignature_version :
Values<"rootsig_1_0,rootsig_1_1,rootsig_1_2">,
NormalizedValuesScope<"llvm::dxbc::RootSignatureVersion">,
NormalizedValues<["V1_0", "V1_1", "V1_2"]>,
- MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_2">;
+ MarshallingInfoEnum<LangOpts<"HLSLRootSigVer">, "V1_1">;
def dxc_rootsig_ver :
Separate<["/", "-"], "force-rootsig-ver">,
Alias<fdx_rootsignature_version>,
diff --git a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
index b5c71a86b7e48..2dfa67915ffce 100644
--- a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
+++ b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
-// RUN: -fdx-rootsignature-version=rootsig_1_1 \
-// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1
-
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
// RUN: -fdx-rootsignature-version=rootsig_1_0 \
// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_0
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
+// RUN: -fdx-rootsignature-version=rootsig_1_1 \
+// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1
+
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-rootsignature -ast-dump \
// RUN: -fdx-rootsignature-version=rootsig_1_2 \
// RUN: -hlsl-entry EntryRootSig -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_2
diff --git a/clang/test/Driver/dxc_frs.hlsl b/clang/test/Driver/dxc_frs.hlsl
index 9fa568901db81..767cab604c829 100644
--- a/clang/test/Driver/dxc_frs.hlsl
+++ b/clang/test/Driver/dxc_frs.hlsl
@@ -3,7 +3,7 @@
// Test to demonstrate extracting the root signature to the specified
// output file with /Frs.
-// CHECK: "{{.*}}/llvm-objcopy{{(.exe)?}}" "{{.*}}.obj" "{{.*}}.{{(dxo|obj)}}" "--extract-section=RTS0={{.*}}.rs.dxo"
+// CHECK: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.obj" "{{.*}}.dxo" "--extract-section=RTS0={{.*}}.rs.dxo"
[shader("compute"), RootSignature("")]
[numthreads(1,1,1)]
diff --git a/clang/test/Driver/dxc_rootsignature_target.hlsl b/clang/test/Driver/dxc_rootsignature_target.hlsl
index 784523707746d..08cd1ab00089b 100644
--- a/clang/test/Driver/dxc_rootsignature_target.hlsl
+++ b/clang/test/Driver/dxc_rootsignature_target.hlsl
@@ -3,6 +3,6 @@
// CMDS: "{{.*}}clang{{.*}}" "-cc1"
// CMDS-SAME: "-triple" "dxilv1.1-unknown-shadermodel1.1-rootsignature"
// CMDS-SAME: "-hlsl-entry" "EntryRS"
-// CMDS: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.{{(dxo|obj)}}" "--only-section=RTS0"
+// CMDS: "{{.*}}llvm-objcopy{{(.exe)?}}" "{{.*}}.dxo" "--only-section=RTS0"
#define EntryRS "UAV(u0)"
>From a2a00a97419d661240f8d2b8ac3677141da0e53a Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Fri, 26 Sep 2025 13:03:13 -0700
Subject: [PATCH 21/25] add test
---
clang/test/AST/HLSL/RootSignatures-AST.hlsl | 22 ++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/clang/test/AST/HLSL/RootSignatures-AST.hlsl b/clang/test/AST/HLSL/RootSignatures-AST.hlsl
index f0c1a0d4ad58b..0965c876ab2f7 100644
--- a/clang/test/AST/HLSL/RootSignatures-AST.hlsl
+++ b/clang/test/AST/HLSL/RootSignatures-AST.hlsl
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
-// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_2
+// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_1
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -ast-dump \
// RUN: -fdx-rootsignature-version=rootsig_1_0 \
// RUN: -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-V1_0
@@ -139,3 +139,23 @@ void same_rs_string_main() {}
// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[DIFF_RS_DECL]]
[RootSignature(SampleDifferentRS)]
void different_rs_string_main() {}
+
+#define SampleStaticSamplerRS \
+ "StaticSampler(s0, flags = NON_NORMALIZED_COORDINATES)"
+
+// Ensure that static samplers flags are correctly parsed in different versions
+
+// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[DIFF_RS_DECL:__hlsl_rootsig_decl_\d*]]
+// CHECK-V1_0: version: 1.0,
+// CHECK-V1_1: version: 1.1,
+// CHECK-SAME: RootElements{
+// CHECK-SAME: StaticSampler(
+// CHECK-SAME: s0, filter = Anisotropic, addressU = Wrap, addressV = Wrap, addressW = Wrap,
+// CHECK-SAME: mipLODBias = 0.000000e+00, maxAnisotropy = 16, comparisonFunc = LessEqual,
+// CHECK-SAME: borderColor = OpaqueWhite, minLOD = 0.000000e+00, maxLOD = 3.402823e+38, space = 0, visibility = All
+// CHECK-SAME: flags = NonNormalizedCoordinates
+// CHECK-SAME: )}
+
+// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[DIFF_RS_DECL]]
+[RootSignature(SampleStaticSamplerRS)]
+void statoc_sampler_v12_main() {}
>From c8f7e13818d0d63c3b0e6280055e5bbf97104af6 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Fri, 26 Sep 2025 14:55:51 -0700
Subject: [PATCH 22/25] fix test
---
clang/test/AST/HLSL/RootSignature-Target-AST.hlsl | 2 +-
clang/test/AST/HLSL/rootsignature-define-ast.hlsl | 6 +++---
clang/test/CodeGenHLSL/RootSignature-Target.hlsl | 2 +-
clang/test/CodeGenHLSL/RootSignature.hlsl | 12 ++++++------
clang/test/Driver/dxc_rootsig-define.hlsl | 2 +-
5 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
index 2dfa67915ffce..129ab7022f361 100644
--- a/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
+++ b/clang/test/AST/HLSL/RootSignature-Target-AST.hlsl
@@ -30,7 +30,7 @@
#define EntryRootSig "CBV(b0)"
// CMD: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CMD_RS_DECL:__hlsl_rootsig_decl_\d*]]
-// CMD-SAME: version: 1.2,
+// CMD-SAME: version: 1.1,
// CMD-SAME: RootElements{
// CMD-SAME: RootUAV(u0, space = 0, visibility = All, flags = DataVolatile)
// CMD-SAME: }
diff --git a/clang/test/AST/HLSL/rootsignature-define-ast.hlsl b/clang/test/AST/HLSL/rootsignature-define-ast.hlsl
index 508670175d1f5..9c17cbc9ad2eb 100644
--- a/clang/test/AST/HLSL/rootsignature-define-ast.hlsl
+++ b/clang/test/AST/HLSL/rootsignature-define-ast.hlsl
@@ -21,13 +21,13 @@
#define SampleUAV "UAV(u0)"
// CMD: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CMD_DECL:__hlsl_rootsig_decl_\d*]]
-// CMD-SAME: version: 1.2, RootElements{
+// CMD-SAME: version: 1.1, RootElements{
// CMD-SAME: RootSRV(t0,
// CMD-SAME: space = 0, visibility = All, flags = DataStaticWhileSetAtExecute
// CMD-SAME: )}
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[CBV_DECL:__hlsl_rootsig_decl_\d*]]
-// CHECK-SAME: version: 1.2, RootElements{
+// CHECK-SAME: version: 1.1, RootElements{
// CHECK-SAME: RootCBV(b0,
// CHECK-SAME: space = 0, visibility = All, flags = DataStaticWhileSetAtExecute
// CHECK-SAME: )}
@@ -41,7 +41,7 @@
void cbv_main() {}
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[UAV_DECL:__hlsl_rootsig_decl_\d*]]
-// CHECK-SAME: version: 1.2, RootElements{
+// CHECK-SAME: version: 1.1, RootElements{
// CHECK-SAME: RootUAV(u0,
// CHECK-SAME: space = 0, visibility = All, flags = DataVolatile
// CHECK-SAME: )}
diff --git a/clang/test/CodeGenHLSL/RootSignature-Target.hlsl b/clang/test/CodeGenHLSL/RootSignature-Target.hlsl
index b1b88081ded8c..50e6bae6786f0 100644
--- a/clang/test/CodeGenHLSL/RootSignature-Target.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature-Target.hlsl
@@ -2,7 +2,7 @@
// RUN: -hlsl-entry EntryRS -emit-llvm -o - %s | FileCheck %s
// CHECK: !dx.rootsignatures = !{![[#ENTRY:]]}
-// CHECK: ![[#ENTRY]] = !{null, ![[#ENTRY_RS:]], i32 3}
+// CHECK: ![[#ENTRY]] = !{null, ![[#ENTRY_RS:]], i32 2}
// CHECK: ![[#ENTRY_RS]] = !{![[#ROOT_CBV:]]}
// CHECK: ![[#ROOT_CBV]] = !{!"RootCBV", i32 0, i32 0, i32 0, i32 4}
diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl b/clang/test/CodeGenHLSL/RootSignature.hlsl
index da257ed9f5734..eaff3a9e73305 100644
--- a/clang/test/CodeGenHLSL/RootSignature.hlsl
+++ b/clang/test/CodeGenHLSL/RootSignature.hlsl
@@ -3,14 +3,14 @@
// CHECK: !dx.rootsignatures = !{![[#EMPTY_ENTRY:]], ![[#DT_ENTRY:]],
// CHECK-SAME: ![[#RF_ENTRY:]], ![[#RC_ENTRY:]], ![[#RD_ENTRY:]], ![[#SS_ENTRY:]]}
-// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]], i32 3}
+// CHECK: ![[#EMPTY_ENTRY]] = !{ptr @EmptyEntry, ![[#EMPTY:]], i32 2}
// CHECK: ![[#EMPTY]] = !{}
[shader("compute"), RootSignature("")]
[numthreads(1,1,1)]
void EmptyEntry() {}
-// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]], i32 3}
+// CHECK: ![[#DT_ENTRY]] = !{ptr @DescriptorTableEntry, ![[#DT_RS:]], i32 2}
// CHECK: ![[#DT_RS]] = !{![[#TABLE:]]}
// CHECK: ![[#TABLE]] = !{!"DescriptorTable", i32 0, ![[#CBV:]], ![[#SRV:]]}
// CHECK: ![[#CBV]] = !{!"CBV", i32 1, i32 0, i32 0, i32 -1, i32 4}
@@ -25,7 +25,7 @@ void EmptyEntry() {}
[numthreads(1,1,1)]
void DescriptorTableEntry() {}
-// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]], i32 3}
+// CHECK: ![[#RF_ENTRY]] = !{ptr @RootFlagsEntry, ![[#RF_RS:]], i32 2}
// CHECK: ![[#RF_RS]] = !{![[#ROOT_FLAGS:]]}
// CHECK: ![[#ROOT_FLAGS]] = !{!"RootFlags", i32 2114}
@@ -38,7 +38,7 @@ void DescriptorTableEntry() {}
[numthreads(1,1,1)]
void RootFlagsEntry() {}
-// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]], i32 3}
+// CHECK: ![[#RC_ENTRY]] = !{ptr @RootConstantsEntry, ![[#RC_RS:]], i32 2}
// CHECK: ![[#RC_RS]] = !{![[#ROOT_CONSTANTS:]]}
// CHECK: ![[#ROOT_CONSTANTS]] = !{!"RootConstants", i32 5, i32 1, i32 2, i32 1}
@@ -52,7 +52,7 @@ void RootFlagsEntry() {}
[numthreads(1,1,1)]
void RootConstantsEntry() {}
-// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]], i32 3}
+// CHECK: ![[#RD_ENTRY]] = !{ptr @RootDescriptorsEntry, ![[#RD_RS:]], i32 2}
// 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 42, i32 3, i32 2}
@@ -66,7 +66,7 @@ void RootConstantsEntry() {}
[numthreads(1,1,1)]
void RootDescriptorsEntry() {}
-// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]], i32 3}
+// CHECK: ![[#SS_ENTRY]] = !{ptr @StaticSamplerEntry, ![[#SS_RS:]], i32 2}
// CHECK: ![[#SS_RS]] = !{![[#STATIC_SAMPLER:]]}
// checking filter = 0x4
diff --git a/clang/test/Driver/dxc_rootsig-define.hlsl b/clang/test/Driver/dxc_rootsig-define.hlsl
index f9eb8c2e4c1ea..40c3e127f94d5 100644
--- a/clang/test/Driver/dxc_rootsig-define.hlsl
+++ b/clang/test/Driver/dxc_rootsig-define.hlsl
@@ -18,7 +18,7 @@
#define NotEmptyRS "CBV(b0)"
// CHECK: !dx.rootsignatures = !{![[#ENTRY:]]}
-// CHECK: ![[#ENTRY]] = !{ptr @main, ![[#RS:]], i32 3}
+// CHECK: ![[#ENTRY]] = !{ptr @main, ![[#RS:]], i32 2}
// REG: ![[#RS]] = !{![[#CBV:]]}
// REG: ![[#CBV]] = !{!"RootCBV"
>From 900c796a1e7d2e9f874b9665954b01aa50714423 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 1 Oct 2025 11:13:46 -0700
Subject: [PATCH 23/25] adding more tests
---
clang/test/SemaHLSL/RootSignature-err.hlsl | 4 ++++
.../SemaHLSL/RootSignature-flags-err.hlsl | 24 +++++++++++--------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 89c684cd8d11f..debeafe7ee446 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -191,6 +191,10 @@ void basic_validation_5() {}
[RootSignature("StaticSampler(s0, mipLODBias = 15.990001)")]
void basic_validation_6() {}
+// expected-error at +1 {{invalid value of flags}}
+[RootSignature("StaticSampler(s0, flags = FLAG_TYPO)")]
+void basic_validation_7() {}
+
// expected-error at +1 {{sampler and non-sampler resource mixed in descriptor table}}
[RootSignature("DescriptorTable(Sampler(s0), CBV(b0))")]
void mixed_resource_table() {}
diff --git a/clang/test/SemaHLSL/RootSignature-flags-err.hlsl b/clang/test/SemaHLSL/RootSignature-flags-err.hlsl
index 9449d33cee1ad..c79e692202ded 100644
--- a/clang/test/SemaHLSL/RootSignature-flags-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-flags-err.hlsl
@@ -2,7 +2,8 @@
// RUN: -fdx-rootsignature-version=rootsig_1_0 %s -verify=v10
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -fsyntax-only \
// RUN: -fdx-rootsignature-version=rootsig_1_1 %s -verify=v11
-
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -fsyntax-only \
+// RUN: -fdx-rootsignature-version=rootsig_1_2 %s -verify=v12
// Root Descriptor Flags:
// v10-error at +1 {{invalid flags for version 1.0}}
@@ -13,8 +14,9 @@ void bad_root_descriptor_flags_0() {}
[RootSignature("CBV(b0, flags = DATA_STATIC_WHILE_SET_AT_EXECUTE)")]
void bad_root_descriptor_flags_1() {}
-// v10-error at +2 {{invalid flags for version 1.0}}
-// v11-error at +1 {{invalid flags for version 1.1}}
+// v10-error at +3 {{invalid flags for version 1.0}}
+// v11-error at +2 {{invalid flags for version 1.1}}
+// v12-error at +1 {{invalid flags for version 1.2}}
[RootSignature("CBV(b0, flags = DATA_STATIC | DATA_VOLATILE)")]
void bad_root_descriptor_flags_2() {}
@@ -40,18 +42,20 @@ void bad_descriptor_range_flags_3() {}
[RootSignature("DescriptorTable(CBV(b0, flags = DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS))")]
void bad_descriptor_range_flags_4() {}
-// v10-error at +2 {{invalid flags for version 1.0}}
-// v11-error at +1 {{invalid flags for version 1.1}}
+// v10-error at +3 {{invalid flags for version 1.0}}
+// v11-error at +2 {{invalid flags for version 1.1}}
+// v12-error at +1 {{invalid flags for version 1.2}}
[RootSignature("DescriptorTable(CBV(b0, flags = DATA_STATIC | DATA_STATIC_WHILE_SET_AT_EXECUTE))")]
void bad_descriptor_range_flags_5() {}
-// v10-error at +2 {{invalid flags for version 1.0}}
-// v11-error at +1 {{invalid flags for version 1.1}}
+// v10-error at +3 {{invalid flags for version 1.0}}
+// v11-error at +2 {{invalid flags for version 1.1}}
+// v12-error at +1 {{invalid flags for version 1.2}}
[RootSignature("DescriptorTable(CBV(b0, flags = DESCRIPTORS_VOLATILE | DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS))")]
void bad_descriptor_range_flags_6() {}
-// v10-error at +2 {{invalid flags for version 1.0}}
-// v11-error at +1 {{invalid flags for version 1.1}}
+// v10-error at +3 {{invalid flags for version 1.0}}
+// v11-error at +2 {{invalid flags for version 1.1}}
+// v12-error at +1 {{invalid flags for version 1.2}}
[RootSignature("DescriptorTable(CBV(b0, flags = DESCRIPTORS_VOLATILE | DATA_STATIC))")]
void bad_descriptor_range_flags_7() {}
-
>From b85b876009990fabe62be74bcd064ecc50395f2f Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 1 Oct 2025 12:28:23 -0700
Subject: [PATCH 24/25] fix version
---
clang/include/clang/Basic/LangOptions.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 280746fd4edeb..68700fade5cb5 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -549,8 +549,9 @@ class LangOptions : public LangOptionsBase {
bool CheckNew = false;
/// The HLSL root signature version for dxil.
+ /// This is kept at 1.1 to make it backwards compatible with DXC.
llvm::dxbc::RootSignatureVersion HLSLRootSigVer =
- llvm::dxbc::RootSignatureVersion::V1_2;
+ llvm::dxbc::RootSignatureVersion::V1_1;
/// The HLSL root signature that will be used to overide the root signature
/// used for the shader entry point.
>From deb02eb9160877e654dc1739afbac717cec94676 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Wed, 1 Oct 2025 13:08:22 -0700
Subject: [PATCH 25/25] removing initialization
---
clang/include/clang/Basic/LangOptions.h | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 68700fade5cb5..41595ec2a060d 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -549,9 +549,7 @@ class LangOptions : public LangOptionsBase {
bool CheckNew = false;
/// The HLSL root signature version for dxil.
- /// This is kept at 1.1 to make it backwards compatible with DXC.
- llvm::dxbc::RootSignatureVersion HLSLRootSigVer =
- llvm::dxbc::RootSignatureVersion::V1_1;
+ llvm::dxbc::RootSignatureVersion HLSLRootSigVer;
/// The HLSL root signature that will be used to overide the root signature
/// used for the shader entry point.
More information about the llvm-commits
mailing list