Skip to content

Commit 3e6b07e

Browse files
author
joaosaffran
committed
add parsing
1 parent 7f70dc5 commit 3e6b07e

File tree

3 files changed

+189
-1
lines changed

3 files changed

+189
-1
lines changed

llvm/include/llvm/BinaryFormat/DXContainerConstants.def

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ DESCRIPTOR_RANGE_FLAG(16, DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS)
9898
#undef DESCRIPTOR_RANGE_FLAG
9999
#endif // DESCRIPTOR_RANGE_FLAG
100100

101+
// DESCRIPTOR_RANGE(value, name).
102+
#ifdef DESCRIPTOR_RANGE
103+
DESCRIPTOR_RANGE(4, ERROR)
104+
DESCRIPTOR_RANGE(0, SRV)
105+
DESCRIPTOR_RANGE(1, UAV)
106+
DESCRIPTOR_RANGE(2, CBV)
107+
DESCRIPTOR_RANGE(3, Sampler)
108+
DESCRIPTOR_RANGE(0, NONE)
109+
#undef DESCRIPTOR_RANGE
110+
#endif // DESCRIPTOR_RANGE
111+
101112
#ifdef ROOT_PARAMETER
102113

103114
ROOT_PARAMETER(0, DescriptorTable)

llvm/lib/Target/DirectX/DXILRootSignature.cpp

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
//===----------------------------------------------------------------------===//
1313
#include "DXILRootSignature.h"
1414
#include "DirectX.h"
15+
#include "llvm/ADT/STLForwardCompat.h"
1516
#include "llvm/ADT/StringSwitch.h"
1617
#include "llvm/ADT/Twine.h"
1718
#include "llvm/Analysis/DXILMetadataAnalysis.h"
@@ -27,6 +28,7 @@
2728
#include "llvm/Support/Error.h"
2829
#include "llvm/Support/ErrorHandling.h"
2930
#include "llvm/Support/raw_ostream.h"
31+
#include <cstddef>
3032
#include <cstdint>
3133
#include <optional>
3234
#include <utility>
@@ -166,6 +168,88 @@ static bool parseRootDescriptors(LLVMContext *Ctx,
166168
return false;
167169
}
168170

