diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h --- a/llvm/include/llvm/BinaryFormat/DXContainer.h +++ b/llvm/include/llvm/BinaryFormat/DXContainer.h @@ -20,6 +20,7 @@ #include namespace llvm { +template struct EnumEntry; // The DXContainer file format is arranged as a header and "parts". Semantically // parts are similar to sections in other object file formats. The File format @@ -273,6 +274,27 @@ namespace PSV { +#define SEMANTIC_KIND(Val, Enum) Enum = Val, +enum class SemanticKind : uint8_t { +#include "DXContainerConstants.def" +}; + +ArrayRef> getSemanticKinds(); + +#define COMPONENT_TYPE(Val, Enum) Enum = Val, +enum class ComponentType : uint8_t { +#include "DXContainerConstants.def" +}; + +ArrayRef> getComponentTypes(); + +#define INTERPOLATION_MODE(Val, Enum) Enum = Val, +enum class InterpolationMode : uint8_t { +#include "DXContainerConstants.def" +}; + +ArrayRef> getInterpolationModes(); + namespace v0 { struct RuntimeInfo { PipelinePSVInfo StageInfo; @@ -302,6 +324,34 @@ } }; +struct SignatureElement { + uint32_t NameOffset; + uint32_t IndicesOffset; + + uint8_t Rows; + uint8_t StartRow; + uint8_t Cols : 4; + uint8_t StartCol : 2; + uint8_t Allocated : 1; + uint8_t Unused : 1; + SemanticKind Kind; + + ComponentType Type; + InterpolationMode Mode; + uint8_t DynamicMask : 4; + uint8_t Stream : 2; + uint8_t Unused2 : 2; + uint8_t Reserved; + + void swapBytes() { + sys::swapByteOrder(NameOffset); + sys::swapByteOrder(IndicesOffset); + } +}; + +static_assert(sizeof(SignatureElement) == 4 * sizeof(uint32_t), + "PSV Signature elements must fit in 16 bytes."); + } // namespace v0 namespace v1 { @@ -326,7 +376,7 @@ // PSVSignatureElement counts uint8_t SigInputElements; uint8_t SigOutputElements; - uint8_t SigPatchConstOrPrimElements; + uint8_t SigPatchOrPrimElements; // Number of packed vectors per signature uint8_t SigInputVectors; diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def --- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def +++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def @@ -46,3 +46,72 @@ #undef SHADER_FLAG #endif + +#ifdef SEMANTIC_KIND + +SEMANTIC_KIND(0, Arbitrary) +SEMANTIC_KIND(1, VertexID) +SEMANTIC_KIND(2, InstanceID) +SEMANTIC_KIND(3, Position) +SEMANTIC_KIND(4, RenderTargetArrayIndex) +SEMANTIC_KIND(5, ViewPortArrayIndex) +SEMANTIC_KIND(6, ClipDistance) +SEMANTIC_KIND(7, CullDistance) +SEMANTIC_KIND(8, OutputControlPointID) +SEMANTIC_KIND(9, DomainLocation) +SEMANTIC_KIND(10, PrimitiveID) +SEMANTIC_KIND(11, GSInstanceID) +SEMANTIC_KIND(12, SampleIndex) +SEMANTIC_KIND(13, IsFrontFace) +SEMANTIC_KIND(14, Coverage) +SEMANTIC_KIND(15, InnerCoverage) +SEMANTIC_KIND(16, Target) +SEMANTIC_KIND(17, Depth) +SEMANTIC_KIND(18, DepthLessEqual) +SEMANTIC_KIND(19, DepthGreaterEqual) +SEMANTIC_KIND(20, StencilRef) +SEMANTIC_KIND(21, DispatchThreadID) +SEMANTIC_KIND(22, GroupID) +SEMANTIC_KIND(23, GroupIndex) +SEMANTIC_KIND(24, GroupThreadID) +SEMANTIC_KIND(25, TessFactor) +SEMANTIC_KIND(26, InsideTessFactor) +SEMANTIC_KIND(27, ViewID) +SEMANTIC_KIND(28, Barycentrics) +SEMANTIC_KIND(29, ShadingRate) +SEMANTIC_KIND(30, CullPrimitive) +SEMANTIC_KIND(30, Invalid) + +#undef SEMANTIC_KIND +#endif + +#ifdef COMPONENT_TYPE + +COMPONENT_TYPE(0, Unknown) +COMPONENT_TYPE(1, UInt32) +COMPONENT_TYPE(2, SInt32) +COMPONENT_TYPE(3, Float32) +COMPONENT_TYPE(4, UInt16) +COMPONENT_TYPE(5, SInt16) +COMPONENT_TYPE(6, Float16) +COMPONENT_TYPE(7, UInt64) +COMPONENT_TYPE(8, SInt64) +COMPONENT_TYPE(9, Float64) + +#undef COMPONENT_TYPE +#endif + +#ifdef INTERPOLATION_MODE + +INTERPOLATION_MODE(0, Undefined) +INTERPOLATION_MODE(1, Constant) +INTERPOLATION_MODE(2, Linear) +INTERPOLATION_MODE(3, LinearCentroid) +INTERPOLATION_MODE(4, LinearNoperspective) +INTERPOLATION_MODE(5, LinearNoperspectiveCentroid) +INTERPOLATION_MODE(6, LinearSample) +INTERPOLATION_MODE(7, LinearNoperspectiveSample) +INTERPOLATION_MODE(8, Invalid) + +#undef INTERPOLATION_MODE +#endif diff --git a/llvm/include/llvm/MC/DXContainerPSVInfo.h b/llvm/include/llvm/MC/DXContainerPSVInfo.h --- a/llvm/include/llvm/MC/DXContainerPSVInfo.h +++ b/llvm/include/llvm/MC/DXContainerPSVInfo.h @@ -9,18 +9,34 @@ #ifndef LLVM_MC_DXCONTAINERPSVINFO_H #define LLVM_MC_DXCONTAINERPSVINFO_H +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/DXContainer.h" #include "llvm/TargetParser/Triple.h" #include #include -#include namespace llvm { class raw_ostream; namespace mcdxbc { + +struct PSVSignatureElement { + StringRef Name; + SmallVector Indices; + uint8_t StartRow; + uint8_t Cols; + uint8_t StartCol; + bool Allocated; + dxbc::PSV::SemanticKind Kind; + dxbc::PSV::ComponentType Type; + dxbc::PSV::InterpolationMode Mode; + uint8_t DynamicMask; + uint8_t Stream; +}; + // This data structure is a helper for reading and writing PSV RuntimeInfo data. // It is implemented in the BinaryFormat library so that it can be used by both // the MC layer and Object tools. @@ -28,8 +44,12 @@ // modifiable format, and can be used to serialize the data back into valid PSV // RuntimeInfo. struct PSVRuntimeInfo { + bool IsFinalized = false; dxbc::PSV::v2::RuntimeInfo BaseData; - std::vector Resources; + SmallVector Resources; + SmallVector InputElements; + SmallVector OutputElements; + SmallVector PatchOrPrimElements; // Serialize PSVInfo into the provided raw_ostream. The version field // specifies the data version to encode, the default value specifies encoding @@ -37,7 +57,14 @@ void write(raw_ostream &OS, uint32_t Version = std::numeric_limits::max()) const; - void swapBytes(Triple::EnvironmentType Stage) { + void finalize(Triple::EnvironmentType Stage) { + IsFinalized = true; + BaseData.SigInputElements = static_cast(InputElements.size()); + BaseData.SigOutputElements = static_cast(OutputElements.size()); + BaseData.SigPatchOrPrimElements = + static_cast(PatchOrPrimElements.size()); + if (!sys::IsBigEndianHost) + return; BaseData.swapBytes(); BaseData.swapBytes(Stage); for (auto &Res : Resources) diff --git a/llvm/include/llvm/MC/StringTableBuilder.h b/llvm/include/llvm/MC/StringTableBuilder.h --- a/llvm/include/llvm/MC/StringTableBuilder.h +++ b/llvm/include/llvm/MC/StringTableBuilder.h @@ -32,7 +32,8 @@ MachO64Linked, RAW, DWARF, - XCOFF + XCOFF, + DXContainer }; private: diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h --- a/llvm/include/llvm/Object/DXContainer.h +++ b/llvm/include/llvm/Object/DXContainer.h @@ -33,14 +33,14 @@ // data is little-endian encoded and may not be properly aligned to read // directly from. The dereference operator creates a copy of the data and byte // swaps it as appropriate. - struct ResourceArray { + template struct ViewArray { StringRef Data; uint32_t Stride; // size of each element in the list. - ResourceArray() = default; - ResourceArray(StringRef D, size_t S) : Data(D), Stride(S) {} + ViewArray() = default; + ViewArray(StringRef D, size_t S) : Data(D), Stride(S) {} - using value_type = dxbc::PSV::v2::ResourceBindInfo; + using value_type = T; static constexpr uint32_t MaxStride() { return static_cast(sizeof(value_type)); } @@ -50,7 +50,7 @@ uint32_t Stride; // size of each element in the list. const char *Current; - iterator(const ResourceArray &A, const char *C) + iterator(const ViewArray &A, const char *C) : Data(A.Data), Stride(A.Stride), Current(C) {} iterator(const iterator &) = default; @@ -58,7 +58,8 @@ // Explicitly zero the structure so that unused fields are zeroed. It is // up to the user to know if the fields are used by verifying the PSV // version. - value_type Val = {{0, 0, 0, 0}, 0, 0}; + value_type Val; + std::memset(&Val, 0, sizeof(value_type)); if (Current >= Data.end()) return Val; memcpy(static_cast(&Val), Current, @@ -103,6 +104,9 @@ size_t size() const { return Data.size() / Stride; } }; + using ResourceArray = ViewArray; + using SigElementArray = ViewArray; + StringRef Data; uint32_t Size; using InfoStruct = @@ -110,6 +114,11 @@ dxbc::PSV::v1::RuntimeInfo, dxbc::PSV::v2::RuntimeInfo>; InfoStruct BasicInfo; ResourceArray Resources; + StringRef StringTable; + SmallVector SemanticIndexTable; + SigElementArray SigInputElements; + SigElementArray SigOutputElements; + SigElementArray SigPatchOrPrimElements; public: PSVRuntimeInfo(StringRef D) : Data(D), Size(0) {} @@ -130,6 +139,23 @@ uint32_t getResourceStride() const { return Resources.Stride; } const InfoStruct &getInfo() const { return BasicInfo; } + + StringRef getStringTable() const { return StringTable; } + ArrayRef getSemanticIndexTable() const { + return SemanticIndexTable; + } + + uint8_t getSigInputCount() const; + uint8_t getSigOutputCount() const; + uint8_t getSigPatchOrPrimCount() const; + + SigElementArray getSigInputElements() const { return SigInputElements; } + SigElementArray getSigOutputElements() const { return SigOutputElements; } + SigElementArray getSigPatchOrPrimElements() const { + return SigPatchOrPrimElements; + } + + uint32_t getSigElementStride() const { return SigInputElements.Stride; } }; } // namespace DirectX diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h --- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h +++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h @@ -73,6 +73,33 @@ using ResourceBindInfo = dxbc::PSV::v2::ResourceBindInfo; +struct SignatureElement { + SignatureElement() = default; + + SignatureElement(dxbc::PSV::v0::SignatureElement El, StringRef StringTable, + ArrayRef IdxTable) + : Name(StringTable.substr(El.NameOffset, + StringTable.find('\0', El.NameOffset) - + El.NameOffset)), + Indices(IdxTable.slice(El.IndicesOffset, El.Rows)), + StartRow(El.StartRow), Cols(El.Cols), StartCol(El.StartCol), + Allocated(El.Allocated != 0), Kind(El.Kind), Type(El.Type), + Mode(El.Mode), DynamicMask(El.DynamicMask), Stream(El.Stream) {} + StringRef Name; + SmallVector Indices; + + uint8_t StartRow; + uint8_t Cols; + uint8_t StartCol; + bool Allocated; + dxbc::PSV::SemanticKind Kind; + + dxbc::PSV::ComponentType Type; + dxbc::PSV::InterpolationMode Mode; + llvm::yaml::Hex8 DynamicMask; + uint8_t Stream; +}; + struct PSVInfo { // The version field isn't actually encoded in the file, but it is inferred by // the size of data regions. We include it in the yaml because it simplifies @@ -81,7 +108,10 @@ dxbc::PSV::v2::RuntimeInfo Info; uint32_t ResourceStride; - std::vector Resources; + SmallVector Resources; + SmallVector SigInputElements; + SmallVector SigOutputElements; + SmallVector SigPatchOrPrimElements; void mapInfoForVersion(yaml::IO &IO); @@ -112,6 +142,11 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::Part) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::ResourceBindInfo) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DXContainerYAML::SignatureElement) +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) + namespace llvm { class raw_ostream; @@ -154,6 +189,10 @@ static void mapping(IO &IO, DXContainerYAML::ResourceBindInfo &Res); }; +template <> struct MappingTraits { + static void mapping(IO &IO, llvm::DXContainerYAML::SignatureElement &El); +}; + } // namespace yaml } // namespace llvm diff --git a/llvm/lib/BinaryFormat/DXContainer.cpp b/llvm/lib/BinaryFormat/DXContainer.cpp --- a/llvm/lib/BinaryFormat/DXContainer.cpp +++ b/llvm/lib/BinaryFormat/DXContainer.cpp @@ -13,6 +13,7 @@ #include "llvm/BinaryFormat/DXContainer.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ScopedPrinter.h" using namespace llvm; using namespace llvm::dxbc; @@ -28,3 +29,33 @@ static uint8_t Zeros[16] = {0}; return Flags > 0 || 0 != memcmp(&Digest, &Zeros, 16); } + +#define SEMANTIC_KIND(Val, Enum) {#Enum, PSV::SemanticKind::Enum}, + +static const EnumEntry SemanticKindNames[] = { +#include "llvm/BinaryFormat/DXContainerConstants.def" +}; + +ArrayRef> PSV::getSemanticKinds() { + return ArrayRef(SemanticKindNames); +} + +#define COMPONENT_TYPE(Val, Enum) {#Enum, PSV::ComponentType::Enum}, + +static const EnumEntry ComponentTypeNames[] = { +#include "llvm/BinaryFormat/DXContainerConstants.def" +}; + +ArrayRef> PSV::getComponentTypes() { + return ArrayRef(ComponentTypeNames); +} + +#define INTERPOLATION_MODE(Val, Enum) {#Enum, PSV::InterpolationMode::Enum}, + +static const EnumEntry InterpolationModeNames[] = { +#include "llvm/BinaryFormat/DXContainerConstants.def" +}; + +ArrayRef> PSV::getInterpolationModes() { + return ArrayRef(InterpolationModeNames); +} diff --git a/llvm/lib/MC/DXContainerPSVInfo.cpp b/llvm/lib/MC/DXContainerPSVInfo.cpp --- a/llvm/lib/MC/DXContainerPSVInfo.cpp +++ b/llvm/lib/MC/DXContainerPSVInfo.cpp @@ -8,6 +8,7 @@ #include "llvm/MC/DXContainerPSVInfo.h" #include "llvm/BinaryFormat/DXContainer.h" +#include "llvm/MC/StringTableBuilder.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/raw_ostream.h" @@ -15,7 +16,59 @@ using namespace llvm::mcdxbc; using namespace llvm::dxbc::PSV; +static constexpr size_t npos = StringRef::npos; + +static size_t FindSequence(ArrayRef Buffer, + ArrayRef Sequence) { + if (Buffer.size() < Sequence.size()) + return npos; + for (size_t Idx = 0; Idx <= Buffer.size() - Sequence.size(); ++Idx) { + if (0 == memcmp(static_cast(&Buffer[Idx]), + static_cast(Sequence.begin()), + Sequence.size() * sizeof(uint32_t))) + return Idx; + } + return npos; +} + +static void +ProcessElementList(StringTableBuilder &StrTabBuilder, + SmallVectorImpl &IndexBuffer, + SmallVectorImpl &FinalElements, + SmallVectorImpl &SemanticNames, + ArrayRef Elements) { + for (auto El : Elements) { + // Put the name in the string table and the name list. + StrTabBuilder.add(El.Name); + SemanticNames.push_back(El.Name); + + v0::SignatureElement FinalElement; + memset(&FinalElement, 0, sizeof(v0::SignatureElement)); + FinalElement.Rows = static_cast(El.Indices.size()); + FinalElement.StartRow = El.StartRow; + FinalElement.Cols = El.Cols; + FinalElement.StartCol = El.StartCol; + FinalElement.Allocated = El.Allocated; + FinalElement.Kind = El.Kind; + FinalElement.Type = El.Type; + FinalElement.Mode = El.Mode; + FinalElement.DynamicMask = El.DynamicMask; + FinalElement.Stream = El.Stream; + + size_t Idx = FindSequence(IndexBuffer, El.Indices); + if (Idx == npos) { + FinalElement.IndicesOffset = static_cast(IndexBuffer.size()); + IndexBuffer.insert(IndexBuffer.end(), El.Indices.begin(), + El.Indices.end()); + } else + FinalElement.IndicesOffset = static_cast(Idx); + FinalElements.push_back(FinalElement); + } +} + void PSVRuntimeInfo::write(raw_ostream &OS, uint32_t Version) const { + assert(IsFinalized && "finalize must be called before write"); + uint32_t InfoSize; uint32_t BindingSize; switch (Version) { @@ -41,8 +94,50 @@ uint32_t ResourceCount = static_cast(Resources.size()); support::endian::write(OS, ResourceCount, support::little); - support::endian::write(OS, BindingSize, support::little); + if (ResourceCount > 0) + support::endian::write(OS, BindingSize, support::little); for (const auto &Res : Resources) OS.write(reinterpret_cast(&Res), BindingSize); + + StringTableBuilder StrTabBuilder((StringTableBuilder::DXContainer)); + SmallVector IndexBuffer; + SmallVector SignatureElements; + SmallVector SemanticNames; + + ProcessElementList(StrTabBuilder, IndexBuffer, SignatureElements, + SemanticNames, InputElements); + ProcessElementList(StrTabBuilder, IndexBuffer, SignatureElements, + SemanticNames, OutputElements); + ProcessElementList(StrTabBuilder, IndexBuffer, SignatureElements, + SemanticNames, PatchOrPrimElements); + + StrTabBuilder.finalize(); + for (auto ElAndName : zip(SignatureElements, SemanticNames)) { + v0::SignatureElement &El = std::get<0>(ElAndName); + StringRef Name = std::get<1>(ElAndName); + El.NameOffset = static_cast(StrTabBuilder.getOffset(Name)); + if (sys::IsBigEndianHost) + El.swapBytes(); + } + + support::endian::write(OS, static_cast(StrTabBuilder.getSize()), + support::little); + + // Write the string table. + StrTabBuilder.write(OS); + + // Write the index table size, then table. + support::endian::write(OS, static_cast(IndexBuffer.size()), + support::little); + for (auto I : IndexBuffer) + support::endian::write(OS, I, support::little); + + // write the size of the signature elements. + support::endian::write( + OS, static_cast(sizeof(v0::SignatureElement)), support::little); + + // write the signature elements. + OS.write(reinterpret_cast(&SignatureElements[0]), + SignatureElements.size() * sizeof(v0::SignatureElement)); } diff --git a/llvm/lib/MC/StringTableBuilder.cpp b/llvm/lib/MC/StringTableBuilder.cpp --- a/llvm/lib/MC/StringTableBuilder.cpp +++ b/llvm/lib/MC/StringTableBuilder.cpp @@ -41,6 +41,7 @@ case MachO: case MachO64: case ELF: + case DXContainer: // Start the table with a NUL byte. Size = 1; break; @@ -167,7 +168,7 @@ } } - if (K == MachO || K == MachOLinked) + if (K == MachO || K == MachOLinked || K == DXContainer) Size = alignTo(Size, 4); // Pad to multiple of 4. if (K == MachO64 || K == MachO64Linked) Size = alignTo(Size, 8); // Pad to multiple of 8. diff --git a/llvm/lib/Object/DXContainer.cpp b/llvm/lib/Object/DXContainer.cpp --- a/llvm/lib/Object/DXContainer.cpp +++ b/llvm/lib/Object/DXContainer.cpp @@ -9,6 +9,7 @@ #include "llvm/Object/DXContainer.h" #include "llvm/BinaryFormat/DXContainer.h" #include "llvm/Object/Error.h" +#include "llvm/Support/Alignment.h" #include "llvm/Support/FormatVariadic.h" using namespace llvm; @@ -223,14 +224,17 @@ if (sys::IsBigEndianHost) Info.swapBytes(ShaderStage); BasicInfo = Info; - } else { + } else if (PSVVersion == 0) { v0::RuntimeInfo Info; if (Error Err = readStruct(PSVInfoData, Current, Info)) return Err; if (sys::IsBigEndianHost) Info.swapBytes(ShaderStage); BasicInfo = Info; - } + } else + return parseFailed( + "Cannot read PSV Runtime Info, unsupported PSV version."); + Current += Size; uint32_t ResourceCount = 0; @@ -251,7 +255,95 @@ "Resource binding data extends beyond the bounds of the part"); Current += BindingDataSize; + } else + Resources.Stride = sizeof(v2::ResourceBindInfo); + + // PSV version 0 ends after the resource bindings. + if (PSVVersion == 0) + return Error::success(); + + // String table starts at a 4-byte offset. + Current = reinterpret_cast( + alignTo<4>(reinterpret_cast(Current))); + + uint32_t StringTableSize = 0; + if (Error Err = readInteger(Data, Current, StringTableSize)) + return Err; + if (StringTableSize % 4 != 0) + return parseFailed("String table misaligned"); + Current += sizeof(uint32_t); + StringTable = StringRef(Current, StringTableSize); + + Current += StringTableSize; + + uint32_t SemanticIndexTableSize = 0; + if (Error Err = readInteger(Data, Current, SemanticIndexTableSize)) + return Err; + Current += sizeof(uint32_t); + + SemanticIndexTable.reserve(SemanticIndexTableSize); + for (uint32_t I = 0; I < SemanticIndexTableSize; ++I) { + uint32_t Index = 0; + if (Error Err = readInteger(Data, Current, Index)) + return Err; + Current += sizeof(uint32_t); + SemanticIndexTable.push_back(Index); + } + + uint8_t InputCount = getSigInputCount(); + uint8_t OutputCount = getSigOutputCount(); + uint8_t PatchOrPrimCount = getSigPatchOrPrimCount(); + + uint32_t ElementCount = InputCount + OutputCount + PatchOrPrimCount; + + if (ElementCount > 0) { + if (Error Err = readInteger(Data, Current, SigInputElements.Stride)) + return Err; + Current += sizeof(uint32_t); + // Assign the stride to all the arrays. + SigOutputElements.Stride = SigPatchOrPrimElements.Stride = + SigInputElements.Stride; + + if (Data.end() - Current < ElementCount * SigInputElements.Stride) + return parseFailed( + "Signature elements extend beyond the size of the part"); + + size_t InputSize = SigInputElements.Stride * InputCount; + SigInputElements.Data = Data.substr(Current - Data.begin(), InputSize); + Current += InputSize; + + size_t OutputSize = SigOutputElements.Stride * OutputCount; + SigOutputElements.Data = Data.substr(Current - Data.begin(), OutputSize); + Current += OutputSize; + + size_t PSize = SigPatchOrPrimElements.Stride * PatchOrPrimCount; + SigPatchOrPrimElements.Data = Data.substr(Current - Data.begin(), PSize); + Current += PSize; } return Error::success(); } + +uint8_t DirectX::PSVRuntimeInfo::getSigInputCount() const { + if (const auto *P = std::get_if(&BasicInfo)) + return P->SigInputElements; + if (const auto *P = std::get_if(&BasicInfo)) + return P->SigInputElements; + return 0; +} + +uint8_t DirectX::PSVRuntimeInfo::getSigOutputCount() const { + if (const auto *P = std::get_if(&BasicInfo)) + return P->SigOutputElements; + if (const auto *P = std::get_if(&BasicInfo)) + return P->SigOutputElements; + return 0; +} + +uint8_t DirectX::PSVRuntimeInfo::getSigPatchOrPrimCount() const { + if (const auto *P = std::get_if(&BasicInfo)) + return P->SigPatchOrPrimElements; + if (const auto *P = std::get_if(&BasicInfo)) + return P->SigPatchOrPrimElements; + return 0; +} diff --git a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp --- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp +++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp @@ -201,9 +201,26 @@ memcpy(&PSV.BaseData, &P.Info->Info, sizeof(dxbc::PSV::v2::RuntimeInfo)); PSV.Resources = P.Info->Resources; - if (sys::IsBigEndianHost) - PSV.swapBytes(static_cast( - Triple::Pixel + P.Info->Info.ShaderStage)); + for (auto El : P.Info->SigInputElements) + PSV.InputElements.push_back(mcdxbc::PSVSignatureElement{ + El.Name, El.Indices, El.StartRow, El.Cols, El.StartCol, + El.Allocated, El.Kind, El.Type, El.Mode, El.DynamicMask, + El.Stream}); + + for (auto El : P.Info->SigOutputElements) + PSV.OutputElements.push_back(mcdxbc::PSVSignatureElement{ + El.Name, El.Indices, El.StartRow, El.Cols, El.StartCol, + El.Allocated, El.Kind, El.Type, El.Mode, El.DynamicMask, + El.Stream}); + + for (auto El : P.Info->SigPatchOrPrimElements) + PSV.PatchOrPrimElements.push_back(mcdxbc::PSVSignatureElement{ + El.Name, El.Indices, El.StartRow, El.Cols, El.StartCol, + El.Allocated, El.Kind, El.Type, El.Mode, El.DynamicMask, + El.Stream}); + + PSV.finalize(static_cast( + Triple::Pixel + P.Info->Info.ShaderStage)); PSV.write(OS, P.Info->Version); break; } diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp --- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp +++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp @@ -12,7 +12,9 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/DXContainerYAML.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/BinaryFormat/DXContainer.h" +#include "llvm/Support/ScopedPrinter.h" namespace llvm { @@ -122,6 +124,9 @@ uint32_t Version = PSV.Version; IO.setContext(&Version); + // Restore the YAML context on function exit. + auto RestoreContext = make_scope_exit([&]() { IO.setContext(OldContext); }); + // Shader stage is only included in binaries for v1 and later, but we always // include it since it simplifies parsing and file construction. IO.mapRequired("ShaderStage", PSV.Info.ShaderStage); @@ -129,9 +134,11 @@ IO.mapRequired("ResourceStride", PSV.ResourceStride); IO.mapRequired("Resources", PSV.Resources); - - // Restore the YAML context. - IO.setContext(OldContext); + if (PSV.Version == 0) + return; + IO.mapRequired("SigInputElements", PSV.SigInputElements); + IO.mapRequired("SigOutputElements", PSV.SigOutputElements); + IO.mapRequired("SigPatchOrPrimElements", PSV.SigPatchOrPrimElements); } void MappingTraits::mapping(IO &IO, @@ -166,6 +173,39 @@ IO.mapRequired("Flags", Res.Flags); } +void MappingTraits::mapping( + IO &IO, DXContainerYAML::SignatureElement &El) { + IO.mapRequired("Name", El.Name); + IO.mapRequired("Indices", El.Indices); + IO.mapRequired("StartRow", El.StartRow); + IO.mapRequired("Cols", El.Cols); + IO.mapRequired("StartCol", El.StartCol); + IO.mapRequired("Allocated", El.Allocated); + IO.mapRequired("Kind", El.Kind); + IO.mapRequired("ComponentType", El.Type); + IO.mapRequired("Interpolation", El.Mode); + IO.mapRequired("DynamicMask", El.DynamicMask); + IO.mapRequired("Stream", El.Stream); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, dxbc::PSV::SemanticKind &Value) { + for (const auto &E : dxbc::PSV::getSemanticKinds()) + IO.enumCase(Value, E.Name.str().c_str(), E.Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, dxbc::PSV::ComponentType &Value) { + for (const auto &E : dxbc::PSV::getComponentTypes()) + IO.enumCase(Value, E.Name.str().c_str(), E.Value); +} + +void ScalarEnumerationTraits::enumeration( + IO &IO, dxbc::PSV::InterpolationMode &Value) { + for (const auto &E : dxbc::PSV::getInterpolationModes()) + IO.enumCase(Value, E.Name.str().c_str(), E.Value); +} + } // namespace yaml void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) { @@ -242,10 +282,6 @@ break; } - IO.mapRequired("SigInputElements", Info.SigInputElements); - IO.mapRequired("SigOutputElements", Info.SigOutputElements); - IO.mapRequired("SigPatchConstOrPrimElements", - Info.SigPatchConstOrPrimElements); IO.mapRequired("SigInputVectors", Info.SigInputVectors); MutableArrayRef Vec(Info.SigOutputVectors); IO.mapRequired("SigOutputVectors", Vec); diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-amplification.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-amplification.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-amplification.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-amplification.yaml @@ -18,9 +18,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -33,6 +30,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -53,9 +53,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -68,4 +65,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-compute.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-compute.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-compute.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-compute.yaml @@ -17,9 +17,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -32,6 +29,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -51,9 +51,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -66,4 +63,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-domain.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-domain.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-domain.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-domain.yaml @@ -21,9 +21,6 @@ MaximumWaveLaneCount: 4294967295 UsesViewID: 128 SigPatchConstOrPrimVectors: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -36,6 +33,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -59,9 +59,6 @@ # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: SigPatchConstOrPrimVectors: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -74,4 +71,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-geometry.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-geometry.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-geometry.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-geometry.yaml @@ -22,9 +22,6 @@ MaximumWaveLaneCount: 4294967295 UsesViewID: 128 MaxVertexCount: 4096 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -37,6 +34,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -61,9 +61,6 @@ # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: MaxVertexCount: 4096 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -76,4 +73,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-hull.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-hull.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-hull.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-hull.yaml @@ -22,9 +22,6 @@ MaximumWaveLaneCount: 4294967295 UsesViewID: 128 SigPatchConstOrPrimVectors: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -37,6 +34,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -61,9 +61,6 @@ # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: SigPatchConstOrPrimVectors: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -76,4 +73,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-mesh.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-mesh.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-mesh.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-mesh.yaml @@ -24,9 +24,6 @@ UsesViewID: 128 SigPrimVectors: 128 MeshOutputTopology: 16 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -39,6 +36,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -65,9 +65,6 @@ # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: SigPrimVectors: 128 # CHECK-NEXT: MeshOutputTopology: 16 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -80,4 +77,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-pixel.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-pixel.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-pixel.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-pixel.yaml @@ -19,9 +19,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -34,6 +31,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -55,9 +55,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -70,4 +67,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv1-vertex.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv1-vertex.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv1-vertex.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv1-vertex.yaml @@ -18,9 +18,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] ResourceStride: 16 @@ -33,6 +30,9 @@ Space: 32768 LowerBound: 8388608 UpperBound: 2147483648 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -53,9 +53,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: ResourceStride: 16 @@ -68,4 +65,7 @@ # CHECK-NEXT: Space: 32768 # CHECK-NEXT: LowerBound: 8388608 # CHECK-NEXT: UpperBound: 2147483648 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-amplification.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-amplification.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-amplification.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-amplification.yaml @@ -18,9 +18,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -40,6 +37,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -60,9 +60,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -82,4 +79,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-compute.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-compute.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-compute.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-compute.yaml @@ -17,9 +17,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -39,6 +36,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -58,9 +58,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -80,4 +77,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-domain.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-domain.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-domain.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-domain.yaml @@ -21,9 +21,6 @@ MaximumWaveLaneCount: 4294967295 UsesViewID: 128 SigPatchConstOrPrimVectors: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -43,6 +40,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -66,9 +66,6 @@ # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: SigPatchConstOrPrimVectors: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -88,4 +85,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-geometry.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-geometry.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-geometry.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-geometry.yaml @@ -22,9 +22,6 @@ MaximumWaveLaneCount: 4294967295 UsesViewID: 128 MaxVertexCount: 4096 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -44,6 +41,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -68,9 +68,6 @@ # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: MaxVertexCount: 4096 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -90,4 +87,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-hull.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-hull.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-hull.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-hull.yaml @@ -22,9 +22,6 @@ MaximumWaveLaneCount: 4294967295 UsesViewID: 128 SigPatchConstOrPrimVectors: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -44,6 +41,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -68,9 +68,6 @@ # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: SigPatchConstOrPrimVectors: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -90,4 +87,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-mesh.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-mesh.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-mesh.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-mesh.yaml @@ -24,9 +24,6 @@ UsesViewID: 128 SigPrimVectors: 128 MeshOutputTopology: 16 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -46,6 +43,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -72,9 +72,6 @@ # CHECK-NEXT: UsesViewID: 128 # CHECK-NEXT: SigPrimVectors: 128 # CHECK-NEXT: MeshOutputTopology: 16 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -94,4 +91,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-pixel.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-pixel.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-pixel.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-pixel.yaml @@ -19,9 +19,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -41,6 +38,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -62,9 +62,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -84,4 +81,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/PSVv2-vertex.yaml b/llvm/test/ObjectYAML/DXContainer/PSVv2-vertex.yaml --- a/llvm/test/ObjectYAML/DXContainer/PSVv2-vertex.yaml +++ b/llvm/test/ObjectYAML/DXContainer/PSVv2-vertex.yaml @@ -18,9 +18,6 @@ MinimumWaveLaneCount: 0 MaximumWaveLaneCount: 4294967295 UsesViewID: 128 - SigInputElements: 8 - SigOutputElements: 16 - SigPatchConstOrPrimElements: 32 SigInputVectors: 64 SigOutputVectors: [ 8, 16, 32, 64 ] NumThreadsX: 512 @@ -40,6 +37,9 @@ UpperBound: 2147483648 Kind: 65535 Flags: 16776960 + SigInputElements: [] + SigOutputElements: [] + SigPatchOrPrimElements: [] - Name: DXIL Size: 24 Program: @@ -60,9 +60,6 @@ # CHECK-NEXT: MinimumWaveLaneCount: 0 # CHECK-NEXT: MaximumWaveLaneCount: 4294967295 # CHECK-NEXT: UsesViewID: 128 -# CHECK-NEXT: SigInputElements: 8 -# CHECK-NEXT: SigOutputElements: 16 -# CHECK-NEXT: SigPatchConstOrPrimElements: 32 # CHECK-NEXT: SigInputVectors: 64 # CHECK-NEXT: SigOutputVectors: [ 8, 16, 32, 64 ] # CHECK-NEXT: NumThreadsX: 512 @@ -82,4 +79,7 @@ # CHECK-NEXT: UpperBound: 2147483648 # CHECK-NEXT: Kind: 65535 # CHECK-NEXT: Flags: 16776960 +# CHECK-NEXT: SigInputElements: [] +# CHECK-NEXT: SigOutputElements: [] +# CHECK-NEXT: SigPatchOrPrimElements: [] # CHECK-NEXT: Name diff --git a/llvm/test/ObjectYAML/DXContainer/SigElements.yaml b/llvm/test/ObjectYAML/DXContainer/SigElements.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/ObjectYAML/DXContainer/SigElements.yaml @@ -0,0 +1,144 @@ +# RUN: yaml2obj %s | obj2yaml | FileCheck %s + +--- !dxcontainer +Header: + Hash: [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ] + Version: + Major: 1 + Minor: 0 + PartCount: 2 +Parts: + - Name: PSV0 + Size: 250 + PSVInfo: + Version: 1 + ShaderStage: 0 + DepthOutput: 7 + SampleFrequency: 96 + MinimumWaveLaneCount: 0 + MaximumWaveLaneCount: 4294967295 + UsesViewID: 128 + SigInputVectors: 64 + SigOutputVectors: [ 8, 16, 32, 64 ] + ResourceStride: 16 + Resources: + - Type: 1 + Space: 2 + LowerBound: 3 + UpperBound: 4 + - Type: 128 + Space: 32768 + LowerBound: 8388608 + UpperBound: 2147483648 + SigInputElements: + - Name: IN + Indices: [ 0, 1 ] + StartRow: 0 + Cols: 2 + StartCol: 0 + Allocated: true + Kind: Arbitrary + ComponentType: SInt32 + Interpolation: Undefined + DynamicMask: 0x0 + Stream: 0 + SigOutputElements: + - Name: OUT + Indices: [ 0, 1 ] + StartRow: 0 + Cols: 2 + StartCol: 0 + Allocated: true + Kind: Arbitrary + ComponentType: Float32 + Interpolation: Linear + DynamicMask: 0x0 + Stream: 1 + SigPatchOrPrimElements: + - Name: Patch + Indices: [ 0 ] + StartRow: 0 + Cols: 1 + StartCol: 0 + Allocated: true + Kind: Arbitrary + ComponentType: Float32 + Interpolation: Linear + DynamicMask: 0x1 + Stream: 2 + - Name: Patch1 + Indices: [ 2 ] + StartRow: 0 + Cols: 1 + StartCol: 0 + Allocated: true + Kind: Arbitrary + ComponentType: Float64 + Interpolation: LinearSample + DynamicMask: 0x2 + Stream: 3 + - Name: DXIL + Size: 24 + Program: + MajorVersion: 6 + MinorVersion: 0 + ShaderKind: 0 + Size: 6 + DXILMajorVersion: 0 + DXILMinorVersion: 1 + DXILSize: 0 +... + +# CHECK: Name: PSV0 +# CHECK: PSVInfo: +# CHECK-NEXT: Version: 1 +# CHECK-NEXT: ShaderStage: 0 + +# CHECK: SigInputElements: +# CHECK-NEXT: - Name: IN +# CHECK-NEXT: Indices: [ 0, 1 ] +# CHECK-NEXT: StartRow: 0 +# CHECK-NEXT: Cols: 2 +# CHECK-NEXT: StartCol: 0 +# CHECK-NEXT: Allocated: true +# CHECK-NEXT: Kind: Arbitrary +# CHECK-NEXT: ComponentType: SInt32 +# CHECK-NEXT: Interpolation: Undefined +# CHECK-NEXT: DynamicMask: 0x0 +# CHECK-NEXT: Stream: 0 +# CHECK-NEXT: SigOutputElements: +# CHECK-NEXT: - Name: OUT +# CHECK-NEXT: Indices: [ 0, 1 ] +# CHECK-NEXT: StartRow: 0 +# CHECK-NEXT: Cols: 2 +# CHECK-NEXT: StartCol: 0 +# CHECK-NEXT: Allocated: true +# CHECK-NEXT: Kind: Arbitrary +# CHECK-NEXT: ComponentType: Float32 +# CHECK-NEXT: Interpolation: Linear +# CHECK-NEXT: DynamicMask: 0x0 +# CHECK-NEXT: Stream: 1 +# CHECK-NEXT: SigPatchOrPrimElements: +# CHECK-NEXT: - Name: Patch +# CHECK-NEXT: Indices: [ 0 ] +# CHECK-NEXT: StartRow: 0 +# CHECK-NEXT: Cols: 1 +# CHECK-NEXT: StartCol: 0 +# CHECK-NEXT: Allocated: true +# CHECK-NEXT: Kind: Arbitrary +# CHECK-NEXT: ComponentType: Float32 +# CHECK-NEXT: Interpolation: Linear +# CHECK-NEXT: DynamicMask: 0x1 +# CHECK-NEXT: Stream: 2 +# CHECK-NEXT: - Name: Patch1 +# CHECK-NEXT: Indices: [ 2 ] +# CHECK-NEXT: StartRow: 0 +# CHECK-NEXT: Cols: 1 +# CHECK-NEXT: StartCol: 0 +# CHECK-NEXT: Allocated: true +# CHECK-NEXT: Kind: Arbitrary +# CHECK-NEXT: ComponentType: Float64 +# CHECK-NEXT: Interpolation: LinearSample +# CHECK-NEXT: DynamicMask: 0x2 +# CHECK-NEXT: Stream: 3 diff --git a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp --- a/llvm/tools/obj2yaml/dxcontainer2yaml.cpp +++ b/llvm/tools/obj2yaml/dxcontainer2yaml.cpp @@ -92,6 +92,22 @@ NewPart.Info->ResourceStride = PSVInfo->getResourceStride(); for (auto Res : PSVInfo->getResources()) NewPart.Info->Resources.push_back(Res); + + for (auto El : PSVInfo->getSigInputElements()) + NewPart.Info->SigInputElements.push_back( + DXContainerYAML::SignatureElement( + El, PSVInfo->getStringTable(), + PSVInfo->getSemanticIndexTable())); + for (auto El : PSVInfo->getSigOutputElements()) + NewPart.Info->SigOutputElements.push_back( + DXContainerYAML::SignatureElement( + El, PSVInfo->getStringTable(), + PSVInfo->getSemanticIndexTable())); + for (auto El : PSVInfo->getSigPatchOrPrimElements()) + NewPart.Info->SigPatchOrPrimElements.push_back( + DXContainerYAML::SignatureElement( + El, PSVInfo->getStringTable(), + PSVInfo->getSemanticIndexTable())); break; } case dxbc::PartType::Unknown: diff --git a/llvm/unittests/Object/DXContainerTest.cpp b/llvm/unittests/Object/DXContainerTest.cpp --- a/llvm/unittests/Object/DXContainerTest.cpp +++ b/llvm/unittests/Object/DXContainerTest.cpp @@ -593,3 +593,50 @@ EXPECT_EQ(Binding.Type, 0u); EXPECT_EQ(Binding.Flags, 0u); } + +// This test binary is created using mutations of the yaml in the SigElements +// test found under test/ObjectYAML/DXContainer/SigElements.yaml. + +TEST(DXCFile, MisalignedStringTable) { + uint8_t Buffer[] = { + 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, + 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x53, 0x56, 0x30, 0x68, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x10, 0x20, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + EXPECT_THAT_EXPECTED(DXContainer::create(getMemoryBuffer<168>(Buffer)), + FailedWithMessage("String table misaligned")); +} + +// This test binary is created using mutations of the yaml in the SigElements +// test found under test/ObjectYAML/DXContainer/SigElements.yaml. +TEST(DXCFile, SigElementsExtendBeyondPart) { + uint8_t Buffer[] = { + 0x44, 0x58, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xb4, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, 0x18, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x00, 0x00, 0x44, 0x58, 0x49, 0x4c, + 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x53, 0x56, 0x30, 0x54, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x05, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x08, 0x10, 0x20, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x49, 0x4e, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x03, 0x00}; + EXPECT_THAT_EXPECTED( + DXContainer::create(getMemoryBuffer<164>(Buffer)), + FailedWithMessage( + "Signature elements extend beyond the size of the part")); +}