Skip to content

Commit b28a7b1

Browse files
inbelicAnthony Tran
authored andcommitted
[HLSL][RootSignature] Plug-in serialization and add full sample testcase (llvm#144769)
This pr extends `dumpRootElements` to invoke the print methods of all `RootElement`s now that they are all implemented. Extends the `RootSignatures-AST.hlsl` testcase to have a root element of each type being parsed, constructed to the in-memory representation mode and then being dumped as part of the AST dump. - Update `HLSLRootSignatureUtils.cpp` to extend `dumpRootElements` - Extend `AST/HLSL/RootSigantures-AST.hlsl` testcase - Defines the helper `operator<<` for `RootElement` - Small correction to the output of `numDescriptors` to be `unbounded` in special case Resolves llvm#124595.
1 parent fd2f3c9 commit b28a7b1

File tree

4 files changed

+108
-53
lines changed

4 files changed

+108
-53
lines changed

clang/test/AST/HLSL/RootSignatures-AST.hlsl

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,61 @@
55
// the Attr AST Node is created succesfully. If an invalid root signature was
66
// passed in then we would exit out of Sema before the Attr is created.
77

8-
#define SampleRS \
9-
"DescriptorTable( " \
10-
" CBV(b1), " \
11-
" SRV(t1, numDescriptors = 8, " \
12-
" flags = DESCRIPTORS_VOLATILE), " \
13-
" UAV(u1, numDescriptors = 0, " \
14-
" flags = DESCRIPTORS_VOLATILE) " \
15-
"), " \
16-
"DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))"
8+
#define SampleRS "RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \
9+
"DENY_VERTEX_SHADER_ROOT_ACCESS), " \
10+
"CBV(b0, space = 1, flags = DATA_STATIC), " \
11+
"SRV(t0), " \
12+
"UAV(u0), " \
13+
"DescriptorTable( CBV(b1), " \
14+
"SRV(t1, numDescriptors = 8, " \
15+
" flags = DESCRIPTORS_VOLATILE), " \
16+
"UAV(u1, numDescriptors = unbounded, " \
17+
" flags = DESCRIPTORS_VOLATILE)), " \
18+
"DescriptorTable(Sampler(s0, space=1, numDescriptors = 4)), " \
19+
"RootConstants(num32BitConstants=3, b10), " \
20+
"StaticSampler(s1)," \
21+
"StaticSampler(s2, " \
22+
"addressU = TEXTURE_ADDRESS_CLAMP, " \
23+
"filter = FILTER_MIN_MAG_MIP_LINEAR )"
1724

1825
// CHECK: -HLSLRootSignatureDecl 0x{{.*}} {{.*}} implicit [[SAMPLE_RS_DECL:__hlsl_rootsig_decl_\d*]]
1926
// CHECK-SAME: RootElements{
20-
// CHECK-SAME: CBV(b1, numDescriptors = 1, space = 0,
21-
// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DataStaticWhileSetAtExecute),
22-
// CHECK-SAME: SRV(t1, numDescriptors = 8, space = 0,
23-
// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile),
24-
// CHECK-SAME: UAV(u1, numDescriptors = 0, space = 0,
25-
// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile),
26-
// CHECK-SAME: DescriptorTable(numClauses = 3, visibility = All),
27-
// CHECK-SAME: Sampler(s0, numDescriptors = 4, space = 1,
28-
// CHECK-SAME: offset = DescriptorTableOffsetAppend, flags = None),
29-
// CHECK-SAME: DescriptorTable(numClauses = 1, visibility = All)
30-
// CHECK-SAME: }
27+
// CHECK-SAME: RootFlags(AllowInputAssemblerInputLayout | DenyVertexShaderRootAccess),
28+
// CHECK-SAME: RootCBV(b0,
29+
// CHECK-SAME: space = 1, visibility = All, flags = DataStatic
30+
// CHECK-SAME: ),
31+
// CHECK-SAME: RootSRV(t0,
32+
// CHECK-SAME: space = 0, visibility = All, flags = DataStaticWhileSetAtExecute
33+
// CHECK-SAME: ),
34+
// CHECK-SAME: RootUAV(
35+
// CHECK-SAME: u0, space = 0, visibility = All, flags = DataVolatile
36+
// CHECK-SAME: ),
37+
// CHECK-SAME: CBV(
38+
// CHECK-SAME: b1, numDescriptors = 1, space = 0, offset = DescriptorTableOffsetAppend, flags = DataStaticWhileSetAtExecute
39+
// CHECK-SAME: ),
40+
// CHECK-SAME: SRV(
41+
// CHECK-SAME: t1, numDescriptors = 8, space = 0, offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile
42+
// CHECK-SAME: ),
43+
// CHECK-SAME: UAV(
44+
// CHECK-SAME: u1, numDescriptors = unbounded, space = 0, offset = DescriptorTableOffsetAppend, flags = DescriptorsVolatile
45+
// CHECK-SAME: ),
46+
// CHECK-SAME: DescriptorTable(
47+
// CHECK-SAME: numClauses = 3, visibility = All
48+
// CHECK-SAME: ),
49+
// CHECK-SAME: Sampler(
50+
// CHECK-SAME: s0, numDescriptors = 4, space = 1, offset = DescriptorTableOffsetAppend, flags = None
51+
// CHECK-SAME: ),
52+
// CHECK-SAME: DescriptorTable(
53+
// CHECK-SAME: numClauses = 1, visibility = All
54+
// CHECK-SAME: ),
55+
// CHECK-SAME: RootConstants(
56+
// CHECK-SAME: num32BitConstants = 3, b10, space = 0, visibility = All
57+
// CHECK-SAME: ),
58+
// CHECK-SAME: StaticSampler(
59+
// CHECK-SAME: s1, filter = Anisotropic, addressU = Wrap, addressV = Wrap, addressW = Wrap,
60+
// CHECK-SAME: mipLODBias = 0.000000e+00, maxAnisotropy = 16, comparisonFunc = LessEqual,
61+
// CHECK-SAME: borderColor = OpaqueWhite, minLOD = 0.000000e+00, maxLOD = 3.402823e+38, space = 0, visibility = All
62+
// CHECK-SAME: )}
3163

3264
// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]]
3365
[RootSignature(SampleRS)]
@@ -44,14 +76,23 @@ void same_rs_main() {}
4476
// link to the same root signature declaration
4577

4678
#define SampleSameRS \
47-
"DescriptorTable( " \
48-
" CBV(b1), " \
49-
" SRV(t1, numDescriptors = 8, " \
50-
" flags = DESCRIPTORS_VOLATILE), " \
51-
" UAV(u1, numDescriptors = 0, " \
52-
" flags = DESCRIPTORS_VOLATILE) " \
53-
"), " \
54-
"DescriptorTable(Sampler(s0, numDescriptors = 4, space = 1))"
79+
"RootFlags( ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | " \
80+
"DENY_VERTEX_SHADER_ROOT_ACCESS), " \
81+
"CBV(b0, space = 1, flags = DATA_STATIC), " \
82+
"SRV(t0), " \
83+
"UAV(u0), " \
84+
"DescriptorTable( CBV(b1), " \
85+
"SRV(t1, numDescriptors = 8, " \
86+
" flags = DESCRIPTORS_VOLATILE), " \
87+
"UAV(u1, numDescriptors = unbounded, " \
88+
" flags = DESCRIPTORS_VOLATILE)), " \
89+
"DescriptorTable(Sampler(s0, space=1, numDescriptors = 4)), " \
90+
"RootConstants(num32BitConstants=3, b10), " \
91+
"StaticSampler(s1)," \
92+
"StaticSampler(s2, " \
93+
"addressU = TEXTURE_ADDRESS_CLAMP, " \
94+
"filter = FILTER_MIN_MAG_MIP_LINEAR )"
95+
5596

5697
// CHECK: -RootSignatureAttr 0x{{.*}} {{.*}} [[SAMPLE_RS_DECL]]
5798
[RootSignature(SampleSameRS)]

llvm/include/llvm/Frontend/HLSL/HLSLRootSignatureUtils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
4444
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS,
4545
const StaticSampler &StaticSampler);
4646

