Skip to content

Commit ac51bf6

Browse files
author
joaosaffran
committed
adding reading logic
1 parent 44bd13a commit ac51bf6

File tree

3 files changed

+212
-2
lines changed

3 files changed

+212
-2
lines changed

llvm/include/llvm/Object/DXContainer.h

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
#include "llvm/ADT/StringRef.h"
2020
#include "llvm/BinaryFormat/DXContainer.h"
2121
#include "llvm/Object/Error.h"
22+
#include "llvm/Support/Endian.h"
2223
#include "llvm/Support/Error.h"
2324
#include "llvm/Support/MemoryBufferRef.h"
2425
#include "llvm/TargetParser/Triple.h"
25-
#include <array>
26-
#include <cstddef>
2726
#include <variant>
2827

2928
namespace llvm {
@@ -169,6 +168,43 @@ struct RootDescriptorView : RootParameterView {
169168
return readParameter<dxbc::RST0::v1::RootDescriptor>();
170169
}
171170
};
171+
template <typename T> struct DescriptorTable {
172+
uint32_t Version;
173+
uint32_t NumRanges;
174+
uint32_t RangesOffset;
175+
ViewArray<T> Ranges;
176+
177+
typename ViewArray<T>::iterator begin() const { return Ranges.begin(); }
178+
179+
typename ViewArray<T>::iterator end() const { return Ranges.end(); }
180+
};
181+
182+
template <typename T> struct DescriptorTableView : RootParameterView {
183+
using TemplateType = T;
184+
185+
static bool classof(const RootParameterView *V) {
186+
return (V->Header.ParameterType ==
187+
llvm::to_underlying(dxbc::RootParameterType::DescriptorTable));
188+
}
189+
190+
// Define a type alias to access the template parameter from inside classof
191+
llvm::Expected<DescriptorTable<T>> read() {
192+
const char *Current = ParamData.begin();
193+
DescriptorTable<T> Table;
194+
195+
Table.NumRanges =
196+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
197+
Current += sizeof(uint32_t);
198+
199+
Table.RangesOffset =
200+
support::endian::read<uint32_t, llvm::endianness::little>(Current);
201+
Current += sizeof(uint32_t);
202+
203+
Table.Ranges.Data =
204+
ParamData.substr(2 * sizeof(uint32_t), Table.NumRanges * sizeof(T));
205+
return Table;
206+
}
207+
};
172208

173209
static Error parseFailed(const Twine &Msg) {
174210
return make_error<GenericBinaryError>(Msg.str(), object_error::parse_failed);
@@ -221,6 +257,18 @@ class RootSignature {
221257
else
222258
DataSize = sizeof(dxbc::RST0::v1::RootDescriptor);
223259
break;
260+
case dxbc::RootParameterType::DescriptorTable:
261+
uint32_t NumRanges =
262+
support::endian::read<uint32_t, llvm::endianness::little>(
263+
PartData.begin() + Header.ParameterOffset);
264+
if (Version == 1)
265+
DataSize = sizeof(dxbc::RST0::v0::DescriptorRange) * NumRanges +
266+
2 * sizeof(uint32_t);
267+
else
268+
DataSize = sizeof(dxbc::RST0::v1::DescriptorRange) * NumRanges +
269+
2 * sizeof(uint32_t);
270+
break;
271+
break;
224272
}
225273
size_t EndOfSectionByte = getNumStaticSamplers() == 0
226274
? PartData.size()

llvm/lib/ObjectYAML/DXContainerYAML.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,55 @@ DXContainerYAML::RootSignatureYamlDesc::create(
9696
llvm::to_underlying(dxbc::RootDescriptorFlag::Val)) > 0;
9797
#include "llvm/BinaryFormat/DXContainerConstants.def"
9898
}
99+
} else if (auto *TDV = dyn_cast<object::DirectX::DescriptorTableView<
100+
dxbc::RST0::v0::DescriptorRange>>(&ParamView)) {
101+
llvm::Expected<
102+
object::DirectX::DescriptorTable<dxbc::RST0::v0::DescriptorRange>>
103+
TableOrErr = TDV->read();
104+
if (Error E = TableOrErr.takeError())
105+
return std::move(E);
106+
auto Table = *TableOrErr;
107+
NewP.Table.NumRanges = Table.NumRanges;
108+
NewP.Table.RangesOffset = Table.RangesOffset;
109+
110+
for (const auto &R : Table) {
111+
DescriptorRangeYaml NewR;
112+
113+
NewR.OffsetInDescriptorsFromTableStart =
114+
R.OffsetInDescriptorsFromTableStart;
115+
NewR.NumDescriptors = R.NumDescriptors;
116+
NewR.BaseShaderRegister = R.BaseShaderRegister;
117+
NewR.RegisterSpace = R.RegisterSpace;
118+
NewR.RangeType = R.RangeType;
119+
120+
NewP.Table.Ranges.push_back(NewR);
121+
}
122+
} else if (auto *TDV = dyn_cast<object::DirectX::DescriptorTableView<
123+
dxbc::RST0::v1::DescriptorRange>>(&ParamView)) {
124+
llvm::Expected<
125+
object::DirectX::DescriptorTable<dxbc::RST0::v1::DescriptorRange>>
126+
TableOrErr = TDV->read();
127+
if (Error E = TableOrErr.takeError())
128+
return std::move(E);
129+
auto Table = *TableOrErr;
130+
NewP.Table.NumRanges = Table.NumRanges;
131+
NewP.Table.RangesOffset = Table.RangesOffset;
132+
133+
for (const auto &R : Table) {
134+
DescriptorRangeYaml NewR;
135+
136+
NewR.OffsetInDescriptorsFromTableStart =
137+
R.OffsetInDescriptorsFromTableStart;
138+
NewR.NumDescriptors = R.NumDescriptors;
139+
NewR.BaseShaderRegister = R.BaseShaderRegister;
140+
NewR.RegisterSpace = R.RegisterSpace;
141+
NewR.RangeType = R.RangeType;
142+
#define DESCRIPTOR_RANGE_FLAG(Num, Val) \
143+
NewR.Val = \
144+
(R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlag::Val)) > 0;
145+
#include "llvm/BinaryFormat/DXContainerConstants.def"
146+
NewP.Table.Ranges.push_back(NewR);
147+
}
99148
}
100149

