Add parsing of shorter stage attributes.

This CL adds the ability to parse the `@compute`, `@fragment` and
`@vertex` attrbutes. The `@stage(...)` are still accepted and are not
marked as deprecated yet.

Most tests are still using `@stage(..)` except for a testing one.

Bug: tint:1503
Change-Id: I85cad5996605035e83109b021ffb13db98b1a144
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/92480
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Auto-Submit: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Reviewed-by: Ryan Harrison <rharrison@chromium.org>
This commit is contained in:
dan sinclair 2022-06-03 02:47:40 +00:00 committed by Dawn LUCI CQ
parent 1ad896df11
commit f0c150b01b
6 changed files with 100 additions and 6 deletions

View File

@ -3258,9 +3258,38 @@ Maybe<const ast::Attribute*> ParserImpl::attribute() {
return Failure::kErrored; return Failure::kErrored;
} }
// TODO(crbug.com/tint/1503): Enable this once all the Dawn and CTS
// tests are updated to use the new format so we can avoid spamming
// the log files.
if ((false)) {
std::string warning = "stage should use @";
switch (stage.value) {
case ast::PipelineStage::kVertex:
warning += "vertex";
break;
case ast::PipelineStage::kFragment:
warning += "fragment";
break;
case ast::PipelineStage::kCompute:
warning += "compute";
break;
case ast::PipelineStage::kNone:
break;
}
deprecated(t.source(), warning);
}
return create<ast::StageAttribute>(t.source(), stage.value); return create<ast::StageAttribute>(t.source(), stage.value);
}); });
} }
if (t == kComputeStage) {
return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kCompute);
}
if (t == kVertexStage) {
return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kVertex);
}
if (t == kFragmentStage) {
return create<ast::StageAttribute>(t.source(), ast::PipelineStage::kFragment);
}
if (t == kSizeAttribute) { if (t == kSizeAttribute) {
const char* use = "size attribute"; const char* use = "size attribute";

View File

@ -18,7 +18,7 @@
namespace tint::reader::wgsl { namespace tint::reader::wgsl {
namespace { namespace {
TEST_F(ParserImplTest, AttributeList_Parses) { TEST_F(ParserImplTest, AttributeList_Parses_Stage) {
auto p = parser("@workgroup_size(2) @stage(compute)"); auto p = parser("@workgroup_size(2) @stage(compute)");
auto attrs = p->attribute_list(); auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error(); EXPECT_FALSE(p->has_error()) << p->error();
@ -44,6 +44,32 @@ TEST_F(ParserImplTest, AttributeList_Parses) {
EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute); EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
} }
TEST_F(ParserImplTest, AttributeList_Parses) {
auto p = parser("@workgroup_size(2) @compute");
auto attrs = p->attribute_list();
EXPECT_FALSE(p->has_error()) << p->error();
EXPECT_FALSE(attrs.errored);
EXPECT_TRUE(attrs.matched);
ASSERT_EQ(attrs.value.size(), 2u);
auto* attr_0 = attrs.value[0]->As<ast::Attribute>();
auto* attr_1 = attrs.value[1]->As<ast::Attribute>();
ASSERT_NE(attr_0, nullptr);
ASSERT_NE(attr_1, nullptr);
ASSERT_TRUE(attr_0->Is<ast::WorkgroupAttribute>());
const ast::Expression* x = attr_0->As<ast::WorkgroupAttribute>()->x;
ASSERT_NE(x, nullptr);
auto* x_literal = x->As<ast::LiteralExpression>();
ASSERT_NE(x_literal, nullptr);
ASSERT_TRUE(x_literal->Is<ast::IntLiteralExpression>());
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->value, 2);
EXPECT_EQ(x_literal->As<ast::IntLiteralExpression>()->suffix,
ast::IntLiteralExpression::Suffix::kNone);
ASSERT_TRUE(attr_1->Is<ast::StageAttribute>());
EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, AttributeList_Invalid) { TEST_F(ParserImplTest, AttributeList_Invalid) {
auto p = parser("@invalid"); auto p = parser("@invalid");
auto attrs = p->attribute_list(); auto attrs = p->attribute_list();

View File

@ -265,5 +265,44 @@ TEST_F(ParserImplTest, Attribute_Stage_MissingRightParen) {
EXPECT_EQ(p->error(), "1:14: expected ')' for stage attribute"); EXPECT_EQ(p->error(), "1:14: expected ')' for stage attribute");
} }
TEST_F(ParserImplTest, Attribute_Compute) {
auto p = parser("compute");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::StageAttribute>());
EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
}
TEST_F(ParserImplTest, Attribute_Vertex) {
auto p = parser("vertex");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::StageAttribute>());
EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage, ast::PipelineStage::kVertex);
}
TEST_F(ParserImplTest, Attribute_Fragment) {
auto p = parser("fragment");
auto attr = p->attribute();
EXPECT_TRUE(attr.matched);
EXPECT_FALSE(attr.errored);
ASSERT_NE(attr.value, nullptr) << p->error();
ASSERT_FALSE(p->has_error());
auto* func_attr = attr.value->As<ast::Attribute>();
ASSERT_NE(func_attr, nullptr);
ASSERT_TRUE(func_attr->Is<ast::StageAttribute>());
EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage, ast::PipelineStage::kFragment);
}
} // namespace } // namespace
} // namespace tint::reader::wgsl } // namespace tint::reader::wgsl

