[clang] [llvm] [HLSL][RootSignature] Add parsing infastructure for StaticSampler (PR #140180)
Finn Plummer via cfe-commits
cfe-commits at lists.llvm.org
Mon May 26 14:27:29 PDT 2025
https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/140180
>From 05cd843e21cd8d93a94914d13843871886146dab Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Thu, 15 May 2025 22:35:30 +0000
Subject: [PATCH 1/3] [HLSL][RootSignature] Add parsing infastructure for
StaticSampler
- define StaticSampler in-memory representation
- implement the infastructure for parsing parameters of StaticSampler
- define and implement parsing of the `s` reg to demonstrate
functionality
- add unit tests
---
.../clang/Parse/ParseHLSLRootSignature.h | 6 ++
clang/lib/Parse/ParseHLSLRootSignature.cpp | 62 +++++++++++++++++++
.../Parse/ParseHLSLRootSignatureTest.cpp | 28 +++++++++
.../llvm/Frontend/HLSL/HLSLRootSignature.h | 18 ++++--
4 files changed, 108 insertions(+), 6 deletions(-)
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 3754b4a7b595f..da17388a2aea5 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -77,6 +77,7 @@ class RootSignatureParser {
std::optional<llvm::hlsl::rootsig::DescriptorTable> parseDescriptorTable();
std::optional<llvm::hlsl::rootsig::DescriptorTableClause>
parseDescriptorTableClause();
+ std::optional<llvm::hlsl::rootsig::StaticSampler> parseStaticSampler();
/// Parameter arguments (eg. `bReg`, `space`, ...) can be specified in any
/// order and only exactly once. The following methods define a
@@ -108,6 +109,11 @@ class RootSignatureParser {
std::optional<ParsedClauseParams>
parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
+ struct ParsedStaticSamplerParams {
+ std::optional<llvm::hlsl::rootsig::Register> Reg;
+ };
+ std::optional<ParsedStaticSamplerParams> parseStaticSamplerParams();
+
// Common parsing methods
std::optional<uint32_t> parseUIntParam();
std::optional<llvm::hlsl::rootsig::Register> parseRegister();
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 5181aae3f2d3b..520676fa0a614 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -55,6 +55,13 @@ bool RootSignatureParser::parse() {
return true;
Elements.push_back(*Descriptor);
}
+
+ if (tryConsumeExpectedToken(TokenKind::kw_StaticSampler)) {
+ auto Sampler = parseStaticSampler();
+ if (!Sampler.has_value())
+ return true;
+ Elements.push_back(*Sampler);
+ }
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
return consumeExpectedToken(TokenKind::end_of_stream,
@@ -348,6 +355,37 @@ RootSignatureParser::parseDescriptorTableClause() {
return Clause;
}
+std::optional<StaticSampler> RootSignatureParser::parseStaticSampler() {
+ assert(CurToken.TokKind == TokenKind::kw_StaticSampler &&
+ "Expects to only be invoked starting at given keyword");
+
+ if (consumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
+ CurToken.TokKind))
+ return std::nullopt;
+
+ StaticSampler Sampler;
+
+ auto Params = parseStaticSamplerParams();
+ if (!Params.has_value())
+ return std::nullopt;
+
+ // Check mandatory parameters were provided
+ if (!Params->Reg.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+ << TokenKind::sReg;
+ return std::nullopt;
+ }
+
+ Sampler.Reg = Params->Reg.value();
+
+ if (consumeExpectedToken(TokenKind::pu_r_paren,
+ diag::err_hlsl_unexpected_end_of_params,
+ /*param of=*/TokenKind::kw_StaticSampler))
+ return std::nullopt;
+
+ return Sampler;
+}
+
// Parameter arguments (eg. `bReg`, `space`, ...) can be specified in any
// order and only exactly once. The following methods will parse through as
// many arguments as possible reporting an error if a duplicate is seen.
@@ -606,6 +644,30 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
return Params;
}
+std::optional<RootSignatureParser::ParsedStaticSamplerParams>
+RootSignatureParser::parseStaticSamplerParams() {
+ assert(CurToken.TokKind == TokenKind::pu_l_paren &&
+ "Expects to only be invoked starting at given token");
+
+ ParsedStaticSamplerParams Params;
+ do {
+ // `s` POS_INT
+ if (tryConsumeExpectedToken(TokenKind::sReg)) {
+ if (Params.Reg.has_value()) {
+ getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+ << CurToken.TokKind;
+ return std::nullopt;
+ }
+ auto Reg = parseRegister();
+ if (!Reg.has_value())
+ return std::nullopt;
+ Params.Reg = Reg;
+ }
+ } while (tryConsumeExpectedToken(TokenKind::pu_comma));
+
+ return Params;
+}
+
std::optional<uint32_t> RootSignatureParser::parseUIntParam() {
assert(CurToken.TokKind == TokenKind::pu_equal &&
"Expects to only be invoked starting at given keyword");
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 64e780a61baf8..cd3b12dbe4d24 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -223,6 +223,34 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
ASSERT_TRUE(Consumer->isSatisfied());
}
+TEST_F(ParseHLSLRootSignatureTest, ValidParseStaticSamplerTest) {
+ const llvm::StringLiteral Source = R"cc(
+ StaticSampler(s0)
+ )cc";
+
+ TrivialModuleLoader ModLoader;
+ auto PP = createPP(Source, ModLoader);
+ auto TokLoc = SourceLocation();
+
+ hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+ SmallVector<RootElement> Elements;
+ hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+
+ // Test no diagnostics produced
+ Consumer->setNoDiag();
+
+ ASSERT_FALSE(Parser.parse());
+
+ ASSERT_EQ(Elements.size(), 1u);
+
+ RootElement Elem = Elements[0];
+ ASSERT_TRUE(std::holds_alternative<StaticSampler>(Elem));
+ ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.ViewType, RegisterType::SReg);
+ ASSERT_EQ(std::get<StaticSampler>(Elem).Reg.Number, 0u);
+
+ ASSERT_TRUE(Consumer->isSatisfied());
+}
+
TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
// This test will checks we can set the valid enum for Sampler descriptor
// range flags
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index fd0abc9479469..ca2f166479ce7 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -155,8 +155,12 @@ struct DescriptorTableClause {
raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause);
-/// Models RootElement : RootFlags | RootConstants | RootDescriptor
-/// | DescriptorTable | DescriptorTableClause
+struct StaticSampler {
+ Register Reg;
+};
+
+/// Models RootElement : RootFlags | RootConstants | RootParam
+/// | DescriptorTable | DescriptorTableClause | StaticSampler
///
/// A Root Signature is modeled in-memory by an array of RootElements. These
/// aim to map closely to their DSL grammar reprsentation defined in the spec.
@@ -164,14 +168,16 @@ raw_ostream &operator<<(raw_ostream &OS, const DescriptorTableClause &Clause);
/// Each optional parameter has its default value defined in the struct, and,
/// each mandatory parameter does not have a default initialization.
///
-/// For the variants RootFlags, RootConstants and DescriptorTableClause: each
-/// data member maps directly to a parameter in the grammar.
+/// For the variants RootFlags, RootConstants, RootParam, StaticSampler and
+/// DescriptorTableClause: each data member maps directly to a parameter in the
+/// grammar.
///
/// The DescriptorTable is modelled by having its Clauses as the previous
/// RootElements in the array, and it holds a data member for the Visibility
/// parameter.
-using RootElement = std::variant<RootFlags, RootConstants, RootDescriptor,
- DescriptorTable, DescriptorTableClause>;
+using RootElement =
+ std::variant<RootFlags, RootConstants, RootParam, DescriptorTable,
+ DescriptorTableClause, StaticSampler>;
void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements);
>From 9454de618dfcba4868874d2ad7e58ec14127c5c7 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Mon, 26 May 2025 21:04:16 +0000
Subject: [PATCH 2/3] self-review: fix typo
---
llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index ca2f166479ce7..f9de86b567fea 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -176,7 +176,7 @@ struct StaticSampler {
/// RootElements in the array, and it holds a data member for the Visibility
/// parameter.
using RootElement =
- std::variant<RootFlags, RootConstants, RootParam, DescriptorTable,
+ std::variant<RootFlags, RootConstants, RootDescriptor, DescriptorTable,
DescriptorTableClause, StaticSampler>;
void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements);
>From 17a78cc3eb80a006246260bb8b283094f1cafdf5 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Thu, 15 May 2025 22:33:54 +0000
Subject: [PATCH 3/3] pre-req: add missing token to Lexer
---
clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def | 1 +
clang/unittests/Lex/LexHLSLRootSignatureTest.cpp | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index c6f7f8928bc91..ddebe82987197 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -80,6 +80,7 @@ KEYWORD(RootSignature) // used only for diagnostic messaging
KEYWORD(RootFlags)
KEYWORD(DescriptorTable)
KEYWORD(RootConstants)
+KEYWORD(StaticSampler)
// RootConstants Keywords:
KEYWORD(num32BitConstants)
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index 1f8d8be64e323..3e38c281f4fb1 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -128,7 +128,7 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
RootSignature
- RootFlags DescriptorTable RootConstants
+ RootFlags DescriptorTable RootConstants StaticSampler
num32BitConstants
More information about the cfe-commits
mailing list