101150
RootSigDesc.Parameters.push_back(NewP);

llvm/unittests/ObjectYAML/DXContainerYAMLTest.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,116 @@ TEST(RootSignature, ParseRootDescriptorsV11) {
354354
EXPECT_EQ(Storage.size(), 133u);
355355
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
356356
}
357+
358+
TEST(RootSignature, ParseDescriptorTableV10) {
359+
SmallString<128> Storage;
360+
361+
// First read a fully explicit yaml with all sizes and offsets provided
362+
ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
363+
Header:
364+
Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
365+
0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
366+
Version:
367+
Major: 1
368+
Minor: 0
369+
FileSize: 133
370+
PartCount: 1
371+
PartOffsets: [ 36 ]
372+
Parts:
373+
- Name: RTS0
374+
Size: 89
375+
RootSignature:
376+
Version: 1
377+
NumRootParameters: 1
378+
RootParametersOffset: 24
379+
NumStaticSamplers: 0
380+
StaticSamplersOffset: 60
381+
Parameters:
382+
- ParameterType: 0 # SRV
383+
ShaderVisibility: 3 # Domain
384+
Table:
385+
NumRanges: 1
386+
Ranges:
387+
- RangeType: 0
388+
NumDescriptors: 41
389+
BaseShaderRegister: 42
390+
RegisterSpace: 43
391+
OffsetInDescriptorsFromTableStart: -1
392+
AllowInputAssemblerInputLayout: true
393+
DenyGeometryShaderRootAccess: true
394+
)"));
395+
396+
uint8_t Buffer[] = {
397+
0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
398+
0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
399+
0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
400+
0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
401+
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402+
0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403+
0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
404+
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
405+
0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
406+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408+
0x00};
409+
410+
EXPECT_EQ(Storage.size(), 133u);
411+
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
412+
}
413+
414+
TEST(RootSignature, ParseDescriptorTableV11) {
415+
SmallString<128> Storage;
416+
417+
// First read a fully explicit yaml with all sizes and offsets provided
418+
ASSERT_TRUE(convert(Storage, R"(--- !dxcontainer
419+
Header:
420+
Hash: [ 0x32, 0x9A, 0x53, 0xD8, 0xEC, 0xBE, 0x35, 0x6F, 0x5,
421+
0x39, 0xE1, 0xFE, 0x31, 0x20, 0xF0, 0xC1 ]
422+
Version:
423+
Major: 1
424+
Minor: 0
425+
FileSize: 133
426+
PartCount: 1
427+
PartOffsets: [ 36 ]
428+
Parts:
429+
- Name: RTS0
430+
Size: 89
431+
RootSignature:
432+
Version: 2
433+
NumRootParameters: 1
434+
RootParametersOffset: 24
435+
NumStaticSamplers: 0
436+
StaticSamplersOffset: 60
437+
Parameters:
438+
- ParameterType: 0 # SRV
439+
ShaderVisibility: 3 # Domain
440+
Table:
441+
NumRanges: 1
442+
Ranges:
443+
- RangeType: 0
444+
NumDescriptors: 41
445+
BaseShaderRegister: 42
446+
RegisterSpace: 43
447+
OffsetInDescriptorsFromTableStart: -1
448+
DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS: true
449+
AllowInputAssemblerInputLayout: true
450+
DenyGeometryShaderRootAccess: true
451+
)"));
452+
453+
uint8_t Buffer[] = {
454+
0x44, 0x58, 0x42, 0x43, 0x32, 0x9a, 0x53, 0xd8, 0xec, 0xbe, 0x35, 0x6f,
455+
0x05, 0x39, 0xe1, 0xfe, 0x31, 0x20, 0xf0, 0xc1, 0x01, 0x00, 0x00, 0x00,
456+
0x85, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
457+
0x52, 0x54, 0x53, 0x30, 0x59, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
458+
0x01, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459+
0x3c, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460+
0x03, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
461+
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
462+
0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
463+
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465+
0x00};
466+
467+
EXPECT_EQ(Storage.size(), 133u);
468+
EXPECT_TRUE(memcmp(Buffer, Storage.data(), 133u) == 0);
469+
}

0 commit comments

Comments
 (0)