https://github.com/joaosaffran updated https://github.com/llvm/llvm-project/pull/160184
>From fefd58c2ab1044ac51c546b6bc6df968eb5edaa8 Mon Sep 17 00:00:00 2001 From: Joao Saffran <joaosaffranl...@gmail.com> Date: Fri, 19 Sep 2025 12:48:11 -0700 Subject: [PATCH 1/8] 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 <joaosaffranl...@gmail.com> Date: Mon, 22 Sep 2025 10:28:12 -0700 Subject: [PATCH 2/8] 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 <joaosaffranl...@gmail.com> Date: Mon, 22 Sep 2025 11:29:55 -0700 Subject: [PATCH 3/8] 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 <joaosaffranl...@gmail.com> Date: Mon, 22 Sep 2025 12:17:34 -0700 Subject: [PATCH 4/8] 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 <joaosaffranl...@gmail.com> Date: Mon, 22 Sep 2025 12:32:25 -0700 Subject: [PATCH 5/8] 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 <joaosaffranl...@gmail.com> Date: Mon, 22 Sep 2025 12:33:59 -0700 Subject: [PATCH 6/8] 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 159cd5793e9bfa1cacaecc4601b8e4607e49cdc8 Mon Sep 17 00:00:00 2001 From: Joao Saffran <joaosaffranl...@gmail.com> Date: Wed, 24 Sep 2025 12:37:02 -0700 Subject: [PATCH 7/8] 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 b7f07aa9781a6e62627aa98a0aa90f5a76d8f75f Mon Sep 17 00:00:00 2001 From: Joao Saffran <joaosaffranl...@gmail.com> Date: Wed, 24 Sep 2025 13:47:31 -0700 Subject: [PATCH 8/8] 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, _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits