[llvm-branch-commits] [llvm] [DirectX] adding support to read/write descriptor table data using obj2yaml/yaml2obj (PR #138315)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Fri May 2 11:00:47 PDT 2025
https://github.com/joaosaffran created https://github.com/llvm/llvm-project/pull/138315
Closes: https://github.com/orgs/llvm/projects/4/views/22?sliceBy%5Bvalue%5D=joaosaffran&pane=issue&itemId=97332852&issue=llvm%7Cllvm-project%7C126635
>From 44bd13abd1038aa43d66f4942d831a3b1c752b8c Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Tue, 29 Apr 2025 23:57:47 +0000
Subject: [PATCH 1/6] making read work
---
llvm/include/llvm/BinaryFormat/DXContainer.h | 35 +++++++
.../BinaryFormat/DXContainerConstants.def | 25 ++++-
.../llvm/MC/DXContainerRootSignature.h | 32 +++++-
.../include/llvm/ObjectYAML/DXContainerYAML.h | 98 +++++++++++++++++++
llvm/lib/MC/DXContainerRootSignature.cpp | 78 +++++++++++++--
llvm/lib/ObjectYAML/DXContainerEmitter.cpp | 27 +++++
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 32 ++++++
.../RootSignature-MultipleParameters.yaml | 11 +++
8 files changed, 326 insertions(+), 12 deletions(-)
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 3dbcfa82f3d7c..a441fa3a36886 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainer.h
+++ b/llvm/include/llvm/BinaryFormat/DXContainer.h
@@ -163,6 +163,11 @@ enum class RootDescriptorFlag : uint32_t {
#include "DXContainerConstants.def"
};
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) Val = 1ull << Num,
+enum class DescriptorRangeFlag : uint32_t {
+#include "DXContainerConstants.def"
+};
+
#define ROOT_PARAMETER(Val, Enum) Enum = Val,
enum class RootParameterType : uint32_t {
#include "DXContainerConstants.def"
@@ -170,6 +175,13 @@ enum class RootParameterType : uint32_t {
ArrayRef<EnumEntry<RootParameterType>> getRootParameterTypes();
+#define DESCRIPTOR_RANGE(Val, Enum) Enum = Val,
+enum class DescriptorRangeType : uint32_t {
+#include "DXContainerConstants.def"
+};
+
+ArrayRef<EnumEntry<DescriptorRangeType>> getDescriptorRangeTypes();
+
#define ROOT_PARAMETER(Val, Enum) \
case Val: \
return true;
@@ -595,6 +607,21 @@ struct RootDescriptor {
sys::swapByteOrder(RegisterSpace);
}
};
+
+struct DescriptorRange {
+ uint32_t RangeType;
+ uint32_t NumDescriptors;
+ uint32_t BaseShaderRegister;
+ uint32_t RegisterSpace;
+ int32_t OffsetInDescriptorsFromTableStart;
+ void swapBytes() {
+ sys::swapByteOrder(RangeType);
+ sys::swapByteOrder(NumDescriptors);
+ sys::swapByteOrder(BaseShaderRegister);
+ sys::swapByteOrder(RegisterSpace);
+ sys::swapByteOrder(OffsetInDescriptorsFromTableStart);
+ }
+};
} // namespace v0
namespace v1 {
@@ -605,6 +632,14 @@ struct RootDescriptor : public v0::RootDescriptor {
sys::swapByteOrder(Flags);
}
};
+
+struct DescriptorRange : public v0::DescriptorRange {
+ uint32_t Flags;
+ void swapBytes() {
+ v0::DescriptorRange::swapBytes();
+ sys::swapByteOrder(Flags);
+ }
+};
} // namespace v1
} // namespace RST0
// following dx12 naming
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index bd9bd760547dc..5fe7e7c321a33 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -73,7 +73,7 @@ ROOT_ELEMENT_FLAG(11, SamplerHeapDirectlyIndexed)
#endif // ROOT_ELEMENT_FLAG
-// ROOT_ELEMENT_FLAG(bit offset for the flag, name).
+// ROOT_DESCRIPTOR_FLAG(bit offset for the flag, name).
#ifdef ROOT_DESCRIPTOR_FLAG
ROOT_DESCRIPTOR_FLAG(0, NONE)
@@ -84,8 +84,21 @@ ROOT_DESCRIPTOR_FLAG(3, DATA_STATIC)
#endif // ROOT_DESCRIPTOR_FLAG
+// DESCRIPTOR_RANGE_FLAG(bit offset for the flag, name).
+#ifdef DESCRIPTOR_RANGE_FLAG
+
+DESCRIPTOR_RANGE_FLAG(0, NONE)
+DESCRIPTOR_RANGE_FLAG(1, DESCRIPTORS_VOLATILE)
+DESCRIPTOR_RANGE_FLAG(2, DATA_VOLATILE)
+DESCRIPTOR_RANGE_FLAG(3, DATA_STATIC_WHILE_SET_AT_EXECUTE)
+DESCRIPTOR_RANGE_FLAG(4, DATA_STATIC)
+DESCRIPTOR_RANGE_FLAG(16, DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS)
+#undef DESCRIPTOR_RANGE_FLAG
+#endif // DESCRIPTOR_RANGE_FLAG
+
#ifdef ROOT_PARAMETER
+ROOT_PARAMETER(0, DescriptorTable)
ROOT_PARAMETER(1, Constants32Bit)
ROOT_PARAMETER(2, CBV)
ROOT_PARAMETER(3, SRV)
@@ -93,6 +106,16 @@ ROOT_PARAMETER(4, UAV)
#undef ROOT_PARAMETER
#endif // ROOT_PARAMETER
+
+#ifdef DESCRIPTOR_RANGE
+
+DESCRIPTOR_RANGE(0, SRV)
+DESCRIPTOR_RANGE(1, UAV)
+DESCRIPTOR_RANGE(2, CBV)
+DESCRIPTOR_RANGE(3, Sampler)
+#undef DESCRIPTOR_RANGE
+#endif // DESCRIPTOR_RANGE
+
#ifdef SHADER_VISIBILITY
SHADER_VISIBILITY(0, All)
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index c8af613a57094..3f5960a6de2f9 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include <cstddef>
#include <cstdint>
@@ -28,17 +29,30 @@ struct RootParameterInfo {
RootParameterInfo(dxbc::RootParameterHeader H, size_t L)
: Header(H), Location(L) {}
};
+using DescriptorRanges = std::variant<dxbc::RST0::v0::DescriptorRange,
+ dxbc::RST0::v1::DescriptorRange>;
+struct DescriptorTable {
+ SmallVector<DescriptorRanges> Ranges;
+
+ SmallVector<DescriptorRanges>::const_iterator begin() const {
+ return Ranges.begin();
+ }
+ SmallVector<DescriptorRanges>::const_iterator end() const {
+ return Ranges.end();
+ }
+};
using RootDescriptor = std::variant<dxbc::RST0::v0::RootDescriptor,
dxbc::RST0::v1::RootDescriptor>;
-using ParametersView = std::variant<const dxbc::RootConstants *,
- const dxbc::RST0::v0::RootDescriptor *,
- const dxbc::RST0::v1::RootDescriptor *>;
+
+using ParametersView = std::variant<
+ const dxbc::RootConstants *, const dxbc::RST0::v0::RootDescriptor *,
+ const dxbc::RST0::v1::RootDescriptor *, const DescriptorTable *>;
struct RootParametersContainer {
SmallVector<RootParameterInfo> ParametersInfo;
-
SmallVector<dxbc::RootConstants> Constants;
SmallVector<RootDescriptor> Descriptors;
+ SmallVector<DescriptorTable> Tables;
void addInfo(dxbc::RootParameterHeader H, size_t L) {
ParametersInfo.push_back(RootParameterInfo(H, L));
@@ -61,13 +75,18 @@ struct RootParametersContainer {
Descriptors.push_back(D);
}
+ void addParameter(dxbc::RootParameterHeader H, DescriptorTable D) {
+ addInfo(H, Tables.size());
+ Tables.push_back(D);
+ }
+
std::optional<ParametersView> getParameter(const RootParameterInfo *H) const {
switch (H->Header.ParameterType) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
return &Constants[H->Location];
case llvm::to_underlying(dxbc::RootParameterType::CBV):
case llvm::to_underlying(dxbc::RootParameterType::SRV):
- case llvm::to_underlying(dxbc::RootParameterType::UAV):
+ case llvm::to_underlying(dxbc::RootParameterType::UAV): {
const RootDescriptor &VersionedParam = Descriptors[H->Location];
if (std::holds_alternative<dxbc::RST0::v0::RootDescriptor>(
VersionedParam)) {
@@ -75,6 +94,9 @@ struct RootParametersContainer {
}
return &std::get<dxbc::RST0::v1::RootDescriptor>(VersionedParam);
}
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+ return &Tables[H->Location];
+ }
return std::nullopt;
}
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 8bb9da7884bed..738108cc3d1be 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -15,6 +15,8 @@
#ifndef LLVM_OBJECTYAML_DXCONTAINERYAML_H
#define LLVM_OBJECTYAML_DXCONTAINERYAML_H
+#include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/DXContainer.h"
@@ -91,6 +93,25 @@ struct RootDescriptorYaml {
#include "llvm/BinaryFormat/DXContainerConstants.def"
};
+struct DescriptorRangeYaml {
+ uint32_t RangeType;
+ uint32_t NumDescriptors;
+ uint32_t BaseShaderRegister;
+ uint32_t RegisterSpace;
+ int32_t OffsetInDescriptorsFromTableStart;
+
+ uint32_t getEncodedFlags() const;
+
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) bool Val = false;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+};
+
+struct DescriptorTableYaml {
+ uint32_t NumRanges;
+ uint32_t RangesOffset;
+ SmallVector<DescriptorRangeYaml> Ranges;
+};
+
struct RootParameterYamlDesc {
uint32_t Type;
uint32_t Visibility;
@@ -107,12 +128,80 @@ struct RootParameterYamlDesc {
case llvm::to_underlying(dxbc::RootParameterType::UAV):
Descriptor = RootDescriptorYaml();
break;
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+ Table = DescriptorTableYaml();
+ break;
+ }
+ }
+
+ ~RootParameterYamlDesc() {
+ switch (Type) {
+
+ case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
+ Constants.~RootConstantsYaml();
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::CBV):
+ case llvm::to_underlying(dxbc::RootParameterType::SRV):
+ case llvm::to_underlying(dxbc::RootParameterType::UAV):
+ Descriptor.~RootDescriptorYaml();
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+ Table.~DescriptorTableYaml();
+ break;
}
}
+ RootParameterYamlDesc(const RootParameterYamlDesc &Other)
+ : Type(Other.Type), Visibility(Other.Visibility), Offset(Other.Offset) {
+ // Initialize the appropriate union member based on Type
+ switch (Type) {
+ case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
+ // Placement new to construct the union member
+ new (&Constants) RootConstantsYaml(Other.Constants);
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::CBV):
+ case llvm::to_underlying(dxbc::RootParameterType::SRV):
+ case llvm::to_underlying(dxbc::RootParameterType::UAV):
+ new (&Descriptor) RootDescriptorYaml(Other.Descriptor);
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+ new (&Table) DescriptorTableYaml(Other.Table);
+ break;
+ }
+ }
+
+ RootParameterYamlDesc &operator=(const RootParameterYamlDesc &other) {
+ if (this != &other) {
+ // First, destroy the current union member
+ this->~RootParameterYamlDesc();
+
+ // Copy the basic members
+ Type = other.Type;
+ Visibility = other.Visibility;
+ Offset = other.Offset;
+
+ // Initialize the new union member based on the Type from 'other'
+ switch (Type) {
+ case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
+ new (&Constants) RootConstantsYaml(other.Constants);
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::CBV):
+ case llvm::to_underlying(dxbc::RootParameterType::SRV):
+ case llvm::to_underlying(dxbc::RootParameterType::UAV):
+ new (&Descriptor) RootDescriptorYaml(other.Descriptor);
+ break;
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+ new (&Table) DescriptorTableYaml(other.Table);
+ break;
+ }
+ }
+ return *this;
+ }
+
union {
RootConstantsYaml Constants;
RootDescriptorYaml Descriptor;
+ DescriptorTableYaml Table;
};
};
@@ -244,6 +333,7 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::PSVInfo::MaskVector)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureParameter)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::RootParameterYamlDesc)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::DescriptorRangeYaml)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::SemanticKind)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::ComponentType)
LLVM_YAML_DECLARE_ENUM_TRAITS(llvm::dxbc::PSV::InterpolationMode)
@@ -328,6 +418,14 @@ template <> struct MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml> {
static void mapping(IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D);
};
+template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml> {
+ static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &D);
+};
+
+template <> struct MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml> {
+ static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &D);
+};
+
} // namespace yaml
} // namespace llvm
diff --git a/llvm/lib/MC/DXContainerRootSignature.cpp b/llvm/lib/MC/DXContainerRootSignature.cpp
index 641c2f5fa1b1b..4c725969e63cf 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -10,11 +10,43 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Support/EndianStream.h"
+#include <cstdint>
#include <variant>
using namespace llvm;
using namespace llvm::mcdxbc;
+class SizeCalculatorVisitor {
+public:
+ SizeCalculatorVisitor(uint32_t Version, size_t &SizeRef)
+ : Size(SizeRef), Version(Version) {}
+
+ void operator()(const dxbc::RootConstants *Value) const {
+ Size += sizeof(dxbc::RootConstants);
+ }
+
+ void operator()(const dxbc::RST0::v0::RootDescriptor *Value) const {
+ Size += sizeof(dxbc::RST0::v0::RootDescriptor);
+ }
+
+ void operator()(const dxbc::RST0::v1::RootDescriptor *Value) const {
+ Size += sizeof(dxbc::RST0::v1::RootDescriptor);
+ }
+
+ void operator()(const DescriptorTable *Value) const {
+ if (Version == 1)
+ Size +=
+ sizeof(dxbc::RST0::v0::DescriptorRange) * Value->Ranges.size() + 8;
+ else
+ Size +=
+ sizeof(dxbc::RST0::v1::DescriptorRange) * Value->Ranges.size() + 8;
+ }
+
+private:
+ size_t &Size;
+ uint32_t Version;
+};
+
static uint32_t writePlaceholder(raw_svector_ostream &Stream) {
const uint32_t DummyValue = std::numeric_limits<uint32_t>::max();
uint32_t Offset = Stream.tell();
@@ -38,12 +70,8 @@ size_t RootSignatureDesc::getSize() const {
std::optional<ParametersView> P = ParametersContainer.getParameter(&I);
if (!P)
continue;
- std::visit(
- [&Size](auto &Value) -> void {
- using T = std::decay_t<decltype(*Value)>;
- Size += sizeof(T);
- },
- *P);
+
+ std::visit(SizeCalculatorVisitor(Version, Size), *P);
}
return Size;
@@ -106,6 +134,44 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
support::endian::write(BOS, Descriptor->RegisterSpace,
llvm::endianness::little);
support::endian::write(BOS, Descriptor->Flags, llvm::endianness::little);
+ } else if (std::holds_alternative<const DescriptorTable *>(P.value())) {
+ auto *Table = std::get<const DescriptorTable *>(P.value());
+
+ support::endian::write(BOS, (uint32_t)Table->Ranges.size(),
+ llvm::endianness::little);
+ rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS));
+ for (const auto &R : *Table) {
+ if (std::holds_alternative<dxbc::RST0::v0::DescriptorRange>(R)) {
+ auto Range = std::get<dxbc::RST0::v0::DescriptorRange>(R);
+
+ support::endian::write(BOS, Range.RangeType,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.NumDescriptors,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.BaseShaderRegister,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.RegisterSpace,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,
+ llvm::endianness::little);
+ } else {
+ if (std::holds_alternative<dxbc::RST0::v1::DescriptorRange>(R)) {
+ auto Range = std::get<dxbc::RST0::v1::DescriptorRange>(R);
+
+ support::endian::write(BOS, Range.RangeType,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.NumDescriptors,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.BaseShaderRegister,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.RegisterSpace,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.OffsetInDescriptorsFromTableStart,
+ llvm::endianness::little);
+ support::endian::write(BOS, Range.Flags, llvm::endianness::little);
+ }
+ }
+ }
}
}
assert(Storage.size() == getSize());
diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
index b8ea1b048edfe..6336a42c8e4ae 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -11,6 +11,7 @@
///
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/MC/DXContainerPSVInfo.h"
#include "llvm/MC/DXContainerRootSignature.h"
@@ -301,6 +302,32 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
RS.ParametersContainer.addParameter(Header, Descriptor);
}
break;
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+ mcdxbc::DescriptorTable Table;
+ for (const auto &R : Param.Table.Ranges) {
+ if (RS.Version == 1) {
+ dxbc::RST0::v0::DescriptorRange Range;
+ Range.RangeType = R.RangeType;
+ Range.NumDescriptors = R.NumDescriptors;
+ Range.BaseShaderRegister = R.BaseShaderRegister;
+ Range.RegisterSpace = R.RegisterSpace;
+ Range.OffsetInDescriptorsFromTableStart =
+ R.OffsetInDescriptorsFromTableStart;
+ Table.Ranges.push_back(Range);
+ } else {
+ dxbc::RST0::v1::DescriptorRange Range;
+ Range.RangeType = R.RangeType;
+ Range.NumDescriptors = R.NumDescriptors;
+ Range.BaseShaderRegister = R.BaseShaderRegister;
+ Range.RegisterSpace = R.RegisterSpace;
+ Range.OffsetInDescriptorsFromTableStart =
+ R.OffsetInDescriptorsFromTableStart;
+ Range.Flags = R.getEncodedFlags();
+ Table.Ranges.push_back(Range);
+ }
+ }
+ RS.ParametersContainer.addParameter(Header, Table);
+ } break;
default:
// Handling invalid parameter type edge case
RS.ParametersContainer.addInfo(Header, -1);
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 18c1299d4b867..5ababda9bcdb5 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -125,6 +125,15 @@ uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
return Flag;
}
+uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
+ uint64_t Flag = 0;
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) \
+ if (Val) \
+ Flag |= (uint32_t)dxbc::DescriptorRangeFlag::Val;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ return Flag;
+}
+
uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
uint64_t Flag = 0;
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str) \
@@ -311,6 +320,25 @@ void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
+void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
+ IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
+ IO.mapRequired("RangeType", R.RangeType);
+ IO.mapRequired("NumDescriptors", R.NumDescriptors);
+ IO.mapRequired("BaseShaderRegister", R.BaseShaderRegister);
+ IO.mapRequired("RegisterSpace", R.RegisterSpace);
+ IO.mapRequired("OffsetInDescriptorsFromTableStart",
+ R.OffsetInDescriptorsFromTableStart);
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) IO.mapOptional(#Val, R.Val, false);
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+}
+
+void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
+ IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
+ IO.mapRequired("NumRanges", T.NumRanges);
+ IO.mapOptional("RangesOffset", T.RangesOffset);
+ IO.mapRequired("Ranges", T.Ranges);
+}
+
void MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc>::mapping(
IO &IO, llvm::DXContainerYAML::RootParameterYamlDesc &P) {
IO.mapRequired("ParameterType", P.Type);
@@ -325,6 +353,10 @@ void MappingTraits<llvm::DXContainerYAML::RootParameterYamlDesc>::mapping(
case llvm::to_underlying(dxbc::RootParameterType::UAV):
IO.mapRequired("Descriptor", P.Descriptor);
break;
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
+ IO.mapRequired("Table", P.Table);
+ break;
+ break;
}
}
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
index debb459c3944e..d680bf09ab730 100644
--- a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
@@ -37,6 +37,17 @@ Parts:
ShaderRegister: 31
RegisterSpace: 32
DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+ - ParameterType: 0 # SRV
+ ShaderVisibility: 3 # Domain
+ Table:
+ NumRanges: 1
+ Ranges:
+ - RangeType: 0
+ NumDescriptors: 41
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: -1
+ DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
>From ac51bf60742f2d8880970c7f7f106c9a1b4d105e Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 2 May 2025 00:41:20 +0000
Subject: [PATCH 2/6] adding reading logic
---
llvm/include/llvm/Object/DXContainer.h | 52 +++++++-
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 49 ++++++++
.../ObjectYAML/DXContainerYAMLTest.cpp | 113 ++++++++++++++++++
3 files changed, 212 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index e359d85f08bec..b27312c5697bc 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -19,11 +19,10 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBufferRef.h"
#include "llvm/TargetParser/Triple.h"
-#include <array>
-#include <cstddef>
#include <variant>
namespace llvm {
@@ -169,6 +168,43 @@ struct RootDescriptorView : RootParameterView {
return readParameter<dxbc::RST0::v1::RootDescriptor>();
}
};
+template <typename T> struct DescriptorTable {
+ uint32_t Version;
+ uint32_t NumRanges;
+ uint32_t RangesOffset;
+ ViewArray<T> Ranges;
+
+ typename ViewArray<T>::iterator begin() const { return Ranges.begin(); }
+
+typename ViewArray<T>::iterator end() const { return Ranges.end(); }
+};
+
+template <typename T> struct DescriptorTableView : RootParameterView {
+ using TemplateType = T;
+
+ static bool classof(const RootParameterView *V) {
+ return (V->Header.ParameterType ==
+ llvm::to_underlying(dxbc::RootParameterType::DescriptorTable));
+ }
+
+ // Define a type alias to access the template parameter from inside classof
+ llvm::Expected<DescriptorTable<T>> read() {
+ const char *Current = ParamData.begin();
+ DescriptorTable<T> Table;
+
+ Table.NumRanges =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ Table.RangesOffset =
+ support::endian::read<uint32_t, llvm::endianness::little>(Current);
+ Current += sizeof(uint32_t);
+
+ Table.Ranges.Data =
+ ParamData.substr(2 * sizeof(uint32_t), Table.NumRanges * sizeof(T));
+ return Table;
+ }
+};
static Error parseFailed(const Twine &Msg) {
return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
@@ -221,6 +257,18 @@ class RootSignature {
else
DataSize = sizeof(dxbc::RST0::v1::RootDescriptor);
break;
+ case dxbc::RootParameterType::DescriptorTable:
+ uint32_t NumRanges =
+ support::endian::read<uint32_t, llvm::endianness::little>(
+ PartData.begin() + Header.ParameterOffset);
+ if (Version == 1)
+ DataSize = sizeof(dxbc::RST0::v0::DescriptorRange) * NumRanges +
+ 2 * sizeof(uint32_t);
+ else
+ DataSize = sizeof(dxbc::RST0::v1::DescriptorRange) * NumRanges +
+ 2 * sizeof(uint32_t);
+ break;
+ break;
}
size_t EndOfSectionByte = getNumStaticSamplers() == 0
? PartData.size()
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 5ababda9bcdb5..528fef59b46e4 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -96,6 +96,55 @@ DXContainerYAML::RootSignatureYamlDesc::create(
llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
+ } else if (auto *TDV = dyn_cast<object::DirectX::DescriptorTableView<
+ dxbc::RST0::v0::DescriptorRange>>(&ParamView)) {
+ llvm::Expected<
+ object::DirectX::DescriptorTable<dxbc::RST0::v0::DescriptorRange>>
+ TableOrErr = TDV->read();
+ if (Error E = TableOrErr.takeError())
+ return std::move(E);
+ auto Table = *TableOrErr;
+ NewP.Table.NumRanges = Table.NumRanges;
+ NewP.Table.RangesOffset = Table.RangesOffset;
+
+ for (const auto &R : Table) {
+ DescriptorRangeYaml NewR;
+
+ NewR.OffsetInDescriptorsFromTableStart =
+ R.OffsetInDescriptorsFromTableStart;
+ NewR.NumDescriptors = R.NumDescriptors;
+ NewR.BaseShaderRegister = R.BaseShaderRegister;
+ NewR.RegisterSpace = R.RegisterSpace;
+ NewR.RangeType = R.RangeType;
+
+ NewP.Table.Ranges.push_back(NewR);
+ }
+ } else if (auto *TDV = dyn_cast<object::DirectX::DescriptorTableView<
+ dxbc::RST0::v1::DescriptorRange>>(&ParamView)) {
+ llvm::Expected<
+ object::DirectX::DescriptorTable<dxbc::RST0::v1::DescriptorRange>>
+ TableOrErr = TDV->read();
+ if (Error E = TableOrErr.takeError())
+ return std::move(E);
+ auto Table = *TableOrErr;
+ NewP.Table.NumRanges = Table.NumRanges;
+ NewP.Table.RangesOffset = Table.RangesOffset;
+
+ for (const auto &R : Table) {
+ DescriptorRangeYaml NewR;
+
+ NewR.OffsetInDescriptorsFromTableStart =
+ R.OffsetInDescriptorsFromTableStart;
+ NewR.NumDescriptors = R.NumDescriptors;
+ NewR.BaseShaderRegister = R.BaseShaderRegister;
+ NewR.RegisterSpace = R.RegisterSpace;
+ NewR.RangeType = R.RangeType;
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) \
+ NewR.Val = \
+ (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlag::Val)) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
+ NewP.Table.Ranges.push_back(NewR);
+ }
}
RootSigDesc.Parameters.push_back(NewP);
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index b6a5cee24b29d..494a710af454a 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -354,3 +354,116 @@ TEST(RootSignature, ParseRootDescriptorsV11) {
EXPECT_EQ(Storage.size(), 133u);
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
}
+
+TEST(RootSignature, ParseDescriptorTableV10) {
+ SmallString<128> Storage;
+
+ // First read a fully explicit yaml with all sizes and offsets provided
+ ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+ Header:
+ Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
+ 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+ Version:
+ Major: 1
+ Minor: 0
+ FileSize: 133
+ PartCount: 1
+ PartOffsets: [ 36 ]
+ Parts:
+ - Name: RTS0
+ Size: 89
+ RootSignature:
+ Version: 1
+ NumRootParameters: 1
+ RootParametersOffset: 24
+ NumStaticSamplers: 0
+ StaticSamplersOffset: 60
+ Parameters:
+ - ParameterType: 0 # SRV
+ ShaderVisibility: 3 # Domain
+ Table:
+ NumRanges: 1
+ Ranges:
+ - RangeType: 0
+ NumDescriptors: 41
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: -1
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+ )"));
+
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+ 0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+ 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 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};
+
+ EXPECT_EQ(Storage.size(), 133u);
+ EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
+}
+
+TEST(RootSignature, ParseDescriptorTableV11) {
+ SmallString<128> Storage;
+
+ // First read a fully explicit yaml with all sizes and offsets provided
+ ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
+ Header:
+ Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
+ 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+ Version:
+ Major: 1
+ Minor: 0
+ FileSize: 133
+ PartCount: 1
+ PartOffsets: [ 36 ]
+ Parts:
+ - Name: RTS0
+ Size: 89
+ RootSignature:
+ Version: 2
+ NumRootParameters: 1
+ RootParametersOffset: 24
+ NumStaticSamplers: 0
+ StaticSamplersOffset: 60
+ Parameters:
+ - ParameterType: 0 # SRV
+ ShaderVisibility: 3 # Domain
+ Table:
+ NumRanges: 1
+ Ranges:
+ - RangeType: 0
+ NumDescriptors: 41
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: -1
+ DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+ )"));
+
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+ 0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+ 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00};
+
+ EXPECT_EQ(Storage.size(), 133u);
+ EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
+}
>From 97fb0036bc183dadc122963f1ff6a890ff8cf68a Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 2 May 2025 01:40:34 +0000
Subject: [PATCH 3/6] test pass locally
---
llvm/include/llvm/Object/DXContainer.h | 29 ++++++--
.../include/llvm/ObjectYAML/DXContainerYAML.h | 19 ++---
llvm/lib/ObjectYAML/DXContainerYAML.cpp | 18 ++---
.../RootSignature-MultipleParameters.yaml | 72 +++++++++++--------
4 files changed, 86 insertions(+), 52 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index b27312c5697bc..26764289631a3 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Object/Error.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBufferRef.h"
@@ -38,6 +39,12 @@ template <typename T>
std::enable_if_t<std::is_class<T>::value, void> swapBytes(T &value) {
value.swapBytes();
}
+
+struct TypeIdGenerator {
+ static inline size_t nextId = 0;
+
+ static size_t getNextId() { return nextId++; }
+};
} // namespace detail
// This class provides a view into the underlying resource array. The Resource
@@ -120,8 +127,10 @@ namespace DirectX {
struct RootParameterView {
const dxbc::RootParameterHeader &Header;
StringRef ParamData;
+ uint32_t Version;
+
RootParameterView(uint32_t V, const dxbc::RootParameterHeader &H, StringRef P)
- : Header(H), ParamData(P) {}
+ : Header(H), ParamData(P), Version(V) {}
template <typename T, typename VersionT = T> Expected<T> readParameter() {
assert(sizeof(VersionT) <= sizeof(T) &&
@@ -169,14 +178,25 @@ struct RootDescriptorView : RootParameterView {
}
};
template <typename T> struct DescriptorTable {
- uint32_t Version;
uint32_t NumRanges;
uint32_t RangesOffset;
ViewArray<T> Ranges;
typename ViewArray<T>::iterator begin() const { return Ranges.begin(); }
-typename ViewArray<T>::iterator end() const { return Ranges.end(); }
+ typename ViewArray<T>::iterator end() const { return Ranges.end(); }
+};
+template <typename T> struct TemplateTypeToVersion {
+ // Default version
+ static constexpr uint32_t Value = -1;
+};
+
+template <> struct TemplateTypeToVersion<dxbc::RST0::v0::DescriptorRange> {
+ static constexpr uint32_t Value = 1;
+};
+
+template <> struct TemplateTypeToVersion<dxbc::RST0::v1::DescriptorRange> {
+ static constexpr uint32_t Value = 2;
};
template <typename T> struct DescriptorTableView : RootParameterView {
@@ -184,7 +204,8 @@ template <typename T> struct DescriptorTableView : RootParameterView {
static bool classof(const RootParameterView *V) {
return (V->Header.ParameterType ==
- llvm::to_underlying(dxbc::RootParameterType::DescriptorTable));
+ llvm::to_underlying(dxbc::RootParameterType::DescriptorTable)) &&
+ (V->Version == TemplateTypeToVersion<T>::Value);
}
// Define a type alias to access the template parameter from inside classof
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 738108cc3d1be..9cf0f8df1debf 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -170,39 +170,40 @@ struct RootParameterYamlDesc {
}
}
- RootParameterYamlDesc &operator=(const RootParameterYamlDesc &other) {
- if (this != &other) {
+ RootParameterYamlDesc &operator=(const RootParameterYamlDesc &Other) {
+ if (this != &Other) {
// First, destroy the current union member
this->~RootParameterYamlDesc();
// Copy the basic members
- Type = other.Type;
- Visibility = other.Visibility;
- Offset = other.Offset;
+ Type = Other.Type;
+ Visibility = Other.Visibility;
+ Offset = Other.Offset;
// Initialize the new union member based on the Type from 'other'
switch (Type) {
case llvm::to_underlying(dxbc::RootParameterType::Constants32Bit):
- new (&Constants) RootConstantsYaml(other.Constants);
+ new (&Constants) RootConstantsYaml(Other.Constants);
break;
case llvm::to_underlying(dxbc::RootParameterType::CBV):
case llvm::to_underlying(dxbc::RootParameterType::SRV):
case llvm::to_underlying(dxbc::RootParameterType::UAV):
- new (&Descriptor) RootDescriptorYaml(other.Descriptor);
+ new (&Descriptor) RootDescriptorYaml(Other.Descriptor);
break;
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):
- new (&Table) DescriptorTableYaml(other.Table);
+ new (&Table) DescriptorTableYaml(Other.Table);
break;
}
}
return *this;
}
+ // ToDo: Fix this (Already have a follow up PR with it)
union {
RootConstantsYaml Constants;
RootDescriptorYaml Descriptor;
- DescriptorTableYaml Table;
};
+ DescriptorTableYaml Table;
};
struct RootSignatureYamlDesc {
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 528fef59b46e4..c0a90dd50925c 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -97,9 +97,9 @@ DXContainerYAML::RootSignatureYamlDesc::create(
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
} else if (auto *TDV = dyn_cast<object::DirectX::DescriptorTableView<
- dxbc::RST0::v0::DescriptorRange>>(&ParamView)) {
+ dxbc::RST0::v1::DescriptorRange>>(&ParamView)) {
llvm::Expected<
- object::DirectX::DescriptorTable<dxbc::RST0::v0::DescriptorRange>>
+ object::DirectX::DescriptorTable<dxbc::RST0::v1::DescriptorRange>>
TableOrErr = TDV->read();
if (Error E = TableOrErr.takeError())
return std::move(E);
@@ -116,13 +116,16 @@ DXContainerYAML::RootSignatureYamlDesc::create(
NewR.BaseShaderRegister = R.BaseShaderRegister;
NewR.RegisterSpace = R.RegisterSpace;
NewR.RangeType = R.RangeType;
-
+#define DESCRIPTOR_RANGE_FLAG(Num, Val) \
+ NewR.Val = \
+ (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlag::Val)) > 0;
+#include "llvm/BinaryFormat/DXContainerConstants.def"
NewP.Table.Ranges.push_back(NewR);
}
} else if (auto *TDV = dyn_cast<object::DirectX::DescriptorTableView<
- dxbc::RST0::v1::DescriptorRange>>(&ParamView)) {
+ dxbc::RST0::v0::DescriptorRange>>(&ParamView)) {
llvm::Expected<
- object::DirectX::DescriptorTable<dxbc::RST0::v1::DescriptorRange>>
+ object::DirectX::DescriptorTable<dxbc::RST0::v0::DescriptorRange>>
TableOrErr = TDV->read();
if (Error E = TableOrErr.takeError())
return std::move(E);
@@ -139,10 +142,7 @@ DXContainerYAML::RootSignatureYamlDesc::create(
NewR.BaseShaderRegister = R.BaseShaderRegister;
NewR.RegisterSpace = R.RegisterSpace;
NewR.RangeType = R.RangeType;
-#define DESCRIPTOR_RANGE_FLAG(Num, Val) \
- NewR.Val = \
- (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlag::Val)) > 0;
-#include "llvm/BinaryFormat/DXContainerConstants.def"
+
NewP.Table.Ranges.push_back(NewR);
}
}
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
index d680bf09ab730..50cf7950be8aa 100644
--- a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
@@ -11,7 +11,7 @@ Header:
PartOffsets: [ 60 ]
Parts:
- Name: RTS0
- Size: 96
+ Size: 200
RootSignature:
Version: 2
NumRootParameters: 3
@@ -51,32 +51,44 @@ Parts:
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
-# CHECK: - Name: RTS0
-# CHECK-NEXT: Size: 96
-# CHECK-NEXT: RootSignature:
-# CHECK-NEXT: Version: 2
-# CHECK-NEXT: NumRootParameters: 3
-# CHECK-NEXT: RootParametersOffset: 24
-# CHECK-NEXT: NumStaticSamplers: 0
-# CHECK-NEXT: StaticSamplersOffset: 60
-# CHECK-NEXT: Parameters:
-# CHECK-NEXT: - ParameterType: 1
-# CHECK-NEXT: ShaderVisibility: 2
-# CHECK-NEXT: Constants:
-# CHECK-NEXT: Num32BitValues: 16
-# CHECK-NEXT: RegisterSpace: 14
-# CHECK-NEXT: ShaderRegister: 15
-# CHECK-NEXT: - ParameterType: 1
-# CHECK-NEXT: ShaderVisibility: 4
-# CHECK-NEXT: Constants:
-# CHECK-NEXT: Num32BitValues: 21
-# CHECK-NEXT: RegisterSpace: 23
-# CHECK-NEXT: ShaderRegister: 22
-# CHECK-NEXT: - ParameterType: 2
-# CHECK-NEXT: ShaderVisibility: 3
-# CHECK-NEXT: Descriptor:
-# CHECK-NEXT: RegisterSpace: 32
-# CHECK-NEXT: ShaderRegister: 31
-# CHECK-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
-# CHECK-NEXT: AllowInputAssemblerInputLayout: true
-# CHECK-NEXT: DenyGeometryShaderRootAccess: true
+#CHECK: - Name: RTS0
+#CHECK-NEXT: Size: 200
+#CHECK-NEXT: RootSignature:
+#CHECK-NEXT: Version: 2
+#CHECK-NEXT: NumRootParameters: 4
+#CHECK-NEXT: RootParametersOffset: 24
+#CHECK-NEXT: NumStaticSamplers: 0
+#CHECK-NEXT: StaticSamplersOffset: 60
+#CHECK-NEXT: Parameters:
+#CHECK-NEXT: - ParameterType: 1
+#CHECK-NEXT: ShaderVisibility: 2
+#CHECK-NEXT: Constants:
+#CHECK-NEXT: Num32BitValues: 16
+#CHECK-NEXT: RegisterSpace: 14
+#CHECK-NEXT: ShaderRegister: 15
+#CHECK-NEXT: - ParameterType: 1
+#CHECK-NEXT: ShaderVisibility: 4
+#CHECK-NEXT: Constants:
+#CHECK-NEXT: Num32BitValues: 21
+#CHECK-NEXT: RegisterSpace: 23
+#CHECK-NEXT: ShaderRegister: 22
+#CHECK-NEXT: - ParameterType: 2
+#CHECK-NEXT: ShaderVisibility: 3
+#CHECK-NEXT: Descriptor:
+#CHECK-NEXT: RegisterSpace: 32
+#CHECK-NEXT: ShaderRegister: 31
+#CHECK-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+#CHECK-NEXT: - ParameterType: 0
+#CHECK-NEXT: ShaderVisibility: 3
+#CHECK-NEXT: Table:
+#CHECK-NEXT: NumRanges: 1
+#CHECK-NEXT: RangesOffset: 116
+#CHECK-NEXT: Ranges:
+#CHECK-NEXT: - RangeType: 0
+#CHECK-NEXT: NumDescriptors: 41
+#CHECK-NEXT: BaseShaderRegister: 42
+#CHECK-NEXT: RegisterSpace: 43
+#CHECK-NEXT: OffsetInDescriptorsFromTableStart: -1
+#CHECK-NEXT: DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
+#CHECK-NEXT: AllowInputAssemblerInputLayout: true
+#CHECK-NEXT: DenyGeometryShaderRootAccess: true
>From 93e04bd0e8e072ad761bdb53b9afd08de7358102 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 2 May 2025 16:55:47 +0000
Subject: [PATCH 4/6] adding tests
---
llvm/unittests/Object/DXContainerTest.cpp | 108 ++++++++++++++++++
.../ObjectYAML/DXContainerYAMLTest.cpp | 2 +-
2 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index 72f860a5039ff..b01b8ad2bad44 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -8,6 +8,7 @@
#include "llvm/Object/DXContainer.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/ObjectYAML/DXContainerYAML.h"
#include "llvm/ObjectYAML/yaml2obj.h"
@@ -1050,3 +1051,110 @@ TEST(RootSignature, ParseRootDescriptor) {
ASSERT_EQ(Descriptor->Flags, 4u);
}
}
+
+TEST(RootSignature, ParseDescriptorTable) {
+ {
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+ 0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+ 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00};
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
+
+ auto MaybeRS = C.getRootSignature();
+ ASSERT_TRUE(MaybeRS.has_value());
+ const auto &RS = MaybeRS.value();
+ ASSERT_EQ(RS.getVersion(), 2u);
+ ASSERT_EQ(RS.getNumParameters(), 1u);
+ ASSERT_EQ(RS.getRootParametersOffset(), 24u);
+ ASSERT_EQ(RS.getNumStaticSamplers(), 0u);
+ ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);
+ ASSERT_EQ(RS.getFlags(), 17u);
+
+ auto RootParam = *RS.param_headers().begin();
+ ASSERT_EQ((unsigned)RootParam.ParameterType, 0u);
+ ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);
+ auto ParamView = RS.getParameter(RootParam);
+ ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
+
+ auto *DescriptorTableView =
+ dyn_cast<DirectX::DescriptorTableView<dxbc::RST0::v1::DescriptorRange>>(
+ &*ParamView);
+ ASSERT_TRUE(DescriptorTableView != nullptr);
+ auto Table = DescriptorTableView->read();
+
+ ASSERT_THAT_ERROR(Table.takeError(), Succeeded());
+
+ ASSERT_EQ(Table->NumRanges, 1u);
+
+ auto Range = *Table->begin();
+
+ ASSERT_EQ(Range.RangeType, 0u);
+ ASSERT_EQ(Range.NumDescriptors, 41u);
+ ASSERT_EQ(Range.BaseShaderRegister, 42u);
+ ASSERT_EQ(Range.RegisterSpace, 43u);
+ ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, -1);
+ ASSERT_EQ(Range.Flags, 65536u);
+ }
+
+ {
+ uint8_t Buffer[] = {
+ 0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
+ 0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
+ 0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
+ 0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+ 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};
+ DXContainer C =
+ llvm::cantFail(DXContainer::create(getMemoryBuffer<133>(Buffer)));
+
+ auto MaybeRS = C.getRootSignature();
+ ASSERT_TRUE(MaybeRS.has_value());
+ const auto &RS = MaybeRS.value();
+ ASSERT_EQ(RS.getVersion(), 1u);
+ ASSERT_EQ(RS.getNumParameters(), 1u);
+ ASSERT_EQ(RS.getRootParametersOffset(), 24u);
+ ASSERT_EQ(RS.getNumStaticSamplers(), 0u);
+ ASSERT_EQ(RS.getStaticSamplersOffset(), 60u);
+ ASSERT_EQ(RS.getFlags(), 17u);
+
+ auto RootParam = *RS.param_headers().begin();
+ ASSERT_EQ((unsigned)RootParam.ParameterType, 0u);
+ ASSERT_EQ((unsigned)RootParam.ShaderVisibility, 3u);
+ auto ParamView = RS.getParameter(RootParam);
+ ASSERT_THAT_ERROR(ParamView.takeError(), Succeeded());
+
+ auto *DescriptorTableView =
+ dyn_cast<DirectX::DescriptorTableView<dxbc::RST0::v0::DescriptorRange>>(
+ &*ParamView);
+ ASSERT_TRUE(DescriptorTableView != nullptr);
+ auto Table = DescriptorTableView->read();
+
+ ASSERT_THAT_ERROR(Table.takeError(), Succeeded());
+
+ ASSERT_EQ(Table->NumRanges, 1u);
+
+ auto Range = *Table->begin();
+
+ ASSERT_EQ(Range.RangeType, 0u);
+ ASSERT_EQ(Range.NumDescriptors, 41u);
+ ASSERT_EQ(Range.BaseShaderRegister, 42u);
+ ASSERT_EQ(Range.RegisterSpace, 43u);
+ ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, -1);
+ }
+}
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index 494a710af454a..fa3af7045a4fd 100644
--- a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
+++ b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
@@ -435,7 +435,7 @@ TEST(RootSignature, ParseDescriptorTableV11) {
NumStaticSamplers: 0
StaticSamplersOffset: 60
Parameters:
- - ParameterType: 0 # SRV
+ - ParameterType: 0 # Descriptor Table
ShaderVisibility: 3 # Domain
Table:
NumRanges: 1
>From 2f6d579c9588338d7677a13f243896ffc972b944 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 2 May 2025 17:32:10 +0000
Subject: [PATCH 5/6] adding more tests
---
.../RootSignature-DescriptorTable1.0.yaml | 57 ++++++++++++++++++
.../RootSignature-DescriptorTable1.1.yaml | 59 +++++++++++++++++++
2 files changed, 116 insertions(+)
create mode 100644 llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
create mode 100644 llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
new file mode 100644
index 0000000000000..f431afa3cd3d3
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
@@ -0,0 +1,57 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !dxcontainer
+Header:
+ Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
+ 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+ Version:
+ Major: 1
+ Minor: 0
+ FileSize: 133
+ PartCount: 1
+ PartOffsets: [ 36 ]
+Parts:
+- Name: RTS0
+ Size: 89
+ RootSignature:
+ Version: 1
+ NumRootParameters: 1
+ RootParametersOffset: 24
+ NumStaticSamplers: 0
+ StaticSamplersOffset: 60
+ Parameters:
+ - ParameterType: 0 # SRV
+ ShaderVisibility: 3 # Domain
+ Table:
+ NumRanges: 1
+ Ranges:
+ - RangeType: 0
+ NumDescriptors: 41
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: -1
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+
+# CHECK: - Name: RTS0
+# CHECK-NEXT: Size: 89
+# CHECK-NEXT: RootSignature:
+# CHECK-NEXT: Version: 1
+# CHECK-NEXT: NumRootParameters: 1
+# CHECK-NEXT: RootParametersOffset: 24
+# CHECK-NEXT: NumStaticSamplers: 0
+# CHECK-NEXT: StaticSamplersOffset: 60
+# CHECK-NEXT: Parameters:
+# CHECK-NEXT: - ParameterType: 0
+# CHECK-NEXT: ShaderVisibility: 3
+# CHECK-NEXT: Table:
+# CHECK-NEXT: NumRanges: 1
+# CHECK-NEXT: RangesOffset: 44
+# CHECK-NEXT: Ranges:
+# CHECK-NEXT: - RangeType: 0
+# CHECK-NEXT: NumDescriptors: 41
+# CHECK-NEXT: BaseShaderRegister: 42
+# CHECK-NEXT: RegisterSpace: 43
+# CHECK-NEXT: OffsetInDescriptorsFromTableStart: -1
+# CHECK-NEXT: AllowInputAssemblerInputLayout: true
+# CHECK-NEXT: DenyGeometryShaderRootAccess: true
diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml
new file mode 100644
index 0000000000000..54899cae57bf9
--- /dev/null
+++ b/llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml
@@ -0,0 +1,59 @@
+# RUN: yaml2obj %s | obj2yaml | FileCheck %s
+
+--- !dxcontainer
+Header:
+ Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
+ 0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
+ Version:
+ Major: 1
+ Minor: 0
+ FileSize: 133
+ PartCount: 1
+ PartOffsets: [ 36 ]
+Parts:
+- Name: RTS0
+ Size: 89
+ RootSignature:
+ Version: 2
+ NumRootParameters: 1
+ RootParametersOffset: 24
+ NumStaticSamplers: 0
+ StaticSamplersOffset: 60
+ Parameters:
+ - ParameterType: 0 # SRV
+ ShaderVisibility: 3 # Domain
+ Table:
+ NumRanges: 1
+ Ranges:
+ - RangeType: 0
+ NumDescriptors: 41
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: -1
+ DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+ AllowInputAssemblerInputLayout: true
+ DenyGeometryShaderRootAccess: true
+
+# CHECK: - Name: RTS0
+# CHECK-NEXT: Size: 89
+# CHECK-NEXT: RootSignature:
+# CHECK-NEXT: Version: 2
+# CHECK-NEXT: NumRootParameters: 1
+# CHECK-NEXT: RootParametersOffset: 24
+# CHECK-NEXT: NumStaticSamplers: 0
+# CHECK-NEXT: StaticSamplersOffset: 60
+# CHECK-NEXT: Parameters:
+# CHECK-NEXT: - ParameterType: 0
+# CHECK-NEXT: ShaderVisibility: 3
+# CHECK-NEXT: Table:
+# CHECK-NEXT: NumRanges: 1
+# CHECK-NEXT: RangesOffset: 44
+# CHECK-NEXT: Ranges:
+# CHECK-NEXT: - RangeType: 0
+# CHECK-NEXT: NumDescriptors: 41
+# CHECK-NEXT: BaseShaderRegister: 42
+# CHECK-NEXT: RegisterSpace: 43
+# CHECK-NEXT: OffsetInDescriptorsFromTableStart: -1
+# CHECK-NEXT: DATA_STATIC_WHILE_SET_AT_EXECUTE: true
+# CHECK-NEXT: AllowInputAssemblerInputLayout: true
+# CHECK-NEXT: DenyGeometryShaderRootAccess: true
>From 76b1b75856b109490616cf1c2df5bc02d67e8d02 Mon Sep 17 00:00:00 2001
From: joaosaffran <joao.saffran at microsoft.com>
Date: Fri, 2 May 2025 17:51:03 +0000
Subject: [PATCH 6/6] clean up
---
llvm/include/llvm/Object/DXContainer.h | 6 ------
llvm/unittests/Object/DXContainerTest.cpp | 1 -
2 files changed, 7 deletions(-)
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 26764289631a3..c6c22213d7de8 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -40,11 +40,6 @@ std::enable_if_t<std::is_class<T>::value, void> swapBytes(T &value) {
value.swapBytes();
}
-struct TypeIdGenerator {
- static inline size_t nextId = 0;
-
- static size_t getNextId() { return nextId++; }
-};
} // namespace detail
// This class provides a view into the underlying resource array. The Resource
@@ -289,7 +284,6 @@ class RootSignature {
DataSize = sizeof(dxbc::RST0::v1::DescriptorRange) * NumRanges +
2 * sizeof(uint32_t);
break;
- break;
}
size_t EndOfSectionByte = getNumStaticSamplers() == 0
? PartData.size()
diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp
index b01b8ad2bad44..955b832459879 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -8,7 +8,6 @@
#include "llvm/Object/DXContainer.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/ObjectYAML/DXContainerYAML.h"
#include "llvm/ObjectYAML/yaml2obj.h"
More information about the llvm-branch-commits
mailing list