https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/160210
>From 787c77638092b06e7648f03660a4429dc602aac6 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 18 Sep 2025 14:16:25 -0700 Subject: [PATCH 01/21] 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 <[email protected]> Date: Thu, 18 Sep 2025 16:54:27 -0700 Subject: [PATCH 02/21] 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 <[email protected]> Date: Fri, 19 Sep 2025 10:46:53 -0700 Subject: [PATCH 03/21] 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 <[email protected]> Date: Fri, 19 Sep 2025 12:48:11 -0700 Subject: [PATCH 04/21] 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 <[email protected]> Date: Mon, 22 Sep 2025 10:28:12 -0700 Subject: [PATCH 05/21] 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 <[email protected]> Date: Mon, 22 Sep 2025 11:29:55 -0700 Subject: [PATCH 06/21] 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 <[email protected]> Date: Mon, 22 Sep 2025 12:17:34 -0700 Subject: [PATCH 07/21] 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 <[email protected]> Date: Mon, 22 Sep 2025 12:32:25 -0700 Subject: [PATCH 08/21] 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 <[email protected]> Date: Mon, 22 Sep 2025 12:33:59 -0700 Subject: [PATCH 09/21] 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 6b191d041990ad667d86b6b07eeed7c802e3fe45 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Mon, 22 Sep 2025 15:31:47 -0700 Subject: [PATCH 10/21] adding metadata static sampler flags --- clang/test/CodeGenHLSL/RootSignature.hlsl | 4 +- .../Frontend/HLSL/RootSignatureMetadata.cpp | 14 +++++- ...gnature-StaticSamplers-Invalid-AddressU.ll | 2 +- ...gnature-StaticSamplers-Invalid-AddressV.ll | 2 +- ...gnature-StaticSamplers-Invalid-AddressW.ll | 2 +- ...ture-StaticSamplers-Invalid-BorderColor.ll | 2 +- ...e-StaticSamplers-Invalid-ComparisonFunc.ll | 2 +- ...Signature-StaticSamplers-Invalid-Filter.ll | 2 +- ...re-StaticSamplers-Invalid-MaxAnisotropy.ll | 2 +- ...Signature-StaticSamplers-Invalid-MaxLod.ll | 2 +- ...Signature-StaticSamplers-Invalid-MinLod.ll | 2 +- ...ature-StaticSamplers-Invalid-MinLopBias.ll | 2 +- ...re-StaticSamplers-Invalid-RegisterSpace.ll | 2 +- ...e-StaticSamplers-Invalid-ShaderRegister.ll | 2 +- ...StaticSamplers-Invalid-ShaderVisibility.ll | 2 +- .../RootSignature-StaticSamplers.ll | 2 +- .../RootSignature-StaticSamplers_V3.ll | 43 +++++++++++++++++++ .../rootsignature-validation-fail-sampler.ll | 2 +- ...re-validation-fail-static-sampler-range.ll | 4 +- 19 files changed, 75 insertions(+), 20 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll diff --git a/clang/test/CodeGenHLSL/RootSignature.hlsl b/clang/test/CodeGenHLSL/RootSignature.hlsl index bc40bdd79ce59..bbab6a73a3658 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 flags +// CHECK-SAME: i32 42, i32 0, i32 0, i32 0} #define SampleStaticSampler \ "StaticSampler(s42, " \ diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index f29f2c7602fc6..5ddf129265648 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(0)), }; return MDNode::get(Ctx, Operands); } @@ -411,7 +412,7 @@ Error MetadataParser::parseDescriptorTable(mcdxbc::RootSignatureDesc &RSD, Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD, MDNode *StaticSamplerNode) { - if (StaticSamplerNode->getNumOperands() != 14) + if (StaticSamplerNode->getNumOperands() != 15) return make_error<InvalidRSMetadataFormat>("Static Sampler"); mcdxbc::StaticSampler Sampler; @@ -495,6 +496,17 @@ Error MetadataParser::parseStaticSampler(mcdxbc::RootSignatureDesc &RSD, return Error(std::move(E)); Sampler.ShaderVisibility = *Visibility; + if (RSD.Version < 3) { + RSD.StaticSamplers.push_back(Sampler); + return Error::success(); + } + assert(RSD.Version >= 3); + + if (std::optional<uint32_t> Val = extractMdIntValue(StaticSamplerNode, 14)) + Sampler.Flags = *Val; + else + return make_error<InvalidRSMetadataValue>("Static Sampler Flags"); + RSD.StaticSamplers.push_back(Sampler); return Error::success(); } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll index 288dea00b6e55..b043ea1418df6 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressU.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 666, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll index e9abcf9669999..8219ffdd679d2 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressV.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 666, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 666, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressW.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressW.ll index 238f488ee78d6..31d8dd10f3e22 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressW.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-AddressW.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 666, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 666, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-BorderColor.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-BorderColor.ll index 8dc69eb1f9d7c..2bb4af5d9c0f2 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-BorderColor.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-BorderColor.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 666, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 666, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ComparisonFunc.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ComparisonFunc.ll index b2c8faf8d4a0a..62fda735b6860 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ComparisonFunc.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ComparisonFunc.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 666, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 666, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Filter.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Filter.ll index 758d2629ed78e..7e8de14160ce9 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Filter.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Filter.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 45, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 45, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxAnisotropy.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxAnisotropy.ll index 47d4b52d72e8e..312e7697d4f2a 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxAnisotropy.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxAnisotropy.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 666, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 666, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxLod.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxLod.ll index 855e0c0cb6e51..80fd208a1bceb 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxLod.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MaxLod.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 0x7FF8000000000000, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 0x7FF8000000000000, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLod.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLod.ll index 812749b9ed824..5daaf69a40062 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLod.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLod.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float 0x7FF8000000000000, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float 0x7FF8000000000000, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLopBias.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLopBias.ll index 6898aec6f2e49..423987b0e2624 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLopBias.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-MinLopBias.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 6.660000e+02, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 6.660000e+02, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-RegisterSpace.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-RegisterSpace.ll index dc6ee4290b532..af630dcdd0300 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-RegisterSpace.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-RegisterSpace.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 4294967280, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 4294967280, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderRegister.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderRegister.ll index 6cee1dd95fd81..bd752f0519da4 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderRegister.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderRegister.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 4294967295, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 4294967295, i32 0, i32 0, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderVisibility.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderVisibility.ll index fa5bf12e2b8cd..ca0c02d64983b 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderVisibility.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-ShaderVisibility.ll @@ -16,4 +16,4 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 666 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 666, i32 0 } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers.ll index 1dd470d7fb822..77c5c7af66247 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers.ll @@ -15,7 +15,7 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 2 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } ; DXC: - Name: RTS0 ; DXC-NEXT: Size: 76 diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll new file mode 100644 index 0000000000000..c7dd8065199a1 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll @@ -0,0 +1,43 @@ +; RUN: opt %s -dxil-embed -dxil-globals -S -o - | FileCheck %s +; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: @dx.rts0 = private constant [80 x i8] c"{{.*}}", section "RTS0", align 4 + +define void @main() #0 { +entry: + ret void +} +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!2} ; list of function/root signature pairs +!2 = !{ ptr @main, !3, i32 3 } ; function, root signature +!3 = !{ !5 } ; list of root signature elements +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 1 } + +; DXC: - Name: RTS0 +; DXC-NEXT: Size: 80 +; DXC-NEXT: RootSignature: +; DXC-NEXT: Version: 3 +; DXC-NEXT: NumRootParameters: 0 +; DXC-NEXT: RootParametersOffset: 24 +; DXC-NEXT: NumStaticSamplers: 1 +; DXC-NEXT: StaticSamplersOffset: 24 +; DXC-NEXT: Parameters: [] +; DXC-NEXT: Samplers: +; DXC-NEXT: - Filter: MinPointMagLinearMipPoint +; DXC-NEXT: AddressU: Mirror +; DXC-NEXT: AddressV: Clamp +; DXC-NEXT: AddressW: MirrorOnce +; DXC-NEXT: MipLODBias: 1.425 +; DXC-NEXT: MaxAnisotropy: 9 +; DXC-NEXT: ComparisonFunc: Equal +; DXC-NEXT: BorderColor: OpaqueWhite +; DXC-NEXT: MinLOD: -128 +; DXC-NEXT: MaxLOD: 128 +; DXC-NEXT: ShaderRegister: 42 +; DXC-NEXT: RegisterSpace: 0 +; DXC-NEXT: ShaderVisibility: All +; DXC-NEXT: SAMPLER_FLAG_UINT_BORDER_COLOR: true diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll index c244095520468..b68606d656d75 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-sampler.ll @@ -10,6 +10,6 @@ entry: !0 = !{ptr @CSMain, !1, i32 2} !1 = !{!2, !3} -!2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 } +!2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0, i32 0 } !3 = !{!"DescriptorTable", i32 0, !4} !4 = !{!"Sampler", i32 1, i32 42, i32 0, i32 -1, i32 0} diff --git a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll index 9ac02ebbc0965..7c836e2f85d68 100644 --- a/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll +++ b/llvm/test/CodeGen/DirectX/rootsignature-validation-fail-static-sampler-range.ll @@ -10,5 +10,5 @@ entry: !0 = !{ptr @CSMain, !1, i32 2} !1 = !{!2, !3} -!2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0 } -!3 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0 } +!2 = !{ !"StaticSampler", i32 5, i32 4, i32 5, i32 3, float 0x3FF7CCCCC0000000, i32 10, i32 2, i32 1, float -1.270000e+02, float 1.220000e+02, i32 42, i32 0, i32 0, i32 0 } +!3 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 0 } >From cc05d4dab69ef809c1bdcc011caaa6c213196375 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 10:57:56 -0700 Subject: [PATCH 11/21] adding default flag to frontend root signature --- llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h | 2 ++ llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h index 87777fddc9157..43dca87f3c4fb 100644 --- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h +++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h @@ -131,6 +131,8 @@ struct StaticSampler { float MaxLOD = std::numeric_limits<float>::max(); uint32_t Space = 0; dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All; + // Flags added in Root Signature 1.2 + dxbc::StaticSamplerFlags Flags = dxbc::StaticSamplerFlags::None; }; /// Models RootElement : RootFlags | RootConstants | RootParam diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 5ddf129265648..cd28998e7418d 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -212,7 +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(0)), + ConstantAsMetadata::get(Sampler.Flags), }; return MDNode::get(Ctx, Operands); } >From f02d18e64c4644cdb98ef4c1cf3b779d5e9e9acf Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 11:26:32 -0700 Subject: [PATCH 12/21] address suggestion from inbelic --- llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index cd28998e7418d..08ac9b546120c 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -212,7 +212,8 @@ MDNode *MetadataBuilder::BuildStaticSampler(const StaticSampler &Sampler) { ConstantAsMetadata::get(Builder.getInt32(Sampler.Space)), ConstantAsMetadata::get( Builder.getInt32(to_underlying(Sampler.Visibility))), - ConstantAsMetadata::get(Sampler.Flags), + ConstantAsMetadata::get( + Builder.getInt32(to_underlying(Sampler.Visibility))), }; return MDNode::get(Ctx, Operands); } >From ddf99455e409897f245c38dc98234f43ff51325b Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 11:45:28 -0700 Subject: [PATCH 13/21] changing size and remove untested parameters --- llvm/include/llvm/BinaryFormat/DXContainer.h | 1 + .../ObjectYAML/DXContainerYAMLTest.cpp | 26 ++++++------------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h index a08cfff4b4974..08a7ddb6929f5 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainer.h +++ b/llvm/include/llvm/BinaryFormat/DXContainer.h @@ -822,6 +822,7 @@ struct DescriptorRange { } }; } // namespace v2 + namespace v3 { struct StaticSampler : public v1::StaticSampler { uint32_t Flags; diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp index db9861f0149a4..1b21fe01dfca9 100644 --- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp +++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp @@ -528,7 +528,7 @@ TEST(RootSignature, ParseStaticSamplers) { } TEST(RootSignature, ParseStaticSamplersV13) { - SmallString<160> Storage; + SmallString<128> Storage; // First read a fully explicit yaml with all sizes and offsets provided ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer @@ -551,19 +551,9 @@ TEST(RootSignature, ParseStaticSamplersV13) { StaticSamplersOffset: 24 Parameters: [] Samplers: - - Filter: MinLinearMagMipPoint - AddressU: Wrap - AddressV: Mirror - AddressW: MirrorOnce - MipLODBias: 1.23 - MaxAnisotropy: 20 - ComparisonFunc: LessEqual - BorderColor: TransparentBlack - MinLOD: 4.56 - MaxLOD: 8.90 - ShaderRegister: 31 + - ShaderRegister: 31 RegisterSpace: 32 - ShaderVisibility: Mesh + ShaderVisibility: All SAMPLER_FLAG_UINT_BORDER_COLOR: true AllowInputAssemblerInputLayout: true DenyGeometryShaderRootAccess: true @@ -577,11 +567,11 @@ TEST(RootSignature, ParseStaticSamplersV13) { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41, - 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x7f, + 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00}; EXPECT_EQ(Storage.size(), 148U); >From 284901cb5c5664a8213254773dc3401e59a2c119 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 11:47:22 -0700 Subject: [PATCH 14/21] adding suggested comment --- llvm/include/llvm/MC/DXContainerRootSignature.h | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h index 2a76e81fefc5f..514e74b92d101 100644 --- a/llvm/include/llvm/MC/DXContainerRootSignature.h +++ b/llvm/include/llvm/MC/DXContainerRootSignature.h @@ -74,6 +74,7 @@ struct StaticSampler { uint32_t ShaderRegister; uint32_t RegisterSpace; dxbc::ShaderVisibility ShaderVisibility; + // Version 3 onwards: uint32_t Flags; }; >From 73e6bb53cf5d71b3cf0f4914207782d7636af0f5 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 12:24:05 -0700 Subject: [PATCH 15/21] addressing inbelic comments --- .../Frontend/HLSL/RootSignatureValidations.h | 2 ++ .../llvm/MC/DXContainerRootSignature.h | 2 +- .../Frontend/HLSL/RootSignatureMetadata.cpp | 7 +++++++ .../HLSL/RootSignatureValidations.cpp | 15 +++++++++++++++ llvm/lib/MC/DXContainerRootSignature.cpp | 10 +++++----- ...otSignature-StaticSamplers-Invalid-Flag.ll | 19 +++++++++++++++++++ 6 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h index ea96094b18300..46a6e6eac379e 100644 --- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h +++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h @@ -33,6 +33,8 @@ LLVM_ABI bool verifyRangeType(uint32_t Type); LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, dxbc::DescriptorRangeFlags FlagsVal); +LLVM_ABI bool verifyStaticSamplerFlags(uint32_t Version, + dxbc::StaticSamplerFlags Flags); LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors); LLVM_ABI bool verifyMipLODBias(float MipLODBias); LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy); diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h index 514e74b92d101..2b08b2439d2c0 100644 --- a/llvm/include/llvm/MC/DXContainerRootSignature.h +++ b/llvm/include/llvm/MC/DXContainerRootSignature.h @@ -75,7 +75,7 @@ struct StaticSampler { uint32_t RegisterSpace; dxbc::ShaderVisibility ShaderVisibility; // Version 3 onwards: - uint32_t Flags; + uint32_t Flags = 0; }; struct RootParametersContainer { diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index f29f2c7602fc6..417169576f5d9 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -651,6 +651,13 @@ Error MetadataParser::validateRootSignature( joinErrors(std::move(DeferredErrs), make_error<RootSignatureValidationError<uint32_t>>( "RegisterSpace", Sampler.RegisterSpace)); + + if (!hlsl::rootsig::verifyStaticSamplerFlags( + RSD.Version, dxbc::StaticSamplerFlags(Sampler.Flags))) + DeferredErrs = + joinErrors(std::move(DeferredErrs), + make_error<RootSignatureValidationError<uint32_t>>( + "Static Sampler Flag", Sampler.Flags)); } return DeferredErrs; diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp index 8c298f0685286..ef1021417414b 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp @@ -113,6 +113,21 @@ bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, return (Flags & ~Mask) == FlagT::None; } +bool verifyStaticSamplerFlags(uint32_t Version, + dxbc::StaticSamplerFlags Flags) { + + if (Version <= 2) + return Flags == dxbc::StaticSamplerFlags::None; + + assert(Version == 3 && "Provided invalid root signature version"); + + dxbc::StaticSamplerFlags Mask = + dxbc::StaticSamplerFlags::NonNormalizedCoordinates | + dxbc::StaticSamplerFlags::UintBorderColor | + dxbc::StaticSamplerFlags::None; + return (Flags | Mask) == Mask; +} + bool verifyNumDescriptors(uint32_t NumDescriptors) { return NumDescriptors > 0; } diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp index 13784e7c86684..2338370d84389 100644 --- a/llvm/lib/MC/DXContainerRootSignature.cpp +++ b/llvm/lib/MC/DXContainerRootSignature.cpp @@ -32,12 +32,12 @@ static uint32_t rewriteOffsetToCurrentByte(raw_svector_ostream &Stream, size_t RootSignatureDesc::getSize() const { uint32_t StaticSamplersOffset = computeStaticSamplersOffset(); - size_t StaticSamplersSize = - (Version > 2 ? sizeof(dxbc::RTS0::v3::StaticSampler) - : sizeof(dxbc::RTS0::v1::StaticSampler)) * - StaticSamplers.size(); + size_t StaticSamplersSize = sizeof(dxbc::RTS0::v1::StaticSampler); + if (Version > 2) + StaticSamplersSize = sizeof(dxbc::RTS0::v3::StaticSampler); - return size_t(StaticSamplersOffset) + StaticSamplersSize; + return size_t(StaticSamplersOffset) + + (StaticSamplersSize * StaticSamplers.size()); } uint32_t RootSignatureDesc::computeRootParametersOffset() const { diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll new file mode 100644 index 0000000000000..fa5bf12e2b8cd --- /dev/null +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll @@ -0,0 +1,19 @@ +; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s + + +target triple = "dxil-unknown-shadermodel6.0-compute" + +; CHECK: error: Invalid value for ShaderVisibility: 666 +; CHECK-NOT: Root Signature Definitions + +define void @main() #0 { +entry: + ret void +} +attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } + + +!dx.rootsignatures = !{!2} ; list of function/root signature pairs +!2 = !{ ptr @main, !3, i32 2 } ; function, root signature +!3 = !{ !5 } ; list of root signature elements +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 666 } >From 159cd5793e9bfa1cacaecc4601b8e4607e49cdc8 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 12:37:02 -0700 Subject: [PATCH 16/21] addressing inbelic comments --- llvm/lib/ObjectYAML/DXContainerYAML.cpp | 2 +- llvm/unittests/Object/DXContainerTest.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp index bfb3837707f0a..efa8b40c2d554 100644 --- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp +++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp @@ -212,7 +212,7 @@ DXContainerYAML::RootSignatureYamlDesc::create( if (Version > 2) { #define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \ NewS.Enum = \ - (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)) > 0; + (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)); #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 7fec8addc8d52..9e805639cb409 100644 --- a/llvm/unittests/Object/DXContainerTest.cpp +++ b/llvm/unittests/Object/DXContainerTest.cpp @@ -1201,6 +1201,9 @@ TEST(RootSignature, ParseStaticSamplers) { ASSERT_EQ(Sampler.ShaderVisibility, 7u); } { + // this is testing static sampler parsing for root signature version 1.2, + // it changes: the version number, the size of root signature being emitted + // and the values for flag fields. 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, >From ae969d424caa095e33aa1f363b981fa7228f5746 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 13:03:39 -0700 Subject: [PATCH 17/21] updating test to account all flags and remove unecessary metadata generatio --- .../llvm/Frontend/HLSL/HLSLRootSignature.h | 2 -- .../Frontend/HLSL/RootSignatureMetadata.cpp | 3 +- .../RootSignature-StaticSamplers_V3.ll | 35 +++++++++---------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h index 43dca87f3c4fb..87777fddc9157 100644 --- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h +++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h @@ -131,8 +131,6 @@ struct StaticSampler { float MaxLOD = std::numeric_limits<float>::max(); uint32_t Space = 0; dxbc::ShaderVisibility Visibility = dxbc::ShaderVisibility::All; - // Flags added in Root Signature 1.2 - dxbc::StaticSamplerFlags Flags = dxbc::StaticSamplerFlags::None; }; /// Models RootElement : RootFlags | RootConstants | RootParam diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 08ac9b546120c..5384bc6a925c2 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -212,8 +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.Visibility))), + ConstantAsMetadata::get(Builder.getInt32(0)) }; return MDNode::get(Ctx, Operands); } diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll index c7dd8065199a1..7e56f0408e3f3 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers_V3.ll @@ -3,7 +3,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: @dx.rts0 = private constant [80 x i8] c"{{.*}}", section "RTS0", align 4 +; CHECK: @dx.rts0 = private constant [248 x i8] c"{{.*}}", section "RTS0", align 4 define void @main() #0 { entry: @@ -14,30 +14,29 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs !2 = !{ ptr @main, !3, i32 3 } ; function, root signature -!3 = !{ !5 } ; list of root signature elements +!3 = !{ !5, !6, !7, !8 } ; list of root signature elements !5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 1 } +!6 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 43, i32 0, i32 0, i32 2 } +!7 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 44, i32 0, i32 0, i32 0 } +!8 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 45, i32 0, i32 0, i32 3 } ; DXC: - Name: RTS0 -; DXC-NEXT: Size: 80 +; DXC-NEXT: Size: 248 ; DXC-NEXT: RootSignature: ; DXC-NEXT: Version: 3 ; DXC-NEXT: NumRootParameters: 0 ; DXC-NEXT: RootParametersOffset: 24 -; DXC-NEXT: NumStaticSamplers: 1 +; DXC-NEXT: NumStaticSamplers: 4 ; DXC-NEXT: StaticSamplersOffset: 24 ; DXC-NEXT: Parameters: [] ; DXC-NEXT: Samplers: -; DXC-NEXT: - Filter: MinPointMagLinearMipPoint -; DXC-NEXT: AddressU: Mirror -; DXC-NEXT: AddressV: Clamp -; DXC-NEXT: AddressW: MirrorOnce -; DXC-NEXT: MipLODBias: 1.425 -; DXC-NEXT: MaxAnisotropy: 9 -; DXC-NEXT: ComparisonFunc: Equal -; DXC-NEXT: BorderColor: OpaqueWhite -; DXC-NEXT: MinLOD: -128 -; DXC-NEXT: MaxLOD: 128 -; DXC-NEXT: ShaderRegister: 42 -; DXC-NEXT: RegisterSpace: 0 -; DXC-NEXT: ShaderVisibility: All -; DXC-NEXT: SAMPLER_FLAG_UINT_BORDER_COLOR: true +; DXC-LABEL: ShaderRegister: 42 +; DXC: SAMPLER_FLAG_UINT_BORDER_COLOR: true +; DXC-LABEL: ShaderRegister: 43 +; DXC: SAMPLER_FLAG_NON_NORMALIZED_COORDINATES: true +; DXC-LABEL: ShaderRegister: 44 +; DXC-NOT: SAMPLER_FLAG_NON_NORMALIZED_COORDINATES: +; DXC-NOT: SAMPLER_FLAG_UINT_BORDER_COLOR: +; DXC-LABEL: ShaderRegister: 45 +; DXC: SAMPLER_FLAG_UINT_BORDER_COLOR: true +; DXC-NEXT: SAMPLER_FLAG_NON_NORMALIZED_COORDINATES: true >From b7f07aa9781a6e62627aa98a0aa90f5a76d8f75f Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 13:47:31 -0700 Subject: [PATCH 18/21] format --- llvm/lib/ObjectYAML/DXContainerYAML.cpp | 3 +-- llvm/unittests/Object/DXContainerTest.cpp | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp index efa8b40c2d554..3c09ae4e5f2bc 100644 --- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp +++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp @@ -211,8 +211,7 @@ DXContainerYAML::RootSignatureYamlDesc::create( if (Version > 2) { #define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \ - NewS.Enum = \ - (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)); + NewS.Enum = (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)); #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 9e805639cb409..d6f7b26b99cd7 100644 --- a/llvm/unittests/Object/DXContainerTest.cpp +++ b/llvm/unittests/Object/DXContainerTest.cpp @@ -1201,8 +1201,8 @@ TEST(RootSignature, ParseStaticSamplers) { ASSERT_EQ(Sampler.ShaderVisibility, 7u); } { - // this is testing static sampler parsing for root signature version 1.2, - // it changes: the version number, the size of root signature being emitted + // this is testing static sampler parsing for root signature version 1.2, + // it changes: the version number, the size of root signature being emitted // and the values for flag fields. uint8_t Buffer[] = { 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, >From c25fee8431b123e879d8ff3d7d93e37498c108e0 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Wed, 24 Sep 2025 13:48:32 -0700 Subject: [PATCH 19/21] format --- llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 5384bc6a925c2..d4520bc556102 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -212,8 +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(0)) - }; + ConstantAsMetadata::get(Builder.getInt32(0))}; return MDNode::get(Ctx, Operands); } >From 8d017fa99050a0bcbd08ced7779b283b523f7523 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 25 Sep 2025 17:34:11 -0700 Subject: [PATCH 20/21] adding test to check flags --- .../include/llvm/Frontend/HLSL/RootSignatureValidations.h | 3 +-- llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp | 3 +-- llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp | 8 ++++++-- .../RootSignature-StaticSamplers-Invalid-Flag.ll | 6 +++--- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h index 46a6e6eac379e..64a8061bba078 100644 --- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h +++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h @@ -33,8 +33,7 @@ LLVM_ABI bool verifyRangeType(uint32_t Type); LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, dxbc::DescriptorRangeFlags FlagsVal); -LLVM_ABI bool verifyStaticSamplerFlags(uint32_t Version, - dxbc::StaticSamplerFlags Flags); +LLVM_ABI bool verifyStaticSamplerFlags(uint32_t Version, uint32_t FlagsNumber); LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors); LLVM_ABI bool verifyMipLODBias(float MipLODBias); LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy); diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 662ded53f569e..9b5a47684e763 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -663,8 +663,7 @@ Error MetadataParser::validateRootSignature( make_error<RootSignatureValidationError<uint32_t>>( "RegisterSpace", Sampler.RegisterSpace)); - if (!hlsl::rootsig::verifyStaticSamplerFlags( - RSD.Version, dxbc::StaticSamplerFlags(Sampler.Flags))) + if (!hlsl::rootsig::verifyStaticSamplerFlags(RSD.Version, Sampler.Flags)) DeferredErrs = joinErrors(std::move(DeferredErrs), make_error<RootSignatureValidationError<uint32_t>>( diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp index ef1021417414b..07a508d8d7642 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp @@ -113,9 +113,13 @@ bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, return (Flags & ~Mask) == FlagT::None; } -bool verifyStaticSamplerFlags(uint32_t Version, - dxbc::StaticSamplerFlags Flags) { +bool verifyStaticSamplerFlags(uint32_t Version, uint32_t FlagsNumber) { + uint32_t LargestValue = llvm::to_underlying( + dxbc::StaticSamplerFlags::LLVM_BITMASK_LARGEST_ENUMERATOR); + if (FlagsNumber >= NextPowerOf2(LargestValue)) + return false; + dxbc::StaticSamplerFlags Flags = dxbc::StaticSamplerFlags(FlagsNumber); if (Version <= 2) return Flags == dxbc::StaticSamplerFlags::None; diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll index fa5bf12e2b8cd..8f7ef8857ad15 100644 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll +++ b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll @@ -3,7 +3,7 @@ target triple = "dxil-unknown-shadermodel6.0-compute" -; CHECK: error: Invalid value for ShaderVisibility: 666 +; CHECK: error: Invalid value for Static Sampler Flag: 4 ; CHECK-NOT: Root Signature Definitions define void @main() #0 { @@ -14,6 +14,6 @@ attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } !dx.rootsignatures = !{!2} ; list of function/root signature pairs -!2 = !{ ptr @main, !3, i32 2 } ; function, root signature +!2 = !{ ptr @main, !3, i32 3 } ; function, root signature !3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 666 } +!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 0, i32 4 } >From efcd87383068e58130656536bb9f67f1320d4972 Mon Sep 17 00:00:00 2001 From: Joao Saffran <[email protected]> Date: Thu, 25 Sep 2025 17:57:31 -0700 Subject: [PATCH 21/21] remove test --- .../Frontend/HLSL/RootSignatureValidations.h | 3 +-- .../Frontend/HLSL/RootSignatureMetadata.cpp | 3 +-- .../HLSL/RootSignatureValidations.cpp | 8 ++++++-- ...otSignature-StaticSamplers-Invalid-Flag.ll | 19 ------------------- 4 files changed, 8 insertions(+), 25 deletions(-) delete mode 100644 llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll diff --git a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h index 46a6e6eac379e..64a8061bba078 100644 --- a/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h +++ b/llvm/include/llvm/Frontend/HLSL/RootSignatureValidations.h @@ -33,8 +33,7 @@ LLVM_ABI bool verifyRangeType(uint32_t Type); LLVM_ABI bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, dxbc::DescriptorRangeFlags FlagsVal); -LLVM_ABI bool verifyStaticSamplerFlags(uint32_t Version, - dxbc::StaticSamplerFlags Flags); +LLVM_ABI bool verifyStaticSamplerFlags(uint32_t Version, uint32_t FlagsNumber); LLVM_ABI bool verifyNumDescriptors(uint32_t NumDescriptors); LLVM_ABI bool verifyMipLODBias(float MipLODBias); LLVM_ABI bool verifyMaxAnisotropy(uint32_t MaxAnisotropy); diff --git a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp index 417169576f5d9..106e49606b8fd 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureMetadata.cpp @@ -652,8 +652,7 @@ Error MetadataParser::validateRootSignature( make_error<RootSignatureValidationError<uint32_t>>( "RegisterSpace", Sampler.RegisterSpace)); - if (!hlsl::rootsig::verifyStaticSamplerFlags( - RSD.Version, dxbc::StaticSamplerFlags(Sampler.Flags))) + if (!hlsl::rootsig::verifyStaticSamplerFlags(RSD.Version, Sampler.Flags)) DeferredErrs = joinErrors(std::move(DeferredErrs), make_error<RootSignatureValidationError<uint32_t>>( diff --git a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp index ef1021417414b..07a508d8d7642 100644 --- a/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp +++ b/llvm/lib/Frontend/HLSL/RootSignatureValidations.cpp @@ -113,9 +113,13 @@ bool verifyDescriptorRangeFlag(uint32_t Version, dxil::ResourceClass Type, return (Flags & ~Mask) == FlagT::None; } -bool verifyStaticSamplerFlags(uint32_t Version, - dxbc::StaticSamplerFlags Flags) { +bool verifyStaticSamplerFlags(uint32_t Version, uint32_t FlagsNumber) { + uint32_t LargestValue = llvm::to_underlying( + dxbc::StaticSamplerFlags::LLVM_BITMASK_LARGEST_ENUMERATOR); + if (FlagsNumber >= NextPowerOf2(LargestValue)) + return false; + dxbc::StaticSamplerFlags Flags = dxbc::StaticSamplerFlags(FlagsNumber); if (Version <= 2) return Flags == dxbc::StaticSamplerFlags::None; diff --git a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll b/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll deleted file mode 100644 index fa5bf12e2b8cd..0000000000000 --- a/llvm/test/CodeGen/DirectX/ContainerData/RootSignature-StaticSamplers-Invalid-Flag.ll +++ /dev/null @@ -1,19 +0,0 @@ -; RUN: not opt -passes='print<dxil-root-signature>' %s -S -o - 2>&1 | FileCheck %s - - -target triple = "dxil-unknown-shadermodel6.0-compute" - -; CHECK: error: Invalid value for ShaderVisibility: 666 -; CHECK-NOT: Root Signature Definitions - -define void @main() #0 { -entry: - ret void -} -attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" } - - -!dx.rootsignatures = !{!2} ; list of function/root signature pairs -!2 = !{ ptr @main, !3, i32 2 } ; function, root signature -!3 = !{ !5 } ; list of root signature elements -!5 = !{ !"StaticSampler", i32 4, i32 2, i32 3, i32 5, float 0x3FF6CCCCC0000000, i32 9, i32 3, i32 2, float -1.280000e+02, float 1.280000e+02, i32 42, i32 0, i32 666 } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
