[llvm] 8e19573 - [DirectX] adding support to read/write descriptor table data using obj2yaml/yaml2obj (#138315)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 29 12:21:23 PDT 2025
Author: joaosaffran
Date: 2025-05-29T12:21:20-07:00
New Revision: 8e19573682b6c53aa1df223e80aa46a3ab48cd35
URL: https://github.com/llvm/llvm-project/commit/8e19573682b6c53aa1df223e80aa46a3ab48cd35
DIFF: https://github.com/llvm/llvm-project/commit/8e19573682b6c53aa1df223e80aa46a3ab48cd35.diff
LOG: [DirectX] adding support to read/write descriptor table data using obj2yaml/yaml2obj (#138315)
Closes:
https://github.com/orgs/llvm/projects/4/views/22?sliceBy%5Bvalue%5D=joaosaffran&pane=issue&itemId=97332852&issue=llvm%7Cllvm-project%7C126635
---------
Co-authored-by: joaosaffran <joao.saffran at microsoft.com>
Added:
llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.0.yaml
llvm/test/ObjectYAML/DXContainer/RootSignature-DescriptorTable1.1.yaml
Modified:
llvm/include/llvm/BinaryFormat/DXContainer.h
llvm/include/llvm/BinaryFormat/DXContainerConstants.def
llvm/include/llvm/MC/DXContainerRootSignature.h
llvm/include/llvm/Object/DXContainer.h
llvm/include/llvm/ObjectYAML/DXContainerYAML.h
llvm/lib/MC/DXContainerRootSignature.cpp
llvm/lib/ObjectYAML/DXContainerEmitter.cpp
llvm/lib/ObjectYAML/DXContainerYAML.cpp
llvm/test/ObjectYAML/DXContainer/RootSignature-MultipleParameters.yaml
llvm/unittests/Object/DXContainerTest.cpp
llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/BinaryFormat/DXContainer.h b/llvm/include/llvm/BinaryFormat/DXContainer.h
index 3494e0fe1a0e9..9bb182b6510d0 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;
@@ -588,6 +600,21 @@ static_assert(sizeof(ProgramSignatureElement) == 32,
namespace RTS0 {
namespace v1 {
+struct DescriptorRange {
+ uint32_t RangeType;
+ uint32_t NumDescriptors;
+ uint32_t BaseShaderRegister;
+ uint32_t RegisterSpace;
+ uint32_t OffsetInDescriptorsFromTableStart;
+ void swapBytes() {
+ sys::swapByteOrder(RangeType);
+ sys::swapByteOrder(NumDescriptors);
+ sys::swapByteOrder(BaseShaderRegister);
+ sys::swapByteOrder(RegisterSpace);
+ sys::swapByteOrder(OffsetInDescriptorsFromTableStart);
+ }
+};
+
struct RootDescriptor {
uint32_t ShaderRegister;
uint32_t RegisterSpace;
@@ -655,6 +682,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
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 81d2c54b6e07c..a407dd0e8d2c2 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)
diff --git a/llvm/include/llvm/MC/DXContainerRootSignature.h b/llvm/include/llvm/MC/DXContainerRootSignature.h
index 5f5919122b3c5..63d7b508d87dd 100644
--- a/llvm/include/llvm/MC/DXContainerRootSignature.h
+++ b/llvm/include/llvm/MC/DXContainerRootSignature.h
@@ -25,11 +25,22 @@ struct RootParameterInfo {
: Header(Header), Location(Location) {}
};
+struct DescriptorTable {
+ SmallVector<dxbc::RTS0::v2::DescriptorRange> Ranges;
+ SmallVector<dxbc::RTS0::v2::DescriptorRange>::const_iterator begin() const {
+ return Ranges.begin();
+ }
+ SmallVector<dxbc::RTS0::v2::DescriptorRange>::const_iterator end() const {
+ return Ranges.end();
+ }
+};
+
struct RootParametersContainer {
SmallVector<RootParameterInfo> ParametersInfo;
SmallVector<dxbc::RTS0::v1::RootConstants> Constants;
SmallVector<dxbc::RTS0::v2::RootDescriptor> Descriptors;
+ SmallVector<DescriptorTable> Tables;
void addInfo(dxbc::RTS0::v1::RootParameterHeader Header, size_t Location) {
ParametersInfo.push_back(RootParameterInfo(Header, Location));
@@ -51,6 +62,12 @@ struct RootParametersContainer {
Descriptors.push_back(Descriptor);
}
+ void addParameter(dxbc::RTS0::v1::RootParameterHeader Header,
+ DescriptorTable Table) {
+ addInfo(Header, Tables.size());
+ Tables.push_back(Table);
+ }
+
const std::pair<uint32_t, uint32_t>
getTypeAndLocForParameter(uint32_t Location) const {
const RootParameterInfo &Info = ParametersInfo[Location];
@@ -70,6 +87,10 @@ struct RootParametersContainer {
return Descriptors[Index];
}
+ const DescriptorTable &getDescriptorTable(size_t Index) const {
+ return Tables[Index];
+ }
+
size_t size() const { return ParametersInfo.size(); }
SmallVector<RootParameterInfo>::const_iterator begin() const {
diff --git a/llvm/include/llvm/Object/DXContainer.h b/llvm/include/llvm/Object/DXContainer.h
index 37cd5ca7dc935..ef981a156e87d 100644
--- a/llvm/include/llvm/Object/DXContainer.h
+++ b/llvm/include/llvm/Object/DXContainer.h
@@ -20,6 +20,7 @@
#include "llvm/ADT/Twine.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"
@@ -177,6 +178,50 @@ struct RootDescriptorView : RootParameterView {
}
};
+struct DescriptorTable {
+ uint32_t NumRanges;
+ uint32_t RangesOffset;
+ ViewArray<dxbc::RTS0::v2::DescriptorRange> Ranges;
+
+ typename ViewArray<dxbc::RTS0::v2::DescriptorRange>::iterator begin() const {
+ return Ranges.begin();
+ }
+
+ typename ViewArray<dxbc::RTS0::v2::DescriptorRange>::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<DescriptorTable> read(uint32_t Version) {
+ const char *Current = ParamData.begin();
+ DescriptorTable 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);
+
+ 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<GenericBinaryError>(Msg.str(), object_error::parse_failed);
}
@@ -213,6 +258,9 @@ class RootSignature {
llvm::Expected<RootParameterView>
getParameter(const dxbc::RTS0::v1::RootParameterHeader &Header) const {
size_t DataSize;
+ size_t EndOfSectionByte = getNumStaticSamplers() == 0
+ ? PartData.size()
+ : getStaticSamplersOffset();
if (!dxbc::isValidParameterType(Header.ParameterType))
return parseFailed("invalid parameter type");
@@ -229,11 +277,23 @@ class RootSignature {
else
DataSize = sizeof(dxbc::RTS0::v2::RootDescriptor);
break;
- }
- size_t EndOfSectionByte = getNumStaticSamplers() == 0
- ? PartData.size()
- : getStaticSamplersOffset();
+ case dxbc::RootParameterType::DescriptorTable:
+ if (Header.ParameterOffset + sizeof(uint32_t) > EndOfSectionByte)
+ return parseFailed("Reading structure out of file bounds");
+ uint32_t NumRanges =
+ support::endian::read<uint32_t, llvm::endianness::little>(
+ PartData.begin() + Header.ParameterOffset);
+ if (Version == 1)
+ DataSize = sizeof(dxbc::RTS0::v1::DescriptorRange) * NumRanges;
+ else
+ DataSize = sizeof(dxbc::RTS0::v2::DescriptorRange) * NumRanges;
+
+ // 4 bytes for the number of ranges in table and
+ // 4 bytes for the ranges offset
+ DataSize += 2 * sizeof(uint32_t);
+ break;
+ }
if (Header.ParameterOffset + DataSize > EndOfSectionByte)
return parseFailed("Reading structure out of file bounds");
diff --git a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
index 3af1da552cc7a..33327e5a2de39 100644
--- a/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
+++ b/llvm/include/llvm/ObjectYAML/DXContainerYAML.h
@@ -90,6 +90,25 @@ struct RootDescriptorYaml {
#include "llvm/BinaryFormat/DXContainerConstants.def"
};
+struct DescriptorRangeYaml {
+ uint32_t RangeType;
+ uint32_t NumDescriptors;
+ uint32_t BaseShaderRegister;
+ uint32_t RegisterSpace;
+ uint32_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 RootParameterHeaderYaml {
uint32_t Type;
uint32_t Visibility;
@@ -113,6 +132,7 @@ struct RootParameterYamlDesc {
SmallVector<RootConstantsYaml> Constants;
SmallVector<RootDescriptorYaml> Descriptors;
+ SmallVector<DescriptorTableYaml> Tables;
template <typename T>
T &getOrInsertImpl(RootParameterLocationYaml &ParamDesc,
@@ -134,6 +154,10 @@ struct RootParameterYamlDesc {
return getOrInsertImpl(ParamDesc, Descriptors);
}
+ DescriptorTableYaml &getOrInsertTable(RootParameterLocationYaml &ParamDesc) {
+ return getOrInsertImpl(ParamDesc, Tables);
+ }
+
void insertLocation(RootParameterLocationYaml &Location) {
Locations.push_back(Location);
}
@@ -263,6 +287,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::RootParameterLocationYaml)
+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)
@@ -351,6 +376,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 3a4bd8321eb95..01531b4d4dbc9 100644
--- a/llvm/lib/MC/DXContainerRootSignature.cpp
+++ b/llvm/lib/MC/DXContainerRootSignature.cpp
@@ -47,6 +47,18 @@ 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);
+
+ // 4 bytes for the number of ranges in table and
+ // 4 bytes for the ranges offset
+ Size += 2 * sizeof(uint32_t);
+ if (Version == 1)
+ Size += sizeof(dxbc::RTS0::v1::DescriptorRange) * Table.Ranges.size();
+ else
+ Size += sizeof(dxbc::RTS0::v2::DescriptorRange) * Table.Ranges.size();
+ break;
}
}
return Size;
@@ -106,6 +118,27 @@ void RootSignatureDesc::write(raw_ostream &OS) const {
support::endian::write(BOS, Descriptor.Flags, llvm::endianness::little);
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 d5fdf0bda68c3..233a79ea20fe9 100644
--- a/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerEmitter.cpp
@@ -303,6 +303,26 @@ void DXContainerWriter::writeParts(raw_ostream &OS) {
RS.ParametersContainer.addParameter(Header, Descriptor);
break;
}
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+ const DXContainerYAML::DescriptorTableYaml &TableYaml =
+ P.RootSignature->Parameters.getOrInsertTable(L);
+ mcdxbc::DescriptorTable Table;
+ for (const auto &R : TableYaml.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
diff --git a/llvm/lib/ObjectYAML/DXContainerYAML.cpp b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
index 22561ec0ac9b9..9af4a93b30644 100644
--- a/llvm/lib/ObjectYAML/DXContainerYAML.cpp
+++ b/llvm/lib/ObjectYAML/DXContainerYAML.cpp
@@ -105,6 +105,38 @@ DXContainerYAML::RootSignatureYamlDesc::create(
llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
+ } else if (auto *DTV =
+ dyn_cast<object::DirectX::DescriptorTableView>(&ParamView)) {
+ llvm::Expected<object::DirectX::DescriptorTable> TableOrErr =
+ DTV->read(Version);
+ if (Error E = TableOrErr.takeError())
+ return std::move(E);
+ auto Table = *TableOrErr;
+ RootParameterLocationYaml Location(Header);
+ DescriptorTableYaml &TableYaml =
+ RootSigDesc.Parameters.getOrInsertTable(Location);
+ RootSigDesc.Parameters.insertLocation(Location);
+
+ TableYaml.NumRanges = Table.NumRanges;
+ TableYaml.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"
+ }
+ TableYaml.Ranges.push_back(NewR);
+ }
}
}
#define ROOT_ELEMENT_FLAG(Num, Val) \
@@ -132,6 +164,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) \
@@ -303,6 +344,37 @@ void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
#include "llvm/BinaryFormat/DXContainerConstants.def"
}
+void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
+ IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
+ IO.mapRequired("RangeType", R.RangeType);
+ // handling the edge case where NumDescriptors might be -1
+ if (IO.outputting()) {
+ if (R.NumDescriptors == UINT_MAX) {
+ int32_t NegOne = -1;
+ IO.mapRequired("NumDescriptors", NegOne);
+ } else
+ IO.mapRequired("NumDescriptors", R.NumDescriptors);
+ } else {
+ int32_t TmpNumDesc = 0;
+ IO.mapRequired("NumDescriptors", TmpNumDesc);
+ R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
+ }
+
+ 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 MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
DXContainerYAML::RootSignatureYamlDesc>::
mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
@@ -325,6 +397,12 @@ void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
IO.mapRequired("Descriptor", Descriptor);
break;
}
+ case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
+ DXContainerYAML::DescriptorTableYaml &Table =
+ S.Parameters.getOrInsertTable(L);
+ IO.mapRequired("Table", Table);
+ 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..0441bb7a256b1
--- /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: -1
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: 41
+ 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: -1
+# CHECK-NEXT: BaseShaderRegister: 42
+# CHECK-NEXT: RegisterSpace: 43
+# CHECK-NEXT: OffsetInDescriptorsFromTableStart: 41
+# 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..d06be5e181418
--- /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: -1
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: 41
+ 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: -1
+# CHECK-NEXT: BaseShaderRegister: 42
+# CHECK-NEXT: RegisterSpace: 43
+# CHECK-NEXT: OffsetInDescriptorsFromTableStart: 41
+# 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..947fc096a9207 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,14 +37,25 @@ 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: -1
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: 41
+ DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
AllowInputAssemblerInputLayout: true
DenyGeometryShaderRootAccess: true
# CHECK: - Name: RTS0
-# CHECK-NEXT: Size: 96
+# CHECK-NEXT: Size: 200
# CHECK-NEXT: RootSignature:
# CHECK-NEXT: Version: 2
-# CHECK-NEXT: NumRootParameters: 3
+# CHECK-NEXT: NumRootParameters: 4
# CHECK-NEXT: RootParametersOffset: 24
# CHECK-NEXT: NumStaticSamplers: 0
# CHECK-NEXT: StaticSamplersOffset: 60
@@ -67,5 +78,17 @@ Parts:
# 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: -1
+# CHECK-NEXT: BaseShaderRegister: 42
+# CHECK-NEXT: RegisterSpace: 43
+# CHECK-NEXT: OffsetInDescriptorsFromTableStart: 41
+# 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..71503729b5f34 100644
--- a/llvm/unittests/Object/DXContainerTest.cpp
+++ b/llvm/unittests/Object/DXContainerTest.cpp
@@ -1050,3 +1050,108 @@ 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, 0xff, 0xff, 0xff, 0xff,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+ 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>(&*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, -1u);
+ ASSERT_EQ(Range.BaseShaderRegister, 42u);
+ ASSERT_EQ(Range.RegisterSpace, 43u);
+ ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);
+ 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, 0xff, 0xff, 0xff, 0xff,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 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};
+ 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>(&*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, -1u);
+ ASSERT_EQ(Range.BaseShaderRegister, 42u);
+ ASSERT_EQ(Range.RegisterSpace, 43u);
+ ASSERT_EQ(Range.OffsetInDescriptorsFromTableStart, 41u);
+ }
+}
diff --git a/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp b/llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp
index b6a5cee24b29d..9215b609a485a 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: 44
+ 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, 0x2c, 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_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: -1
+ BaseShaderRegister: 42
+ RegisterSpace: 43
+ OffsetInDescriptorsFromTableStart: 41
+ 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, 0xff, 0xff, 0xff, 0xff,
+ 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
+ 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);
+}
More information about the llvm-commits
mailing list