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.saff...@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.saff...@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.saff...@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.saff...@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.saff...@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.saff...@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" _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits