-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[HLSL][RootSignature] Add parsing of ShaderVisibility to DescriptorTable #136751
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang Author: Finn Plummer (inbelic) Changes
Part three of implementing #126569 Full diff: https://github.com/llvm/llvm-project/pull/136751.diff 4 Files Affected:
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index d9f121030c1fc..d639ca91c002f 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -85,9 +85,13 @@ class RootSignatureParser {
std::optional<ParsedClauseParams>
parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
+ // Common parsing methods
std::optional<uint32_t> parseUIntParam();
std::optional<llvm::hlsl::rootsig::Register> parseRegister();
+ /// Parsing methods of various enums
+ std::optional<llvm::hlsl::rootsig::ShaderVisibility> parseShaderVisibility();
+
/// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
/// 32-bit integer
std::optional<uint32_t> handleUIntLiteral();
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 1bf33b8e8329c..8244e91c8f89a 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -52,6 +52,7 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
return std::nullopt;
DescriptorTable Table;
+ std::optional<ShaderVisibility> Visibility;
// Iterate as many Clauses as possible
do {
@@ -63,8 +64,27 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
Elements.push_back(*Clause);
Table.NumClauses++;
}
+
+ if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
+ if (Visibility.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;
+
+ Visibility = parseShaderVisibility();
+ if (!Visibility.has_value())
+ return std::nullopt;
+ }
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
+ // Fill in optional visibility
+ if (Visibility.has_value())
+ Table.Visibility = Visibility.value();
+
if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_DescriptorTable))
@@ -222,6 +242,32 @@ std::optional<Register> RootSignatureParser::parseRegister() {
return Reg;
}
+std::optional<llvm::hlsl::rootsig::ShaderVisibility>
+RootSignatureParser::parseShaderVisibility() {
+ assert(CurToken.TokKind == TokenKind::pu_equal &&
+ "Expects to only be invoked starting at given keyword");
+
+ TokenKind Expected[] = {
+#define SHADER_VISIBILITY_ENUM(NAME, LIT) TokenKind::en_##NAME,
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ };
+
+ if (!tryConsumeExpectedToken(Expected))
+ return std::nullopt;
+
+ switch (CurToken.TokKind) {
+#define SHADER_VISIBILITY_ENUM(NAME, LIT) \
+ case TokenKind::en_##NAME: \
+ return ShaderVisibility::NAME; \
+ break;
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ default:
+ llvm_unreachable("Switch for consumed enum token was not provided");
+ }
+
+ return std::nullopt;
+}
+
std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
// Parse the numeric value and do semantic checks on its specification
clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index e382a1b26d366..1d89567509e72 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -131,6 +131,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
DescriptorTable(
CBV(b0),
SRV(space = 3, t42),
+ visibility = SHADER_VISIBILITY_PIXEL,
Sampler(s987, space = +2),
UAV(u4294967294)
),
@@ -186,11 +187,14 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
Elem = Elements[4];
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)4);
+ ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility,
+ ShaderVisibility::Pixel);
// Empty Descriptor Table
Elem = Elements[5];
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, 0u);
+ ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility, ShaderVisibility::All);
ASSERT_TRUE(Consumer->isSatisfied());
}
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 778b0c397f9cf..d51b853942dd3 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -21,6 +21,19 @@ namespace llvm {
namespace hlsl {
namespace rootsig {
+// Definition of the various enumerations and flags
+
+enum class ShaderVisibility {
+ All = 0,
+ Vertex = 1,
+ Hull = 2,
+ Domain = 3,
+ Geometry = 4,
+ Pixel = 5,
+ Amplification = 6,
+ Mesh = 7,
+};
+
// Definitions of the in-memory data layout structures
// Models the different registers: bReg | tReg | uReg | sReg
@@ -32,6 +45,7 @@ struct Register {
// Models the end of a descriptor table and stores its visibility
struct DescriptorTable {
+ ShaderVisibility Visibility = ShaderVisibility::All;
uint32_t NumClauses = 0; // The number of clauses in the table
};
|
@llvm/pr-subscribers-hlsl Author: Finn Plummer (inbelic) Changes
Part three of implementing #126569 Full diff: https://github.com/llvm/llvm-project/pull/136751.diff 4 Files Affected:
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index d9f121030c1fc..d639ca91c002f 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -85,9 +85,13 @@ class RootSignatureParser {
std::optional<ParsedClauseParams>
parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
+ // Common parsing methods
std::optional<uint32_t> parseUIntParam();
std::optional<llvm::hlsl::rootsig::Register> parseRegister();
+ /// Parsing methods of various enums
+ std::optional<llvm::hlsl::rootsig::ShaderVisibility> parseShaderVisibility();
+
/// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
/// 32-bit integer
std::optional<uint32_t> handleUIntLiteral();
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 1bf33b8e8329c..8244e91c8f89a 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -52,6 +52,7 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
return std::nullopt;
DescriptorTable Table;
+ std::optional<ShaderVisibility> Visibility;
// Iterate as many Clauses as possible
do {
@@ -63,8 +64,27 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
Elements.push_back(*Clause);
Table.NumClauses++;
}
+
+ if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
+ if (Visibility.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;
+
+ Visibility = parseShaderVisibility();
+ if (!Visibility.has_value())
+ return std::nullopt;
+ }
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
+ // Fill in optional visibility
+ if (Visibility.has_value())
+ Table.Visibility = Visibility.value();
+
if (consumeExpectedToken(TokenKind::pu_r_paren,
diag::err_hlsl_unexpected_end_of_params,
/*param of=*/TokenKind::kw_DescriptorTable))
@@ -222,6 +242,32 @@ std::optional<Register> RootSignatureParser::parseRegister() {
return Reg;
}
+std::optional<llvm::hlsl::rootsig::ShaderVisibility>
+RootSignatureParser::parseShaderVisibility() {
+ assert(CurToken.TokKind == TokenKind::pu_equal &&
+ "Expects to only be invoked starting at given keyword");
+
+ TokenKind Expected[] = {
+#define SHADER_VISIBILITY_ENUM(NAME, LIT) TokenKind::en_##NAME,
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ };
+
+ if (!tryConsumeExpectedToken(Expected))
+ return std::nullopt;
+
+ switch (CurToken.TokKind) {
+#define SHADER_VISIBILITY_ENUM(NAME, LIT) \
+ case TokenKind::en_##NAME: \
+ return ShaderVisibility::NAME; \
+ break;
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+ default:
+ llvm_unreachable("Switch for consumed enum token was not provided");
+ }
+
+ return std::nullopt;
+}
+
std::optional<uint32_t> RootSignatureParser::handleUIntLiteral() {
// Parse the numeric value and do semantic checks on its specification
clang::NumericLiteralParser Literal(CurToken.NumSpelling, CurToken.TokLoc,
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index e382a1b26d366..1d89567509e72 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -131,6 +131,7 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
DescriptorTable(
CBV(b0),
SRV(space = 3, t42),
+ visibility = SHADER_VISIBILITY_PIXEL,
Sampler(s987, space = +2),
UAV(u4294967294)
),
@@ -186,11 +187,14 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
Elem = Elements[4];
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)4);
+ ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility,
+ ShaderVisibility::Pixel);
// Empty Descriptor Table
Elem = Elements[5];
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, 0u);
+ ASSERT_EQ(std::get<DescriptorTable>(Elem).Visibility, ShaderVisibility::All);
ASSERT_TRUE(Consumer->isSatisfied());
}
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 778b0c397f9cf..d51b853942dd3 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -21,6 +21,19 @@ namespace llvm {
namespace hlsl {
namespace rootsig {
+// Definition of the various enumerations and flags
+
+enum class ShaderVisibility {
+ All = 0,
+ Vertex = 1,
+ Hull = 2,
+ Domain = 3,
+ Geometry = 4,
+ Pixel = 5,
+ Amplification = 6,
+ Mesh = 7,
+};
+
// Definitions of the in-memory data layout structures
// Models the different registers: bReg | tReg | uReg | sReg
@@ -32,6 +45,7 @@ struct Register {
// Models the end of a descriptor table and stores its visibility
struct DescriptorTable {
+ ShaderVisibility Visibility = ShaderVisibility::All;
uint32_t NumClauses = 0; // The number of clauses in the table
};
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
It's strange to me that shader visibility is not a bit mask like in Vulkan, but rather an enum.
This is a DirectX thing though, and not an issue with your PR.
- Defines `parseShaderVisiblity` to establish how single enums will be parsed - Adds unit testing of the visiblity enum Part three of implementing llvm#126569
3896ada
to
c607180
Compare
…ble (llvm#136751) - Defines `parseShaderVisiblity` to establish how single enums will be parsed - Adds unit testing of the visiblity enum Part three of implementing llvm#126569
…ble (llvm#136751) - Defines `parseShaderVisiblity` to establish how single enums will be parsed - Adds unit testing of the visiblity enum Part three of implementing llvm#126569
…ble (llvm#136751) - Defines `parseShaderVisiblity` to establish how single enums will be parsed - Adds unit testing of the visiblity enum Part three of implementing llvm#126569
…ble (llvm#136751) - Defines `parseShaderVisiblity` to establish how single enums will be parsed - Adds unit testing of the visiblity enum Part three of implementing llvm#126569
parseShaderVisiblity
to establish how single enums will be parsedPart three of implementing #126569