diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h index 82890bf814935..2f1a9fe2e8f93 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> getRootParameterTypes(); +#define DESCRIPTOR_RANGE(Val, Enum) Enum = Val, +enum class DescriptorRangeType : uint32_t { +#include "DXContainerConstants.def" +}; + +ArrayRef> 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 v1 namespace v2 { @@ -610,6 +637,14 @@ struct RootDescriptor : public v1::RootDescriptor { sys::swapByteOrder(Flags); } }; + +struct DescriptorRange : public v1::DescriptorRange { + uint32_t Flags; + void swapBytes() { + v1::DescriptorRange::swapBytes(); + sys::swapByteOrder(Flags); + } +}; } // namespace v2 } // namespace RTS0 // following dx12 naming diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def index 81d2c54b6e07c..065b8c95eda10 100644 --- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def +++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def @@ -86,8 +86,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) @@ -95,6 +108,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 3496b5fff398f..5abcf1710e8ee 100644 --- a/llvm/include/llvm/MC/DXContainerRootSignature.h +++ b/llvm/include/llvm/MC/DXContainerRootSignature.h @@ -6,9 +6,12 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/STLForwardCompat.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/BinaryFormat/DXContainer.h" #include #include +#include namespace llvm { @@ -25,11 +28,25 @@ struct RootParameterInfo { : Header(Header), Location(Location) {} }; + +struct DescriptorTable { + SmallVector Ranges; + + SmallVector::const_iterator begin() const { + return Ranges.begin(); + } + SmallVector::const_iterator end() const { + return Ranges.end(); + } +}; + + + struct RootParametersContainer { SmallVector ParametersInfo; - SmallVector Constants; SmallVector Descriptors; + SmallVector Tables; void addInfo(dxbc::RootParameterHeader Header, size_t Location) { ParametersInfo.push_back(RootParameterInfo(Header, Location)); @@ -51,6 +68,11 @@ struct RootParametersContainer { Descriptors.push_back(Descriptor); } + void addParameter(dxbc::RootParameterHeader H, DescriptorTable D) { + addInfo(H, Tables.size()); + Tables.push_back(D); + } + const std::pair getTypeAndLocForParameter(uint32_t Location) const { const RootParameterInfo &Info = ParametersInfo[Location]; @@ -69,6 +91,9 @@ struct RootParametersContainer { const dxbc::RTS0::v2::RootDescriptor &getRootDescriptor(size_t Index) const { return Descriptors[Index]; } + const DescriptorTable &getDescriptorTable(size_t Index) const { + return Tables[Index]; + } size_t size() const { return ParametersInfo.size(); } diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h index 61bfa9411cc57..8908719640e63 100644 --- a/llvm/include/llvm/Object/DXContainer.h +++ b/llvm/include/llvm/Object/DXContainer.h @@ -20,11 +20,11 @@ #include "llvm/ADT/Twine.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" #include "llvm/TargetParser/Triple.h" -#include -#include #include #include @@ -41,6 +41,7 @@ template std::enable_if_t::value, void> swapBytes(T &value) { value.swapBytes(); } + } // namespace detail // This class provides a view into the underlying resource array. The Resource @@ -177,6 +178,46 @@ struct RootDescriptorView : RootParameterView { } }; +struct DescriptorTable { + uint32_t NumRanges; + uint32_t RangesOffset; + ViewArray Ranges; + + typename ViewArray::iterator begin() const { return Ranges.begin(); } + + typename ViewArray::iterator end() const { return Ranges.end(); } +}; + +struct DescriptorTableView : RootParameterView { + 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 read(uint32_t Version) { + const char *Current = ParamData.begin(); + DescriptorTable Table; + + Table.NumRanges = + support::endian::read(Current); + Current += sizeof(uint32_t); + + Table.RangesOffset = + support::endian::read(Current); + Current += sizeof(uint32_t); + + size_t RangeSize = sizeof(dxbc::RTS0::v1::DescriptorRange); + if(Version > 1) + RangeSize = sizeof(dxbc::RTS0::v2::DescriptorRange); + + Table.Ranges.Stride = RangeSize; + Table.Ranges.Data = + ParamData.substr(2 * sizeof(uint32_t), Table.NumRanges * RangeSize); + return Table; + } +}; + static Error parseFailed(const Twine &Msg) { return make_error(Msg.str(), object_error::parse_failed); } @@ -228,6 +269,17 @@ class RootSignature { else DataSize = sizeof(dxbc::RTS0::v2::RootDescriptor); break; + case dxbc::RootParameterType::DescriptorTable: + uint32_t NumRanges = + support::endian::read( + PartData.begin() + Header.ParameterOffset); + if (Version == 1) + DataSize = sizeof(dxbc::RTS0::v1::DescriptorRange) * NumRanges + + 2 * sizeof(uint32_t); + else + DataSize = sizeof(dxbc::RTS0::v2::DescriptorRange) * NumRanges + + 2 * sizeof(uint32_t); + break; } size_t EndOfSectionByte = getNumStaticSamplers() == 0 ? PartData.size() diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h index 73532fa392520..ced8c9583d6ad 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" @@ -90,6 +92,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 Ranges; +}; + struct RootParameterYamlDesc { uint32_t Type; uint32_t Visibility; @@ -106,13 +127,82 @@ 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; + } + + // ToDo: Fix this (Already have a follow up PR with it) union { RootConstantsYaml Constants; RootDescriptorYaml Descriptor; }; + DescriptorTableYaml Table; }; struct RootSignatureYamlDesc { @@ -243,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) @@ -327,6 +418,14 @@ template <> struct MappingTraits { static void mapping(IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D); }; +template <> struct MappingTraits { + static void mapping(IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &D); +}; + +template <> struct MappingTraits { + 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 a9394541d18da..116ada468582c 100644 --- a/llvm/lib/MC/DXContainerRootSignature.cpp +++ b/llvm/lib/MC/DXContainerRootSignature.cpp @@ -7,7 +7,9 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/DXContainerRootSignature.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallString.h" +#include "llvm/BinaryFormat/DXContainer.h" #include "llvm/Support/EndianStream.h" using namespace llvm; @@ -46,6 +48,15 @@ size_t RootSignatureDesc::getSize() const { Size += sizeof(dxbc::RTS0::v2::RootDescriptor); break; + case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): + const DescriptorTable &Table = ParametersContainer.getDescriptorTable(I.Location); + if (Version == 1) + Size += + sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size() + 8; + else + Size += + sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size() + 8; + break; } } return Size; @@ -89,8 +100,8 @@ void RootSignatureDesc::write(raw_ostream &OS) const { llvm::endianness::little); support::endian::write(BOS, Constants.Num32BitValues, llvm::endianness::little); - break; - } + } + break; case llvm::to_underlying(dxbc::RootParameterType::CBV): case llvm::to_underlying(dxbc::RootParameterType::SRV): case llvm::to_underlying(dxbc::RootParameterType::UAV): { @@ -103,8 +114,30 @@ void RootSignatureDesc::write(raw_ostream &OS) const { llvm::endianness::little); if (Version > 1) support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little); - break; } + break; + case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable):{ + const DescriptorTable &Table = + ParametersContainer.getDescriptorTable(Loc); + support::endian::write(BOS, (uint32_t)Table.Ranges.size(), + llvm::endianness::little); + rewriteOffsetToCurrentByte(BOS, writePlaceholder(BOS)); + for (const auto &Range : Table) { + 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); + if(Version > 1) + support::endian::write(BOS, Range.Flags, + llvm::endianness::little); + } + } break; } } assert(Storage.size() == getSize()); diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp index c00cd3e08d59d..13ee8758e363d 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" @@ -295,6 +296,23 @@ void DXContainerWriter::writeParts(raw_ostream &OS) { Descriptor.Flags = Param.Descriptor.getEncodedFlags(); RS.ParametersContainer.addParameter(Header, Descriptor); break; + case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): { + mcdxbc::DescriptorTable Table; + for (const auto &R : Param.Table.Ranges) { + + dxbc::RTS0::v2::DescriptorRange Range; + Range.RangeType = R.RangeType; + Range.NumDescriptors = R.NumDescriptors; + Range.BaseShaderRegister = R.BaseShaderRegister; + Range.RegisterSpace = R.RegisterSpace; + Range.OffsetInDescriptorsFromTableStart = + R.OffsetInDescriptorsFromTableStart; + if (RS.Version > 1) + Range.Flags = R.getEncodedFlags(); + Table.Ranges.push_back(Range); + } + RS.ParametersContainer.addParameter(Header, Table); + } break; default: // Handling invalid parameter type edge case. We intentionally let // obj2yaml/yaml2obj parse and emit invalid dxcontainer data, in order @@ -304,7 +322,6 @@ void DXContainerWriter::writeParts(raw_ostream &OS) { } RS.write(OS); - break; } uint64_t BytesWritten = OS.tell() - DataStart; RollingOffset += BytesWritten; diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp index 8964c913946f2..64c9335caa495 100644 --- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp +++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp @@ -95,7 +95,32 @@ DXContainerYAML::RootSignatureYamlDesc::create( llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0; #include "llvm/BinaryFormat/DXContainerConstants.def" } + } else if (auto *TDV = dyn_cast(&ParamView)) { + llvm::ExpectedTableOrErr = TDV->read(Version); + 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; + if (Version > 1) { +#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); } @@ -124,6 +149,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) \ @@ -310,6 +344,25 @@ void MappingTraits::mapping( #include "llvm/BinaryFormat/DXContainerConstants.def" } +void MappingTraits::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::mapping( + IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) { + IO.mapRequired("NumRanges", T.NumRanges); + IO.mapOptional("RangesOffset", T.RangesOffset); + IO.mapRequired("Ranges", T.Ranges); +} + void MappingTraits::mapping( IO &IO, llvm::DXContainerYAML::RootParameterYamlDesc &P) { IO.mapRequired("ParameterType", P.Type); @@ -324,6 +377,10 @@ void MappingTraits::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-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 diff --git a/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml b/llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml index debb459c3944e..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 @@ -37,35 +37,58 @@ 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 -# 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 diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp index 72f860a5039ff..d33a4264e1b14 100644 --- a/llvm/unittests/Object/DXContainerTest.cpp +++ b/llvm/unittests/Object/DXContainerTest.cpp @@ -1050,3 +1050,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( + &*ParamView); + ASSERT_TRUE(DescriptorTableView != nullptr); + auto Table = DescriptorTableView->read(2); + + 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( + &*ParamView); + ASSERT_TRUE(DescriptorTableView != nullptr); + auto Table = DescriptorTableView->read(1); + + 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 b6a5cee24b29d..fa3af7045a4fd 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 # Descriptor Table + 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); +}