Skip to content

Commit 3c39922

Browse files
authored
[HLSL][RootSignature] Add parsing of ShaderVisibility to DescriptorTable (#136751)
- Defines `parseShaderVisiblity` to establish how single enums will be parsed - Adds unit testing of the visiblity enum Part three of implementing #126569
1 parent 73ddbd3 commit 3c39922

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,13 @@ class RootSignatureParser {
8585
std::optional<ParsedClauseParams>
8686
parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
8787

88+
// Common parsing methods
8889
std::optional<uint32_t> parseUIntParam();
8990
std::optional<llvm::hlsl::rootsig::Register> parseRegister();
9091

92+
/// Parsing methods of various enums
93+
std::optional<llvm::hlsl::rootsig::ShaderVisibility> parseShaderVisibility();
94+
9195
/// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
9296
/// 32-bit integer
9397
std::optional<uint32_t> handleUIntLiteral();

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
5252
return std::nullopt;
5353

5454
DescriptorTable Table;
55+
std::optional<ShaderVisibility> Visibility;
5556

5657
// Iterate as many Clauses as possible
5758
do {
@@ -63,8 +64,27 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
6364
Elements.push_back(*Clause);
6465
Table.NumClauses++;
6566
}
67+
68+
if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
69+
if (Visibility.has_value()) {
70+
getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
71+
<< CurToken.TokKind;
72+
return std::nullopt;
73+
}
74+
75+
if (consumeExpectedToken(TokenKind::pu_equal))
76+
return std::nullopt;
77+
78+
Visibility = parseShaderVisibility();
79+
if (!Visibility.has_value())
80+
return std::nullopt;
81+
}
6682
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
6783

84+
// Fill in optional visibility
85+
if (Visibility.has_value())
86+
Table.Visibility = Visibility.value();
87+
6888
if (consumeExpectedToken(TokenKind::pu_r_paren,
6989
diag::err_hlsl_unexpected_end_of_params,
7090
/*param of=*/TokenKind::kw_DescriptorTable))
@@ -222,6 +242,32 @@ std::optional<Register> RootSignatureParser::parseRegister() {
222242
return Reg;
223243
}
224244

245+
std::optional<llvm::hlsl::rootsig::ShaderVisibility>
246+
RootSignatureParser::parseShaderVisibility() {
247+
assert(CurToken.TokKind == TokenKind::pu_equal &&
248+
"Expects to only be invoked starting at given keyword");
249+
250+
TokenKind Expected[] = {
251+
#define SHADER_VISIBILITY_ENUM(NAME, LIT) TokenKind::en_##NAME,
252+
#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
253+
};
254+
255+
if (!tryConsumeExpectedToken(Expected))
256+
return std::nullopt;
257+
258+
switch (CurToken.TokKind) {
259+
#define SHADER_VISIBILITY_ENUM(NAME, LIT) \
260+
case TokenKind::en_##NAME: \
261+
return ShaderVisibility::NAME; \
262+
break;
263+
#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
264+
default:
265+
llvm_unreachable("Switch for consumed enum token was not provided");
266+
}
267+
268+
return std::nullopt;
269+
}
270+
225271
std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
226272
// Parse the numeric value and do semantic checks on its specification
227273
clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
131131
DescriptorTable(
132132
CBV(b0),
133133
SRV(space = 3, t42),
134+
visibility = SHADER_VISIBILITY_PIXEL,
134135
Sampler(s987, space = +2),
135136
UAV(u4294967294)
136137
),
@@ -186,11 +187,14 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
186187
Elem = Elements[4];
187188
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
188189
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)4);
190+
ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility,
191+
ShaderVisibility::Pixel);
189192

190193
// Empty Descriptor Table
191194
Elem = Elements[5];
192195
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
193196
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, 0u);
197+
ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility, ShaderVisibility::All);
194198

195199
ASSERT_TRUE(Consumer->isSatisfied());
196200
}

llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@ namespace llvm {
2121
namespace hlsl {
2222
namespace rootsig {
2323

24+
// Definition of the various enumerations and flags
25+
26+
enum class ShaderVisibility {
27+
All = 0,
28+
Vertex = 1,
29+
Hull = 2,
30+
Domain = 3,
31+
Geometry = 4,
32+
Pixel = 5,
33+
Amplification = 6,
34+
Mesh = 7,
35+
};
36+
2437
// Definitions of the in-memory data layout structures
2538

2639
// Models the different registers: bReg | tReg | uReg | sReg
@@ -32,6 +45,7 @@ struct Register {
3245

3346
// Models the end of a descriptor table and stores its visibility
3447
struct DescriptorTable {
48+
ShaderVisibility Visibility = ShaderVisibility::All;
3549
uint32_t NumClauses = 0; // The number of clauses in the table
3650
};
3751

0 commit comments

Comments
 (0)