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");
}
// 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() {
auto ident = expect_ident("builtin");
if (ident.errored) {
@ -2995,8 +3053,8 @@ Maybe<const ast::Expression*> ParserImpl::expression() {
return logical_or_expression();
}
// compound_assignment_operator:
// | plus_equal
// compound_assignment_operator
// : plus_equal
// | minus_equal
// | times_equal
// | division_equal
@ -3234,37 +3292,25 @@ Maybe<const ast::Attribute*> ParserImpl::attribute() {
if (t == kInterpolateAttribute) {
return expect_paren_block("interpolate attribute", [&]() -> Result {
ast::InterpolationType type;
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
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");
auto type = expect_interpolation_type_name();
if (type.errored) {
return Failure::kErrored;
}
ast::InterpolationSampling sampling = ast::InterpolationSampling::kNone;
if (match(Token::Type::kComma)) {
if (!peek_is(Token::Type::kParenRight)) {
auto& sampling_tok = next();
if (sampling_tok == "center") {
sampling = ast::InterpolationSampling::kCenter;
} 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");
auto sample = expect_interpolation_sample_name();
if (sample.errored) {
return Failure::kErrored;
}
sampling = sample.value;
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
/// @returns the parsed access control.
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
/// valid builtin name.
/// @returns the parsed builtin.

View File

@ -235,7 +235,7 @@ TEST_F(ParserImplTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
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) {
@ -329,7 +329,7 @@ TEST_F(ParserImplTest, Attribute_Interpolate_MissingFirstValue) {
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
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) {