[clang] [llvm] [HLSL][RootSignature] Add parsing of remaining Descriptor Table params (PR #137038)
Finn Plummer via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 25 13:14:59 PDT 2025
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/137038
>From dd004171f5777dc68b700a5bf0f96c9c703a57c9 Mon Sep 17 00:00:00 2001
From: Finn Plummer <finnplummer at microsoft.com>
Date: Wed, 23 Apr 2025 18:37:55 +0000
Subject: [PATCH 1/2] pre-req: Add `unbounded` keyword to lexer
---
clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def | 7 +++++++
clang/unittests/Lex/LexHLSLRootSignatureTest.cpp | 1 +
2 files changed, 8 insertions(+)
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index c514d3456146a..d94be66b420c7 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -27,6 +27,9 @@
#endif
// Defines the various types of enum
+#ifndef UNBOUNDED_ENUM
+#define UNBOUNDED_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
#ifndef DESCRIPTOR_RANGE_OFFSET_ENUM
#define DESCRIPTOR_RANGE_OFFSET_ENUM(NAME, LIT) ENUM(NAME, LIT)
#endif
@@ -87,6 +90,9 @@ KEYWORD(flags)
KEYWORD(numDescriptors)
KEYWORD(offset)
+// Unbounded Enum:
+UNBOUNDED_ENUM(unbounded, "unbounded")
+
// Descriptor Range Offset Enum:
DESCRIPTOR_RANGE_OFFSET_ENUM(DescriptorRangeOffsetAppend, "DESCRIPTOR_RANGE_OFFSET_APPEND")
@@ -118,6 +124,7 @@ SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH")
#undef DESCRIPTOR_RANGE_FLAG_ENUM_ON
#undef ROOT_DESCRIPTOR_FLAG_ENUM
#undef DESCRIPTOR_RANGE_OFFSET_ENUM
+#undef UNBOUNDED_ENUM
#undef ENUM
#undef KEYWORD
#undef PUNCTUATOR
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index 46f00450adb62..2024ff3a7dba9 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -93,6 +93,7 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
space visibility flags
numDescriptors offset
+ unbounded
DESCRIPTOR_RANGE_OFFSET_APPEND
DATA_VOLATILE
>From 58d319539faa8522d0d7ed621383d58e034f3e2b Mon Sep 17 00:00:00 2001
From: Finn Plummer <finnplummer at microsoft.com>
Date: Wed, 23 Apr 2025 18:41:54 +0000
Subject: [PATCH 2/2] [HLSL][RootSignature] Add parsing of remaining Descriptor
Table params
- defines the special values for `DESCRIPTOR_RANGE_OFFSET_APPEND` and
`unbounded` for the `offset` and `numDescriptors` parameters
respectively
- adds these parmaters to the `DescriptorClause` struct and the params
struct
- plugs in parsing of `numDescriptors` and `offset` into
`parseDescriptorTableClauseParams`
- adds corresponding unit tests
---
.../clang/Parse/ParseHLSLRootSignature.h | 2 +
clang/lib/Parse/ParseHLSLRootSignature.cpp | 52 +++++++++++++++++++
.../Parse/ParseHLSLRootSignatureTest.cpp | 18 +++++--
.../llvm/Frontend/HLSL/HLSLRootSignature.h | 4 ++
4 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index d2e8f4dbcfc0c..91640e8bf0354 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -80,7 +80,9 @@ class RootSignatureParser {
/// state of parsed params
struct ParsedClauseParams {
std::optional<llvm::hlsl::rootsig::Register> Reg;
+ std::optional<uint32_t> NumDescriptors;
std::optional<uint32_t> Space;
+ std::optional<uint32_t> Offset;
std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags> Flags;
};
std::optional<ParsedClauseParams>
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 3b9e96017c88d..042aedbf1af52 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -145,9 +145,15 @@ RootSignatureParser::parseDescriptorTableClause() {
Clause.Reg = Params->Reg.value();
// Fill in optional values
+ if (Params->NumDescriptors.has_value())
+ Clause.NumDescriptors = Params->NumDescriptors.value();
+
if (Params->Space.has_value())
Clause.Space = Params->Space.value();
+ if (Params->Offset.has_value())
+ Clause.Offset = Params->Offset.value();
+
if (Params->Flags.has_value())
Clause.Flags = Params->Flags.value();
@@ -182,6 +188,29 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
Params.Reg = Reg;
}
+ // `numDescriptors` `=` POS_INT | unbounded
+ if (tryConsumeExpectedToken(TokenKind::kw_numDescriptors)) {
+ if (Params.NumDescriptors.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+ << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ std::optional<uint32_t> NumDescriptors;
+ if (tryConsumeExpectedToken(TokenKind::en_unbounded))
+ NumDescriptors = NumDescriptorsUnbounded;
+ else {
+ NumDescriptors = parseUIntParam();
+ if (!NumDescriptors.has_value())
+ return std::nullopt;
+ }
+
+ Params.NumDescriptors = NumDescriptors;
+ }
+
// `space` `=` POS_INT
if (tryConsumeExpectedToken(TokenKind::kw_space)) {
if (Params.Space.has_value()) {
@@ -199,6 +228,29 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
Params.Space = Space;
}
+ // `offset` `=` POS_INT | DESCRIPTOR_RANGE_OFFSET_APPEND
+ if (tryConsumeExpectedToken(TokenKind::kw_offset)) {
+ if (Params.Offset.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+ << CurToken.TokKind;
+ return std::nullopt;
+ }
+
+ if (consumeExpectedToken(TokenKind::pu_equal))
+ return std::nullopt;
+
+ std::optional<uint32_t> Offset;
+ if (tryConsumeExpectedToken(TokenKind::en_DescriptorRangeOffsetAppend))
+ Offset = DescriptorTableOffsetAppend;
+ else {
+ Offset = parseUIntParam();
+ if (!Offset.has_value())
+ return std::nullopt;
+ }
+
+ Params.Offset = Offset;
+ }
+
// `flags` `=` DESCRIPTOR_RANGE_FLAGS
if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
if (Params.Flags.has_value()) {
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index f4baf1580de61..2d4e37463bef3 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -130,10 +130,10 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
const llvm::StringLiteral Source = R"cc(
DescriptorTable(
CBV(b0),
- SRV(space = 3, t42, flags = 0),
+ SRV(space = 3, offset = 32, t42, flags = 0, numDescriptors = 4),
visibility = SHADER_VISIBILITY_PIXEL,
- Sampler(s987, space = +2),
- UAV(u4294967294,
+ Sampler(s987, space = +2, offset = DESCRIPTOR_RANGE_OFFSET_APPEND),
+ UAV(u4294967294, numDescriptors = unbounded,
flags = Descriptors_Volatile | Data_Volatile
| Data_Static_While_Set_At_Execute | Data_Static
| Descriptors_Static_Keeping_Buffer_Bounds_Checks
@@ -162,7 +162,10 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
RegisterType::BReg);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 0u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors, 1u);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 0u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset,
+ DescriptorTableOffsetAppend);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
DescriptorRangeFlags::DataStaticWhileSetAtExecute);
@@ -172,7 +175,9 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
RegisterType::TReg);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 42u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors, 4u);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 3u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset, 32u);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
DescriptorRangeFlags::None);
@@ -182,7 +187,10 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
RegisterType::SReg);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 987u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors, 1u);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 2u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset,
+ DescriptorTableOffsetAppend);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
DescriptorRangeFlags::None);
@@ -192,7 +200,11 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.ViewType,
RegisterType::UReg);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Reg.Number, 4294967294u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).NumDescriptors,
+ NumDescriptorsUnbounded);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Space, 0u);
+ ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Offset,
+ DescriptorTableOffsetAppend);
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Flags,
DescriptorRangeFlags::ValidFlags);
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 0745bce983bb3..818caccfe1998 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -60,12 +60,16 @@ struct DescriptorTable {
uint32_t NumClauses = 0; // The number of clauses in the table
};
+static const uint32_t NumDescriptorsUnbounded = 0xffffffff;
+static const uint32_t DescriptorTableOffsetAppend = 0xffffffff;
// Models DTClause : CBV | SRV | UAV | Sampler, by collecting like parameters
using ClauseType = llvm::dxil::ResourceClass;
struct DescriptorTableClause {
ClauseType Type;
Register Reg;
+ uint32_t NumDescriptors = 1;
uint32_t Space = 0;
+ uint32_t Offset = DescriptorTableOffsetAppend;
DescriptorRangeFlags Flags;
void setDefaultFlags() {
More information about the cfe-commits
mailing list