View File

@ -34,7 +34,7 @@ namespace tint::transform {
/// @location(2) loc2 : vec4<u32>; /// @location(2) loc2 : vec4<u32>;
/// }; /// };
/// ///
/// @stage(fragment) /// @fragment
/// fn frag_main(@builtin(position) coord : vec4<f32>, /// fn frag_main(@builtin(position) coord : vec4<f32>,
/// locations : Locations) -> @location(0) f32 { /// locations : Locations) -> @location(0) f32 {
/// if (coord.w > 1.0) { /// if (coord.w > 1.0) {
@ -71,7 +71,7 @@ namespace tint::transform {
/// return col; /// return col;
/// } /// }
/// ///
/// @stage(fragment) /// @fragment
/// fn frag_main(in : frag_main_in) -> frag_main_out { /// fn frag_main(in : frag_main_in) -> frag_main_out {
/// let inner_retval = frag_main_inner(in.coord, Locations(in.loc1, in.loc2)); /// let inner_retval = frag_main_inner(in.coord, Locations(in.loc1, in.loc2));
/// var wrapper_result : frag_main_out; /// var wrapper_result : frag_main_out;

View File

@ -43,7 +43,7 @@ namespace tint::transform {
/// p = p + f; /// p = p + f;
/// } /// }
/// ///
/// @stage(compute) @workgroup_size(1) /// @compute @workgroup_size(1)
/// fn main() { /// fn main() {
/// foo(); /// foo();
/// } /// }
@ -55,7 +55,7 @@ namespace tint::transform {
/// *p = *p + (*sptr).f; /// *p = *p + (*sptr).f;
/// } /// }
/// ///
/// @stage(compute) @workgroup_size(1) /// @compute @workgroup_size(1)
/// fn main(sptr : ptr<storage, S, read>) { /// fn main(sptr : ptr<storage, S, read>) {
/// var<private> p : f32 = 2.0; /// var<private> p : f32 = 2.0;
/// foo(&p, sptr); /// foo(&p, sptr);

View File

@ -1,4 +1,4 @@
@stage(compute) @workgroup_size(1) @compute @workgroup_size(1)
fn main( fn main(
@builtin(local_invocation_id) local_invocation_id : vec3<u32>, @builtin(local_invocation_id) local_invocation_id : vec3<u32>,
@builtin(local_invocation_index) local_invocation_index : u32, @builtin(local_invocation_index) local_invocation_index : u32,