[llvm-branch-commits] [llvm] [DirectX] Updating DXContainer logic to read version 1.2 of static samplers (PR #160184)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Sep 24 12:37:18 PDT 2025
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 <joaosaffranllvm at gmail.com>
Date: Fri, 19 Sep 2025 12:48:11 -0700
Subject: [PATCH 1/7] fix test
---
llvm/include/llvm/Object/DXContainer.h | 57 ++++++++++++++++-------
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 16 ++++++-
llvm/unittests/Object/DXContainerTest.cpp | 16 ++++---
3 files changed, 63 insertions(+), 26 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 9bc1918852335..e3e532f6635a4 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -123,25 +123,26 @@ template <typename T> struct ViewArray {
};
namespace DirectX {
+
+template <typename T> Expected<T> readParameter(StringRef Data) {
+ T Struct;
+ if (sizeof(T) != Data.size())
+ return make_error<GenericBinaryError>(
+ "Reading structure out of file bounds", object_error::parse_failed);
+
+ memcpy(&Struct, Data.data(), sizeof(T));
+ // DXContainer is always little endian
+ if (sys::IsBigEndianHost)
+ Struct.swapBytes();
+ return Struct;
+}
+
struct RootParameterView {
const dxbc::RTS0::v1::RootParameterHeader &Header;
StringRef ParamData;
RootParameterView(const dxbc::RTS0::v1::RootParameterHeader &H, StringRef P)
: Header(H), ParamData(P) {}
-
- template <typename T> Expected<T> readParameter() {
- T Struct;
- if (sizeof(T) != ParamData.size())
- return make_error<GenericBinaryError>(
- "Reading structure out of file bounds", object_error::parse_failed);
-
- memcpy(&Struct, ParamData.data(), sizeof(T));
- // DXContainer is always little endian
- if (sys::IsBigEndianHost)
- Struct.swapBytes();
- return Struct;
- }
};
struct RootConstantView : RootParameterView {
@@ -151,7 +152,7 @@ struct RootConstantView : RootParameterView {
}
llvm::Expected<dxbc::RTS0::v1::RootConstants> read() {
- return readParameter<dxbc::RTS0::v1::RootConstants>();
+ return readParameter<dxbc::RTS0::v1::RootConstants>(ParamData);
}
};
@@ -167,7 +168,8 @@ struct RootDescriptorView : RootParameterView {
llvm::Expected<dxbc::RTS0::v2::RootDescriptor> read(uint32_t Version) {
if (Version == 1) {
- auto Descriptor = readParameter<dxbc::RTS0::v1::RootDescriptor>();
+ auto Descriptor =
+ readParameter<dxbc::RTS0::v1::RootDescriptor>(ParamData);
if (Error E = Descriptor.takeError())
return E;
return dxbc::RTS0::v2::RootDescriptor(*Descriptor);
@@ -176,9 +178,10 @@ struct RootDescriptorView : RootParameterView {
return make_error<GenericBinaryError>("Invalid Root Signature version: " +
Twine(Version),
object_error::parse_failed);
- return readParameter<dxbc::RTS0::v2::RootDescriptor>();
+ return readParameter<dxbc::RTS0::v2::RootDescriptor>(ParamData);
}
};
+
template <typename T> struct DescriptorTable {
uint32_t NumRanges;
uint32_t RangesOffset;
@@ -247,8 +250,26 @@ class RootSignature {
llvm::iterator_range<param_header_iterator> param_headers() const {
return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
}
- llvm::iterator_range<samplers_iterator> samplers() const {
- return llvm::make_range(StaticSamplers.begin(), StaticSamplers.end());
+ llvm::Expected<dxbc::RTS0::v3::StaticSampler> getSampler(uint32_t Loc) const {
+ if (Loc >= getNumStaticSamplers())
+ return parseFailed("Static sampler index out of range");
+
+ auto SamplerSize = (Version <= 2) ? sizeof(dxbc::RTS0::v1::StaticSampler)
+ : sizeof(dxbc::RTS0::v3::StaticSampler);
+
+ StringRef Buff = PartData.substr(StaticSamplersOffset + (Loc * SamplerSize),
+ SamplerSize);
+ if (Version < 3) {
+ auto Sampler = readParameter<dxbc::RTS0::v1::StaticSampler>(Buff);
+ if (Error E = Sampler.takeError())
+ return E;
+ return dxbc::RTS0::v3::StaticSampler(*Sampler);
+ }
+ if (Version != 3)
+ return make_error<GenericBinaryError>("Invalid Root Signature version: " +
+ Twine(Version),
+ object_error::parse_failed);
+ return readParameter<dxbc::RTS0::v3::StaticSampler>(Buff);
}
uint32_t getFlags() const { return Flags; }
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 42074731c4e16..6f24b7d2573ec 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -163,7 +163,13 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
- for (const auto &S : Data.samplers()) {
+ for (uint32_t Loc = 0; Loc < Data.getNumStaticSamplers(); ++Loc) {
+ llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler =
+ Data.getSampler(Loc);
+ if (Error E = MaybeSampler.takeError())
+ return std::move(E);
+ const llvm::dxbc::RTS0::v3::StaticSampler &S = *MaybeSampler;
+
if (!dxbc::isValidSamplerFilter(S.Filter))
return createStringError(std::errc::invalid_argument,
"Invalid value for static sampler filter");
@@ -209,6 +215,14 @@ DXContainerYAML::RootSignatureYamlDesc::create(
NewS.RegisterSpace = S.RegisterSpace;
NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);
+ if (Version > 2) {
+ if (Version > 1) {
+#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
+ NewS.Enum = \
+ (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ }
+ }
RootSigDesc.StaticSamplers.push_back(NewS);
}
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 396d060a75bfd..f2a7bdfdcd75a 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1165,11 +1165,11 @@ TEST(RootSignature, ParseStaticSamplers) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
- 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
- 0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
+ 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x7f,
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
DXContainer C =
llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
@@ -1179,12 +1179,14 @@ TEST(RootSignature, ParseStaticSamplers) {
const auto &RS = MaybeRS.value();
ASSERT_EQ(RS.getVersion(), 2u);
ASSERT_EQ(RS.getNumParameters(), 0u);
- ASSERT_EQ(RS.getRootParametersOffset(), 0u);
+ ASSERT_EQ(RS.getRootParametersOffset(), 24u);
ASSERT_EQ(RS.getNumStaticSamplers(), 1u);
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
- auto Sampler = *RS.samplers().begin();
+ auto MaybeSamplerView = RS.getSampler(0);
+ ASSERT_THAT_ERROR(MaybeSamplerView.takeError(), Succeeded());
+ const auto &Sampler = *MaybeSamplerView;
ASSERT_EQ(Sampler.Filter, 10u);
ASSERT_EQ(Sampler.AddressU, 1u);
>From 1d0cbd39875a84c983106678c8b857d8157bfa51 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 10:28:12 -0700
Subject: [PATCH 2/7] adding samplers_iterator
---
llvm/include/llvm/Object/DXContainer.h | 70 +++++++++++++++++------
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 5 +-
llvm/unittests/Object/DXContainerTest.cpp | 2 +-
3 files changed, 56 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e3e532f6635a4..e3913ece842bc 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -223,6 +223,28 @@ static Error parseFailed(const Twine &Msg) {
class RootSignature {
private:
+ struct samplers_iterator {
+ const RootSignature *Parent = nullptr;
+ uint32_t Index = 0;
+
+ llvm::Expected<dxbc::RTS0::v3::StaticSampler> operator*() const {
+ return Parent->getSampler(Index);
+ }
+
+ samplers_iterator &operator++() {
+ ++Index;
+ return *this;
+ }
+
+ bool operator==(const samplers_iterator &Other) const {
+ return Parent == Other.Parent && Index == Other.Index;
+ }
+
+ bool operator!=(const samplers_iterator &Other) const {
+ return !(*this == Other);
+ }
+ };
+
uint32_t Version;
uint32_t NumParameters;
uint32_t RootParametersOffset;
@@ -233,23 +255,6 @@ class RootSignature {
StringRef PartData;
ViewArray<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
- using param_header_iterator =
- ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
- using samplers_iterator = ViewArray<dxbc::RTS0::v1::StaticSampler>::iterator;
-
-public:
- RootSignature(StringRef PD) : PartData(PD) {}
-
- LLVM_ABI Error parse();
- uint32_t getVersion() const { return Version; }
- uint32_t getNumParameters() const { return NumParameters; }
- uint32_t getRootParametersOffset() const { return RootParametersOffset; }
- uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
- uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
- uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
- llvm::iterator_range<param_header_iterator> param_headers() const {
- return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
- }
llvm::Expected<dxbc::RTS0::v3::StaticSampler> getSampler(uint32_t Loc) const {
if (Loc >= getNumStaticSamplers())
return parseFailed("Static sampler index out of range");
@@ -271,6 +276,37 @@ class RootSignature {
object_error::parse_failed);
return readParameter<dxbc::RTS0::v3::StaticSampler>(Buff);
}
+
+ using param_header_iterator =
+ ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
+
+public:
+ RootSignature(StringRef PD) : PartData(PD) {}
+
+ LLVM_ABI Error parse();
+ uint32_t getVersion() const { return Version; }
+ uint32_t getNumParameters() const { return NumParameters; }
+ uint32_t getRootParametersOffset() const { return RootParametersOffset; }
+ uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
+ uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
+ uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
+
+ samplers_iterator samplers_begin() const {
+ return samplers_iterator{this, 0};
+ }
+
+ samplers_iterator samplers_end() const {
+ return samplers_iterator{this, getNumStaticSamplers()};
+ }
+
+ llvm::iterator_range<samplers_iterator> samplers() const {
+ return llvm::make_range(samplers_begin(), samplers_end());
+ }
+
+ llvm::iterator_range<param_header_iterator> param_headers() const {
+ return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
+ }
+
uint32_t getFlags() const { return Flags; }
llvm::Expected<RootParameterView>
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 6f24b7d2573ec..91f86caaa4005 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -163,9 +163,8 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
- for (uint32_t Loc = 0; Loc < Data.getNumStaticSamplers(); ++Loc) {
- llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler =
- Data.getSampler(Loc);
+ for (llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler :
+ Data.samplers()) {
if (Error E = MaybeSampler.takeError())
return std::move(E);
const llvm::dxbc::RTS0::v3::StaticSampler &S = *MaybeSampler;
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 923df70f44194..fe898c430b8a3 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1184,7 +1184,7 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
- auto MaybeSamplerView = RS.getSampler(0);
+ auto MaybeSamplerView = *RS.samplers().begin();
ASSERT_THAT_ERROR(MaybeSamplerView.takeError(), Succeeded());
const auto &Sampler = *MaybeSamplerView;
>From e530bcc1b81b300a12ada139c54553b84ab89a03 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 11:29:55 -0700
Subject: [PATCH 3/7] this was easier than I thought
---
llvm/include/llvm/Object/DXContainer.h | 62 ++---------------------
llvm/lib/Object/DXContainer.cpp | 13 +++--
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 6 +--
llvm/unittests/Object/DXContainerTest.cpp | 49 ++++++++++++++++--
4 files changed, 61 insertions(+), 69 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e3913ece842bc..0bfc5cec48da4 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -223,28 +223,6 @@ static Error parseFailed(const Twine &Msg) {
class RootSignature {
private:
- struct samplers_iterator {
- const RootSignature *Parent = nullptr;
- uint32_t Index = 0;
-
- llvm::Expected<dxbc::RTS0::v3::StaticSampler> operator*() const {
- return Parent->getSampler(Index);
- }
-
- samplers_iterator &operator++() {
- ++Index;
- return *this;
- }
-
- bool operator==(const samplers_iterator &Other) const {
- return Parent == Other.Parent && Index == Other.Index;
- }
-
- bool operator!=(const samplers_iterator &Other) const {
- return !(*this == Other);
- }
- };
-
uint32_t Version;
uint32_t NumParameters;
uint32_t RootParametersOffset;
@@ -253,32 +231,11 @@ class RootSignature {
uint32_t Flags;
ViewArray<dxbc::RTS0::v1::RootParameterHeader> ParametersHeaders;
StringRef PartData;
- ViewArray<dxbc::RTS0::v1::StaticSampler> StaticSamplers;
-
- llvm::Expected<dxbc::RTS0::v3::StaticSampler> getSampler(uint32_t Loc) const {
- if (Loc >= getNumStaticSamplers())
- return parseFailed("Static sampler index out of range");
-
- auto SamplerSize = (Version <= 2) ? sizeof(dxbc::RTS0::v1::StaticSampler)
- : sizeof(dxbc::RTS0::v3::StaticSampler);
-
- StringRef Buff = PartData.substr(StaticSamplersOffset + (Loc * SamplerSize),
- SamplerSize);
- if (Version < 3) {
- auto Sampler = readParameter<dxbc::RTS0::v1::StaticSampler>(Buff);
- if (Error E = Sampler.takeError())
- return E;
- return dxbc::RTS0::v3::StaticSampler(*Sampler);
- }
- if (Version != 3)
- return make_error<GenericBinaryError>("Invalid Root Signature version: " +
- Twine(Version),
- object_error::parse_failed);
- return readParameter<dxbc::RTS0::v3::StaticSampler>(Buff);
- }
+ ViewArray<dxbc::RTS0::v3::StaticSampler> StaticSamplers;
using param_header_iterator =
ViewArray<dxbc::RTS0::v1::RootParameterHeader>::iterator;
+ using samplers_iterator = ViewArray<dxbc::RTS0::v3::StaticSampler>::iterator;
public:
RootSignature(StringRef PD) : PartData(PD) {}
@@ -290,21 +247,12 @@ class RootSignature {
uint32_t getNumStaticSamplers() const { return NumStaticSamplers; }
uint32_t getStaticSamplersOffset() const { return StaticSamplersOffset; }
uint32_t getNumRootParameters() const { return ParametersHeaders.size(); }
-
- samplers_iterator samplers_begin() const {
- return samplers_iterator{this, 0};
- }
-
- samplers_iterator samplers_end() const {
- return samplers_iterator{this, getNumStaticSamplers()};
+ llvm::iterator_range<param_header_iterator> param_headers() const {
+ return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
}
llvm::iterator_range<samplers_iterator> samplers() const {
- return llvm::make_range(samplers_begin(), samplers_end());
- }
-
- llvm::iterator_range<param_header_iterator> param_headers() const {
- return llvm::make_range(ParametersHeaders.begin(), ParametersHeaders.end());
+ return llvm::make_range(StaticSamplers.begin(), StaticSamplers.end());
}
uint32_t getFlags() const { return Flags; }
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index 031b9414f4c1a..b7da8316840f0 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//
+#include <cstddef>
+
#include "llvm/Object/DXContainer.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
@@ -276,10 +278,13 @@ Error DirectX::RootSignature::parse() {
RootParametersOffset,
NumParameters * sizeof(dxbc::RTS0::v1::RootParameterHeader));
- StaticSamplers.Stride = sizeof(dxbc::RTS0::v1::StaticSampler);
- StaticSamplers.Data = PartData.substr(
- StaticSamplersOffset,
- NumStaticSamplers * sizeof(dxbc::RTS0::v1::StaticSampler));
+ StaticSamplers.Stride = (Version <= 2)
+ ? sizeof(dxbc::RTS0::v1::StaticSampler)
+ : sizeof(dxbc::RTS0::v3::StaticSampler);
+
+ StaticSamplers.Data = PartData.substr(StaticSamplersOffset,
+ static_cast<size_t>(NumStaticSamplers) *
+ StaticSamplers.Stride);
return Error::success();
}
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 91f86caaa4005..2fde1b86247f8 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -163,11 +163,7 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
}
- for (llvm::Expected<dxbc::RTS0::v3::StaticSampler> MaybeSampler :
- Data.samplers()) {
- if (Error E = MaybeSampler.takeError())
- return std::move(E);
- const llvm::dxbc::RTS0::v3::StaticSampler &S = *MaybeSampler;
+ for (const auto &S : Data.samplers()) {
if (!dxbc::isValidSamplerFilter(S.Filter))
return createStringError(std::errc::invalid_argument,
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index fe898c430b8a3..76b2aed5bb591 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1184,9 +1184,7 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(RS.getStaticSamplersOffset(), 24u);
ASSERT_EQ(RS.getFlags(), 17u);
- auto MaybeSamplerView = *RS.samplers().begin();
- ASSERT_THAT_ERROR(MaybeSamplerView.takeError(), Succeeded());
- const auto &Sampler = *MaybeSamplerView;
+ auto Sampler = *RS.samplers().begin();
ASSERT_EQ(Sampler.Filter, 10u);
ASSERT_EQ(Sampler.AddressU, 1u);
@@ -1202,4 +1200,49 @@ TEST(RootSignature, ParseStaticSamplers) {
ASSERT_EQ(Sampler.RegisterSpace, 32u);
ASSERT_EQ(Sampler.ShaderVisibility, 7u);
}
+ {
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x4c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x18, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0xa4, 0x70, 0x9d, 0x3f, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
+ 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00};
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<148>(Buffer)));
+
+ auto MaybeRS = C.getRootSignature();
+ ASSERT_TRUE(MaybeRS.has_value());
+ const auto &RS = MaybeRS.value();
+ ASSERT_EQ(RS.getVersion(), 3U);
+ ASSERT_EQ(RS.getNumParameters(), 0U);
+ ASSERT_EQ(RS.getRootParametersOffset(), 0U);
+ ASSERT_EQ(RS.getNumStaticSamplers(), 1U);
+ ASSERT_EQ(RS.getStaticSamplersOffset(), 24U);
+ ASSERT_EQ(RS.getFlags(), 17U);
+
+ auto Sampler = *RS.samplers().begin();
+
+ ASSERT_EQ(Sampler.Filter, 10U);
+ ASSERT_EQ(Sampler.AddressU, 1U);
+ ASSERT_EQ(Sampler.AddressV, 2U);
+ ASSERT_EQ(Sampler.AddressW, 5U);
+ ASSERT_FLOAT_EQ(Sampler.MipLODBias, 1.23F);
+ ASSERT_EQ(Sampler.MaxAnisotropy, 20U);
+ ASSERT_EQ(Sampler.ComparisonFunc, 4U);
+ ASSERT_EQ(Sampler.BorderColor, 0U);
+ ASSERT_FLOAT_EQ(Sampler.MinLOD, 4.56F);
+ ASSERT_FLOAT_EQ(Sampler.MaxLOD, 8.9F);
+ ASSERT_EQ(Sampler.ShaderRegister, 31U);
+ ASSERT_EQ(Sampler.RegisterSpace, 32U);
+ ASSERT_EQ(Sampler.ShaderVisibility, 7U);
+ ASSERT_EQ(Sampler.Flags, 1U);
+ }
}
>From 79ea587527552aaf93110098b526a88edbce620b Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 12:17:34 -0700
Subject: [PATCH 4/7] adding new test
---
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 2 -
.../RootSignature-StaticSamplers1.3.yaml | 65 +++++++++++++++++++
2 files changed, 65 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 2fde1b86247f8..806722be0813d 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -211,12 +211,10 @@ DXContainerYAML::RootSignatureYamlDesc::create(
NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);
if (Version > 2) {
- if (Version > 1) {
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag) \
NewS.Enum = \
(S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
- }
}
RootSigDesc.StaticSamplers.push_back(NewS);
}
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml
new file mode 100644
index 0000000000000..1623b05def009
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-StaticSamplers1.3.yaml
@@ -0,0 +1,65 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !dxcontainer
+Header:
+ Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ]
+ Version:
+ Major: 1
+ Minor: 0
+ PartCount: 1
+ PartOffsets: [ 60 ]
+Parts:
+ - Name: RTS0
+ Size: 80
+ RootSignature:
+ Version: 3
+ NumRootParameters: 0
+ RootParametersOffset: 24
+ NumStaticSamplers: 1
+ StaticSamplersOffset: 24
+ Parameters: []
+ Samplers:
+ - Filter: MinLinearMagMipPoint
+ AddressU: Wrap
+ AddressV: Mirror
+ AddressW: MirrorOnce
+ MipLODBias: 1.23
+ MaxAnisotropy: 20
+ ComparisonFunc: LessEqual
+ BorderColor: TransparentBlack
+ MinLOD: 4.56
+ MaxLOD: 8.90
+ ShaderRegister: 31
+ RegisterSpace: 32
+ ShaderVisibility: Mesh
+ SAMPLER_FLAG_UINT_BORDER_COLOR: true
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+
+#CHECK: - Name: RTS0
+#CHECK-NEXT: Size: 80
+#CHECK-NEXT: RootSignature:
+#CHECK-NEXT: Version: 3
+#CHECK-NEXT: NumRootParameters: 0
+#CHECK-NEXT: RootParametersOffset: 24
+#CHECK-NEXT: NumStaticSamplers: 1
+#CHECK-NEXT: StaticSamplersOffset: 24
+#CHECK-NEXT: Parameters: []
+#CHECK-NEXT: Samplers:
+#CHECK-NEXT: - Filter: MinLinearMagMipPoint
+#CHECK-NEXT: AddressU: Wrap
+#CHECK-NEXT: AddressV: Mirror
+#CHECK-NEXT: AddressW: MirrorOnce
+#CHECK-NEXT: MipLODBias: 1.23
+#CHECK-NEXT: MaxAnisotropy: 20
+#CHECK-NEXT: ComparisonFunc: LessEqual
+#CHECK-NEXT: BorderColor: TransparentBlack
+#CHECK-NEXT: MinLOD: 4.56
+#CHECK-NEXT: MaxLOD: 8.9
+#CHECK-NEXT: ShaderRegister: 31
+#CHECK-NEXT: RegisterSpace: 32
+#CHECK-NEXT: ShaderVisibility: Mesh
+#CHECK-NEXT: SAMPLER_FLAG_UINT_BORDER_COLOR: true
+#CHECK-NEXT: AllowInputAssemblerInputLayout: true
+#CHECK-NEXT: DenyGeometryShaderRootAccess: true
>From 905d5d39d93e35a512537bec76566abefc79ce27 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 12:32:25 -0700
Subject: [PATCH 5/7] clean up
---
llvm/include/llvm/Object/DXContainer.h | 33 +++++++++++------------
llvm/lib/Object/DXContainer.cpp | 2 --
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 1 -
llvm/unittests/Object/DXContainerTest.cpp | 2 +-
4 files changed, 17 insertions(+), 21 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 0bfc5cec48da4..6f10401dd2ba2 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -124,25 +124,25 @@ template <typename T> struct ViewArray {
namespace DirectX {
-template <typename T> Expected<T> readParameter(StringRef Data) {
- T Struct;
- if (sizeof(T) != Data.size())
- return make_error<GenericBinaryError>(
- "Reading structure out of file bounds", object_error::parse_failed);
-
- memcpy(&Struct, Data.data(), sizeof(T));
- // DXContainer is always little endian
- if (sys::IsBigEndianHost)
- Struct.swapBytes();
- return Struct;
-}
-
struct RootParameterView {
const dxbc::RTS0::v1::RootParameterHeader &Header;
StringRef ParamData;
RootParameterView(const dxbc::RTS0::v1::RootParameterHeader &H, StringRef P)
: Header(H), ParamData(P) {}
+
+ template <typename T> Expected<T> readParameter() {
+ T Struct;
+ if (sizeof(T) != ParamData.size())
+ return make_error<GenericBinaryError>(
+ "Reading structure out of file bounds", object_error::parse_failed);
+
+ memcpy(&Struct, ParamData.data(), sizeof(T));
+ // DXContainer is always little endian
+ if (sys::IsBigEndianHost)
+ Struct.swapBytes();
+ return Struct;
+ }
};
struct RootConstantView : RootParameterView {
@@ -152,7 +152,7 @@ struct RootConstantView : RootParameterView {
}
llvm::Expected<dxbc::RTS0::v1::RootConstants> read() {
- return readParameter<dxbc::RTS0::v1::RootConstants>(ParamData);
+ return readParameter<dxbc::RTS0::v1::RootConstants>();
}
};
@@ -168,8 +168,7 @@ struct RootDescriptorView : RootParameterView {
llvm::Expected<dxbc::RTS0::v2::RootDescriptor> read(uint32_t Version) {
if (Version == 1) {
- auto Descriptor =
- readParameter<dxbc::RTS0::v1::RootDescriptor>(ParamData);
+ auto Descriptor = readParameter<dxbc::RTS0::v1::RootDescriptor>();
if (Error E = Descriptor.takeError())
return E;
return dxbc::RTS0::v2::RootDescriptor(*Descriptor);
@@ -178,7 +177,7 @@ struct RootDescriptorView : RootParameterView {
return make_error<GenericBinaryError>("Invalid Root Signature version: " +
Twine(Version),
object_error::parse_failed);
- return readParameter<dxbc::RTS0::v2::RootDescriptor>(ParamData);
+ return readParameter<dxbc::RTS0::v2::RootDescriptor>();
}
};
diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp
index b7da8316840f0..7b7b8d88c63fc 100644
--- a/llvm/lib/Object/DXContainer.cpp
+++ b/llvm/lib/Object/DXContainer.cpp
@@ -6,8 +6,6 @@
//
//===----------------------------------------------------------------------===//
-#include <cstddef>
-
#include "llvm/Object/DXContainer.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 806722be0813d..bfb3837707f0a 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -164,7 +164,6 @@ DXContainerYAML::RootSignatureYamlDesc::create(
}
for (const auto &S : Data.samplers()) {
-
if (!dxbc::isValidSamplerFilter(S.Filter))
return createStringError(std::errc::invalid_argument,
"Invalid value for static sampler filter");
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 76b2aed5bb591..7fec8addc8d52 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1172,7 +1172,7 @@ TEST(RootSignature, ParseStaticSamplers) {
0x00, 0x00, 0x00, 0x00, 0x85, 0xeb, 0x91, 0x40, 0x66, 0x66, 0x0e, 0x41,
0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
DXContainer C =
- llvm::cantFail(DXContainer::create(getMemoryBuffer<144>(Buffer)));
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
auto MaybeRS = C.getRootSignature();
ASSERT_TRUE(MaybeRS.has_value());
>From b73bf248c1225498e6372d25f8e75ce6a03d5489 Mon Sep 17 00:00:00 2001
From: Joao Saffran <joaosaffranllvm at gmail.com>
Date: Mon, 22 Sep 2025 12:33:59 -0700
Subject: [PATCH 6/7] 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 <joaosaffranllvm at gmail.com>
Date: Wed, 24 Sep 2025 12:37:02 -0700
Subject: [PATCH 7/7] 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,
More information about the llvm-branch-commits
mailing list