171+
static bool parseDescriptorRange(LLVMContext *Ctx,
172+
mcdxbc::RootSignatureDesc &RSD,
173+
mcdxbc::DescriptorTable &Table,
174+
MDNode *RangeDescriptorNode) {
175+
176+
if (RangeDescriptorNode->getNumOperands() != 6)
177+
return reportError(Ctx, "Invalid format for Descriptor Range");
178+
179+
dxbc::RTS0::v2::DescriptorRange Range;
180+
181+
std::optional<StringRef> ElementText =
182+
extractMdStringValue(RangeDescriptorNode, 0);
183+
184+
if (!ElementText.has_value())
185+
return reportError(Ctx, "Descriptor Range, first element is not a string.");
186+
187+
Range.RangeType =
188+
StringSwitch<uint32_t>(*ElementText)
189+
.Case("CBV", llvm::to_underlying(dxbc::DescriptorRangeType::CBV))
190+
.Case("SRV", llvm::to_underlying(dxbc::DescriptorRangeType::SRV))
191+
.Case("UAV", llvm::to_underlying(dxbc::DescriptorRangeType::UAV))
192+
.Case("Sampler",
193+
llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))
194+
.Default(llvm::to_underlying(dxbc::DescriptorRangeType::ERROR));
195+
196+
if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 1))
197+
Range.NumDescriptors = *Val;
198+
else
199+
return reportError(Ctx, "Invalid value for Number of Descriptor in Range");
200+
201+
if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 2))
202+
Range.BaseShaderRegister = *Val;
203+
else
204+
return reportError(Ctx, "Invalid value for BaseShaderRegister");
205+
206+
if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 3))
207+
Range.RegisterSpace = *Val;
208+
else
209+
return reportError(Ctx, "Invalid value for RegisterSpace");
210+
211+
if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 4))
212+
Range.OffsetInDescriptorsFromTableStart = *Val;
213+
else
214+
return reportError(Ctx,
215+
"Invalid value for OffsetInDescriptorsFromTableStart");
216+
217+
if (std::optional<uint32_t> Val = extractMdIntValue(RangeDescriptorNode, 5))
218+
Range.Flags = *Val;
219+
else
220+
return reportError(Ctx, "Invalid value for Descriptor Range Flags");
221+
222+
Table.Ranges.push_back(Range);
223+
return false;
224+
}
225+
226+
static bool parseDescriptorTable(LLVMContext *Ctx,
227+
mcdxbc::RootSignatureDesc &RSD,
228+
MDNode *DescriptorTableNode) {
229+
if (DescriptorTableNode->getNumOperands() < 2)
230+
return reportError(Ctx, "Invalid format for Descriptor Table");
231+
232+
dxbc::RTS0::v1::RootParameterHeader Header;
233+
if (std::optional<uint32_t> Val = extractMdIntValue(DescriptorTableNode, 1))
234+
Header.ShaderVisibility = *Val;
235+
else
236+
return reportError(Ctx, "Invalid value for ShaderVisibility");
237+
238+
mcdxbc::DescriptorTable Table;
239+
240+
for (unsigned int I = 2; I < DescriptorTableNode->getNumOperands(); I++) {
241+
MDNode *Element = dyn_cast<MDNode>(DescriptorTableNode->getOperand(I));
242+
if (Element == nullptr)
243+
return reportError(Ctx, "Missing Root Element Metadata Node.");
244+
245+
if (parseDescriptorRange(Ctx, RSD, Table, Element))
246+
return true;
247+
}
248+
249+
RSD.ParametersContainer.addParameter(Header, Table);
250+
return false;
251+
}
252+
169253
static bool parseRootSignatureElement(LLVMContext *Ctx,
170254
mcdxbc::RootSignatureDesc &RSD,
171255
MDNode *Element) {
@@ -180,6 +264,7 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
180264
.Case("RootCBV", RootSignatureElementKind::RootDescriptors)
181265
.Case("RootSRV", RootSignatureElementKind::RootDescriptors)
182266
.Case("RootUAV", RootSignatureElementKind::RootDescriptors)
267+
.Case("DescriptorTable", RootSignatureElementKind::DescriptorTable)
183268
.Default(RootSignatureElementKind::Error);
184269

185270
switch (ElementKind) {
@@ -190,6 +275,8 @@ static bool parseRootSignatureElement(LLVMContext *Ctx,
190275
return parseRootConstants(Ctx, RSD, Element);
191276
case RootSignatureElementKind::RootDescriptors:
192277
return parseRootDescriptors(Ctx, RSD, Element);
278+
case RootSignatureElementKind::DescriptorTable:
279+
return parseDescriptorTable(Ctx, RSD, Element);
193280
case RootSignatureElementKind::Error:
194281
return reportError(Ctx, "Invalid Root Signature Element: " +
195282
ElementText->getString());
@@ -230,6 +317,79 @@ static bool verifyRegisterSpace(uint32_t RegisterSpace) {
230317

231318
static bool verifyDescriptorFlag(uint32_t Flags) { return (Flags & ~0xE) == 0; }
232319

320+
static bool verifyRangeType(uint32_t Type) {
321+
switch (Type) {
322+
case llvm::to_underlying(dxbc::DescriptorRangeType::CBV):
323+
case llvm::to_underlying(dxbc::DescriptorRangeType::SRV):
324+
case llvm::to_underlying(dxbc::DescriptorRangeType::UAV):
325+
case llvm::to_underlying(dxbc::DescriptorRangeType::Sampler):
326+
return true;
327+
};
328+
329+
return false;
330+
}
331+
332+
static bool verifyDescriptorRangeFlag(uint32_t Version, uint32_t Type,
333+
uint32_t Flags) {
334+
if (Version == 1 &&
335+
Type == llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))
336+
return Flags == 0;
337+
338+
if (Version == 2 &&
339+
Type == llvm::to_underlying(dxbc::DescriptorRangeType::Sampler)) {
340+
switch (Flags) {
341+
case 0:
342+
case llvm::to_underlying(dxbc::DescriptorRangeFlag::DATA_VOLATILE):
343+
case llvm::to_underlying(
344+
dxbc::DescriptorRangeFlag::
345+
DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS):
346+
return true;
347+
}
348+
return false;
349+
}
350+
351+
if (Version == 1 &&
352+
Type != llvm::to_underlying(dxbc::DescriptorRangeType::Sampler))
353+
return Flags ==
354+
llvm::to_underlying(dxbc::DescriptorRangeFlag::DESCRIPTORS_VOLATILE);
355+
356+
if (Version == 2 &&
357+
Type != llvm::to_underlying(dxbc::DescriptorRangeType::Sampler)) {
358+
switch (Flags) {
359+
case 0:
360+
case llvm::to_underlying(dxbc::DescriptorRangeFlag::DESCRIPTORS_VOLATILE):
361+
case llvm::to_underlying(dxbc::DescriptorRangeFlag::DATA_VOLATILE):
362+
case llvm::to_underlying(dxbc::DescriptorRangeFlag::DATA_STATIC):
363+
case llvm::to_underlying(
364+
dxbc::DescriptorRangeFlag::DATA_STATIC_WHILE_SET_AT_EXECUTE):
365+
case llvm::to_underlying(
366+
dxbc::DescriptorRangeFlag::
367+
DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS):
368+
case llvm::to_underlying(dxbc::DescriptorRangeFlag::DESCRIPTORS_VOLATILE) |
369+
llvm::to_underlying(dxbc::DescriptorRangeFlag::DATA_VOLATILE):
370+
case llvm::to_underlying(dxbc::DescriptorRangeFlag::DESCRIPTORS_VOLATILE) |
371+
llvm::to_underlying(
372+
dxbc::DescriptorRangeFlag::DATA_STATIC_WHILE_SET_AT_EXECUTE):
373+
case llvm::to_underlying(
374+
dxbc::DescriptorRangeFlag::
375+
DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS) |
376+
llvm::to_underlying(dxbc::DescriptorRangeFlag::DATA_VOLATILE):
377+
case llvm::to_underlying(
378+
dxbc::DescriptorRangeFlag::
379+
DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS) |
380+
llvm::to_underlying(dxbc::DescriptorRangeFlag::DATA_STATIC):
381+
case llvm::to_underlying(
382+
dxbc::DescriptorRangeFlag::
383+
DESCRIPTORS_STATIC_KEEPING_BUFFER_BOUNDS_CHECKS) |
384+
llvm::to_underlying(
385+
dxbc::DescriptorRangeFlag::DATA_STATIC_WHILE_SET_AT_EXECUTE):
386+
return true;
387+
}
388+
return false;
389+
}
390+
return false;
391+
}
392+
233393
static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
234394

235395
if (!verifyVersion(RSD.Version)) {
@@ -268,6 +428,22 @@ static bool validate(LLVMContext *Ctx, const mcdxbc::RootSignatureDesc &RSD) {
268428
}
269429
break;
270430
}
431+
case llvm::to_underlying(dxbc::RootParameterType::DescriptorTable): {
432+
const mcdxbc::DescriptorTable &Table =
433+
RSD.ParametersContainer.getDescriptorTable(Info.Location);
434+
for (const dxbc::RTS0::v2::DescriptorRange &Range : Table) {
435+
if (!verifyRangeType(Range.RangeType))
436+
return reportValueError(Ctx, "RangeType", Range.RangeType);
437+
438+
if (!verifyRegisterSpace(Range.RegisterSpace))
439+
return reportValueError(Ctx, "RegisterSpace", Range.RegisterSpace);
440+
441+
if (!verifyDescriptorRangeFlag(RSD.Version, Range.RangeType,
442+
Range.Flags))
443+
return reportValueError(Ctx, "DescriptorFlag", Range.Flags);
444+
}
445+
break;
446+
}
271447
}
272448
}
273449

llvm/lib/Target/DirectX/DXILRootSignature.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ enum class RootSignatureElementKind {
2828
Error = 0,
2929
RootFlags = 1,
3030
RootConstants = 2,
31-
RootDescriptors = 3
31+
RootDescriptors = 3,
32+
DescriptorTable = 4,
3233
};
3334
class RootSignatureAnalysis : public AnalysisInfoMixin<RootSignatureAnalysis> {
3435
friend AnalysisInfoMixin<RootSignatureAnalysis>;

0 commit comments

Comments
 (0)