47+
LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, const RootElement &Element);
48+
4749
LLVM_ABI void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements);
4850

4951
class MetadataBuilder {

llvm/lib/Frontend/HLSL/HLSLRootSignatureUtils.cpp

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -287,9 +287,12 @@ raw_ostream &operator<<(raw_ostream &OS, const DescriptorTable &Table) {
287287
}
288288

289289
raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause) {
290-
OS << Clause.Type << "(" << Clause.Reg
291-
<< ", numDescriptors = " << Clause.NumDescriptors
292-
<< ", space = " << Clause.Space << ", offset = ";
290+
OS << Clause.Type << "(" << Clause.Reg << ", numDescriptors = ";
291+
if (Clause.NumDescriptors == NumDescriptorsUnbounded)
292+
OS << "unbounded";
293+
else
294+
OS << Clause.NumDescriptors;
295+
OS << ", space = " << Clause.Space << ", offset = ";
293296
if (Clause.Offset == DescriptorTableOffsetAppend)
294297
OS << "DescriptorTableOffsetAppend";
295298
else
@@ -324,36 +327,45 @@ raw_ostream &operator<<(raw_ostream &OS, const StaticSampler &Sampler) {
324327
return OS;
325328
}
326329

330+
namespace {
331+
332+
// We use the OverloadVisit with std::visit to ensure the compiler catches if a
333+
// new RootElement variant type is added but it's operator<< or metadata
334+
// generation isn't handled.
335+
template <class... Ts> struct OverloadedVisit : Ts... {
336+
using Ts::operator()...;
337+
};
338+
template <class... Ts> OverloadedVisit(Ts...) -> OverloadedVisit<Ts...>;
339+
340+
} // namespace
341+
342+
raw_ostream &operator<<(raw_ostream &OS, const RootElement &Element) {
343+
const auto Visitor = OverloadedVisit{
344+
[&OS](const RootFlags &Flags) { OS << Flags; },
345+
[&OS](const RootConstants &Constants) { OS << Constants; },
346+
[&OS](const RootDescriptor &Descriptor) { OS << Descriptor; },
347+
[&OS](const DescriptorTableClause &Clause) { OS << Clause; },
348+
[&OS](const DescriptorTable &Table) { OS << Table; },
349+
[&OS](const StaticSampler &Sampler) { OS << Sampler; },
350+
};
351+
std::visit(Visitor, Element);
352+
return OS;
353+
}
354+
327355
void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements) {
328-
OS << "RootElements{";
356+
OS << " RootElements{";
329357
bool First = true;
330358
for (const RootElement &Element : Elements) {
331359
if (!First)
332360
OS << ",";
333-
OS << " ";
334-
if (const auto &Clause = std::get_if<DescriptorTableClause>(&Element))
335-
OS << *Clause;
336-
if (const auto &Table = std::get_if<DescriptorTable>(&Element))
337-
OS << *Table;
361+
OS << " " << Element;
338362
First = false;
339363
}
340364
OS << "}";
341365
}
342366

