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:
parent
1ad896df11
commit
f0c150b01b
|
@ -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";
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue