Extract interpolation sample and type name parsing

This CL pulls the interpolation sample and type name parsing out
to methods to closer match the WGSL spec. This will also make it simpler
to convert to using generated parsing for these strings if desired.

Bug: tint:1633
Change-Id: Ib7b663a3eeef7f3ecacae8bf160d41641b5474f1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/98260
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
dan sinclair 2022-08-04 21:21:37 +00:00 committed by Dawn LUCI CQ
parent 737fd8223e
commit 69a9415084
3 changed files with 89 additions and 35 deletions

View File

@ -1558,6 +1558,64 @@ Expect<ast::PipelineStage> ParserImpl::expect_pipeline_stage() {
return add_error(peek(), "invalid value for stage attribute"); return add_error(peek(), "invalid value for stage attribute");
} }
// interpolation_sample_name
// : 'center'
// | 'centroid'
// | 'sample'
Expect<ast::InterpolationSampling> ParserImpl::expect_interpolation_sample_name() {
auto ident = expect_ident("interpolation sample name");
if (ident.errored) {
return Failure::kErrored;
}
if (ident.value == "center") {
return {ast::InterpolationSampling::kCenter, ident.source};
}
if (ident.value == "centroid") {
return {ast::InterpolationSampling::kCentroid, ident.source};
}
if (ident.value == "sample") {
return {ast::InterpolationSampling::kSample, ident.source};
}
return add_error(ident.source, "invalid interpolation sampling");
}
// interpolation_type_name
// : 'perspective'
// | 'linear'
// | 'flat'
Expect<ast::InterpolationType> ParserImpl::expect_interpolation_type_name() {
auto ident = expect_ident("interpolation type name");
if (ident.errored) {
return Failure::kErrored;
}
if (ident.value == "perspective") {
return {ast::InterpolationType::kPerspective, ident.source};
}
if (ident.value == "linear") {
return {ast::InterpolationType::kLinear, ident.source};
}
if (ident.value == "flat") {
return {ast::InterpolationType::kFlat, ident.source};
}
return add_error(ident.source, "invalid interpolation type");
}
// builtin_value_name
// : 'vertex_index'
// | 'instance_index'
// | 'position'
// | 'front_facing'
// | 'frag_depth'
// | 'local_invocation_id'
// | 'local_invocation_index'
// | 'global_invocation_id'
// | 'workgroup_id'
// | 'num_workgroups'
// | 'sample_index'
// | 'sample_mask'
Expect<ast::BuiltinValue> ParserImpl::expect_builtin() { Expect<ast::BuiltinValue> ParserImpl::expect_builtin() {
auto ident = expect_ident("builtin"); auto ident = expect_ident("builtin");
if (ident.errored) { if (ident.errored) {
@ -2995,8 +3053,8 @@ Maybe<const ast::Expression*> ParserImpl::expression() {
return logical_or_expression(); return logical_or_expression();
} }
// compound_assignment_operator: // compound_assignment_operator
// | plus_equal // : plus_equal
// | minus_equal // | minus_equal
// | times_equal // | times_equal
// | division_equal // | division_equal
@ -3234,37 +3292,25 @@ Maybe<const ast::Attribute*> ParserImpl::attribute() {
if (t == kInterpolateAttribute) { if (t == kInterpolateAttribute) {
return expect_paren_block("interpolate attribute", [&]() -> Result { return expect_paren_block("interpolate attribute", [&]() -> Result {
ast::InterpolationType type; auto type = expect_interpolation_type_name();
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone; if (type.errored) {
return Failure::kErrored;
auto& type_tok = next();
if (type_tok == "perspective") {
type = ast::InterpolationType::kPerspective;
} else if (type_tok == "linear") {
type = ast::InterpolationType::kLinear;
} else if (type_tok == "flat") {
type = ast::InterpolationType::kFlat;
} else {
return add_error(type_tok, "invalid interpolation type");
} }
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
if (match(Token::Type::kComma)) { if (match(Token::Type::kComma)) {
if (!peek_is(Token::Type::kParenRight)) { if (!peek_is(Token::Type::kParenRight)) {
auto& sampling_tok = next(); auto sample = expect_interpolation_sample_name();
if (sampling_tok == "center") { if (sample.errored) {
sampling = ast::InterpolationSampling::kCenter; return Failure::kErrored;
} else if (sampling_tok == "centroid") {
sampling = ast::InterpolationSampling::kCentroid;
} else if (sampling_tok == "sample") {
sampling = ast::InterpolationSampling::kSample;
} else {
return add_error(sampling_tok, "invalid interpolation sampling");
} }
sampling = sample.value;
match(Token::Type::kComma); match(Token::Type::kComma);
} }
} }
return create<ast::InterpolateAttribute>(t.source(), type, sampling); return create<ast::InterpolateAttribute>(t.source(), type.value, sampling);
}); });
} }

View File

@ -493,6 +493,14 @@ class ParserImpl {
/// @param use a description of what was being parsed if an error was raised /// @param use a description of what was being parsed if an error was raised
/// @returns the parsed access control. /// @returns the parsed access control.
Expect<ast::Access> expect_access(std::string_view use); Expect<ast::Access> expect_access(std::string_view use);
/// Parses an interpolation sample name identifier, erroring if the next token does not match a
/// valid sample name.
/// @returns the parsed sample name.
Expect<ast::InterpolationSampling> expect_interpolation_sample_name();
/// Parses an interpolation type name identifier, erroring if the next token does not match a
/// value type name.
/// @returns the parsed type name
Expect<ast::InterpolationType> expect_interpolation_type_name();
/// Parses a builtin identifier, erroring if the next token does not match a /// Parses a builtin identifier, erroring if the next token does not match a
/// valid builtin name. /// valid builtin name.
/// @returns the parsed builtin. /// @returns the parsed builtin.

View File

@ -235,7 +235,7 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
EXPECT_TRUE(attr.errored); EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr); EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:18: invalid interpolation sampling"); EXPECT_EQ(p->error(), "1:18: expected identifier for interpolation sample name");
} }
TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) { TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) {
@ -329,7 +329,7 @@ TEST_F(ParserImplTest, Attribute_Interpolate_MissingFirstValue) {
EXPECT_TRUE(attr.errored); EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr); EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error()); EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:13: invalid interpolation type"); EXPECT_EQ(p->error(), "1:13: expected identifier for interpolation type name");
} }
TEST_F(ParserImplTest, Attribute_Interpolate_InvalidFirstValue) { TEST_F(ParserImplTest, Attribute_Interpolate_InvalidFirstValue) {