343-
namespace {
344-
345-
// We use the OverloadBuild with std::visit to ensure the compiler catches if a
346-
// new RootElement variant type is added but it's metadata generation isn't
347-
// handled.
348-
template <class... Ts> struct OverloadedBuild : Ts... {
349-
using Ts::operator()...;
350-
};
351-
template <class... Ts> OverloadedBuild(Ts...) -> OverloadedBuild<Ts...>;
352-
353-
} // namespace
354-
355367
MDNode *MetadataBuilder::BuildRootSignature() {
356-
const auto Visitor = OverloadedBuild{
368+
const auto Visitor = OverloadedVisit{
357369
[this](const RootFlags &Flags) -> MDNode * {
358370
return BuildRootFlags(Flags);
359371
},

llvm/unittests/Frontend/HLSLRootSignatureDumpTest.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ TEST(HLSLRootSignatureTest, DescriptorSRVClauseDump) {
3434
DescriptorTableClause Clause;
3535
Clause.Type = ClauseType::SRV;
3636
Clause.Reg = {RegisterType::TReg, 0};
37-
Clause.NumDescriptors = 2;
37+
Clause.NumDescriptors = NumDescriptorsUnbounded;
3838
Clause.Space = 42;
3939
Clause.Offset = 3;
4040
Clause.Flags = DescriptorRangeFlags::None;
@@ -44,8 +44,8 @@ TEST(HLSLRootSignatureTest, DescriptorSRVClauseDump) {
4444
OS << Clause;
4545
OS.flush();
4646

47-
std::string Expected =
48-
"SRV(t0, numDescriptors = 2, space = 42, offset = 3, flags = None)";
47+
std::string Expected = "SRV(t0, numDescriptors = unbounded, space = 42, "
48+
"offset = 3, flags = None)";
4949
EXPECT_EQ(Out, Expected);
5050
}
5151

0 commit comments

Comments
 (0)