[HLSL][RootSignature] Add parsing for empty RootDescriptors (#140147)
- define the RootDescriptor in-memory struct containing its type - add test harness for testing First part of https://github.com/llvm/llvm-project/issues/126577
This commit is contained in:
parent
4f869e0f5c
commit
b499f7f2b2
@ -73,6 +73,7 @@ private:
|
||||
/// Root Element parse methods:
|
||||
std::optional<llvm::hlsl::rootsig::RootFlags> parseRootFlags();
|
||||
std::optional<llvm::hlsl::rootsig::RootConstants> parseRootConstants();
|
||||
std::optional<llvm::hlsl::rootsig::RootDescriptor> parseRootDescriptor();
|
||||
std::optional<llvm::hlsl::rootsig::DescriptorTable> parseDescriptorTable();
|
||||
std::optional<llvm::hlsl::rootsig::DescriptorTableClause>
|
||||
parseDescriptorTableClause();
|
||||
|
@ -47,6 +47,14 @@ bool RootSignatureParser::parse() {
|
||||
return true;
|
||||
Elements.push_back(*Table);
|
||||
}
|
||||
|
||||
if (tryConsumeExpectedToken(
|
||||
{TokenKind::kw_CBV, TokenKind::kw_SRV, TokenKind::kw_UAV})) {
|
||||
auto Descriptor = parseRootDescriptor();
|
||||
if (!Descriptor.has_value())
|
||||
return true;
|
||||
Elements.push_back(*Descriptor);
|
||||
}
|
||||
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
|
||||
|
||||
return consumeExpectedToken(TokenKind::end_of_stream,
|
||||
@ -155,6 +163,41 @@ std::optional<RootConstants> RootSignatureParser::parseRootConstants() {
|
||||
return Constants;
|
||||
}
|
||||
|
||||
std::optional<RootDescriptor> RootSignatureParser::parseRootDescriptor() {
|
||||
assert((CurToken.TokKind == TokenKind::kw_CBV ||
|
||||
CurToken.TokKind == TokenKind::kw_SRV ||
|
||||
CurToken.TokKind == TokenKind::kw_UAV) &&
|
||||
"Expects to only be invoked starting at given keyword");
|
||||
|
||||
TokenKind DescriptorKind = CurToken.TokKind;
|
||||
|
||||
if (consumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
|
||||
CurToken.TokKind))
|
||||
return std::nullopt;
|
||||
|
||||
RootDescriptor Descriptor;
|
||||
switch (DescriptorKind) {
|
||||
default:
|
||||
llvm_unreachable("Switch for consumed token was not provided");
|
||||
case TokenKind::kw_CBV:
|
||||
Descriptor.Type = DescriptorType::CBuffer;
|
||||
break;
|
||||
case TokenKind::kw_SRV:
|
||||
Descriptor.Type = DescriptorType::SRV;
|
||||
break;
|
||||
case TokenKind::kw_UAV:
|
||||
Descriptor.Type = DescriptorType::UAV;
|
||||
break;
|
||||
}
|
||||
|
||||
if (consumeExpectedToken(TokenKind::pu_r_paren,
|
||||
diag::err_hlsl_unexpected_end_of_params,
|
||||
/*param of=*/TokenKind::kw_RootConstants))
|
||||
return std::nullopt;
|
||||
|
||||
return Descriptor;
|
||||
}
|
||||
|
||||
std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
|
||||
assert(CurToken.TokKind == TokenKind::kw_DescriptorTable &&
|
||||
"Expects to only be invoked starting at given keyword");
|
||||
|
@ -344,6 +344,43 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) {
|
||||
ASSERT_TRUE(Consumer->isSatisfied());
|
||||
}
|
||||
|
||||
TEST_F(ParseHLSLRootSignatureTest, ValidParseRootDescriptorsTest) {
|
||||
const llvm::StringLiteral Source = R"cc(
|
||||
CBV(),
|
||||
SRV(),
|
||||
UAV()
|
||||
)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(), 3u);
|
||||
|
||||
RootElement Elem = Elements[0];
|
||||
ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
|
||||
ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::CBuffer);
|
||||
|
||||
Elem = Elements[1];
|
||||
ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
|
||||
ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::SRV);
|
||||
|
||||
Elem = Elements[2];
|
||||
ASSERT_TRUE(std::holds_alternative<RootDescriptor>(Elem));
|
||||
ASSERT_EQ(std::get<RootDescriptor>(Elem).Type, DescriptorType::UAV);
|
||||
|
||||
ASSERT_TRUE(Consumer->isSatisfied());
|
||||
}
|
||||
|
||||
TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
|
||||
// This test will checks we can handling trailing commas ','
|
||||
const llvm::StringLiteral Source = R"cc(
|
||||
|
@ -85,6 +85,12 @@ struct RootConstants {
|
||||
ShaderVisibility Visibility = ShaderVisibility::All;
|
||||
};
|
||||
|
||||
using DescriptorType = llvm::dxil::ResourceClass;
|
||||
// Models RootDescriptor : CBV | SRV | UAV, by collecting like parameters
|
||||
struct RootDescriptor {
|
||||
DescriptorType Type;
|
||||
};
|
||||
|
||||
// Models the end of a descriptor table and stores its visibility
|
||||
struct DescriptorTable {
|
||||
ShaderVisibility Visibility = ShaderVisibility::All;
|
||||
@ -125,8 +131,8 @@ struct DescriptorTableClause {
|
||||
void dump(raw_ostream &OS) const;
|
||||
};
|
||||
|
||||
/// Models RootElement : RootFlags | RootConstants | DescriptorTable
|
||||
/// | DescriptorTableClause
|
||||
/// Models RootElement : RootFlags | RootConstants | RootDescriptor
|
||||
/// | DescriptorTable | DescriptorTableClause
|
||||
///
|
||||
/// 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.
|
||||
@ -140,8 +146,8 @@ struct DescriptorTableClause {
|
||||
/// 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, DescriptorTable,
|
||||
DescriptorTableClause>;
|
||||
using RootElement = std::variant<RootFlags, RootConstants, RootDescriptor,
|
||||
DescriptorTable, DescriptorTableClause>;
|
||||
|
||||
void dumpRootElements(raw_ostream &OS, ArrayRef<RootElement> Elements);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user