mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 23:56:16 +00:00
validation: compute shader must include 'workgroup_size' in its attributes
Bug: tint:884 Change-Id: If96c6df3247fee142a779117fa26d006afd4f7ef Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/55680 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
@@ -273,7 +273,7 @@ TEST_F(ResolverBuiltinsValidationTest, VertexBuiltin_Pass) {
|
||||
}
|
||||
|
||||
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_Pass) {
|
||||
// [[stage(compute)]]
|
||||
// [[stage(compute), workgroup_size(1)]]
|
||||
// fn main(
|
||||
// [[builtin(local_invocationId)]] li_id: vec3<u32>,
|
||||
// [[builtin(local_invocationIndex)]] li_index: u32,
|
||||
|
||||
@@ -271,7 +271,7 @@ TEST_P(EntryPointReturnTypeDecorationTest, IsValid) {
|
||||
|
||||
Func("main", ast::VariableList{}, ty.vec4<f32>(),
|
||||
{Return(Construct(ty.vec4<f32>(), 1.f))},
|
||||
{Stage(ast::PipelineStage::kCompute)},
|
||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)},
|
||||
createDecorations({}, *this, params.kind));
|
||||
|
||||
if (params.should_pass) {
|
||||
@@ -933,6 +933,24 @@ namespace WorkgroupDecorationTests {
|
||||
namespace {
|
||||
|
||||
using WorkgroupDecoration = ResolverTest;
|
||||
TEST_F(WorkgroupDecoration, ComputeShaderPass) {
|
||||
Func("main", {}, ty.void_(), {},
|
||||
{Stage(ast::PipelineStage::kCompute),
|
||||
create<ast::WorkgroupDecoration>(Source{{12, 34}}, Expr(1))});
|
||||
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
TEST_F(WorkgroupDecoration, Missing) {
|
||||
Func(Source{{12, 34}}, "main", {}, ty.void_(), {},
|
||||
{Stage(ast::PipelineStage::kCompute)});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
"12:34 error: a compute shader must include 'workgroup_size' in its "
|
||||
"attributes");
|
||||
}
|
||||
|
||||
TEST_F(WorkgroupDecoration, NotAnEntryPoint) {
|
||||
Func("main", {}, ty.void_(), {},
|
||||
|
||||
@@ -49,12 +49,12 @@ using IntrinsicType = sem::IntrinsicType;
|
||||
using ResolverIntrinsicValidationTest = ResolverTest;
|
||||
|
||||
TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageDirect) {
|
||||
// [[stage(compute)]] fn func { return dpdx(1.0); }
|
||||
// [[stage(compute), workgroup_size(1)]] fn func { return dpdx(1.0); }
|
||||
|
||||
auto* dpdx = create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"),
|
||||
ast::ExpressionList{Expr(1.0f)});
|
||||
Func(Source{{1, 2}}, "func", ast::VariableList{}, ty.void_(), {Ignore(dpdx)},
|
||||
{Stage(ast::PipelineStage::kCompute)});
|
||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
@@ -65,7 +65,7 @@ TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageIndirect) {
|
||||
// fn f0 { return dpdx(1.0); }
|
||||
// fn f1 { f0(); }
|
||||
// fn f2 { f1(); }
|
||||
// [[stage(compute)]] fn main { return f2(); }
|
||||
// [[stage(compute), workgroup_size(1)]] fn main { return f2(); }
|
||||
|
||||
auto* dpdx = create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"),
|
||||
ast::ExpressionList{Expr(1.0f)});
|
||||
@@ -78,7 +78,8 @@ TEST_F(ResolverIntrinsicValidationTest, InvalidPipelineStageIndirect) {
|
||||
{Ignore(Call("f1"))});
|
||||
|
||||
Func(Source{{7, 8}}, "main", ast::VariableList{}, ty.void_(),
|
||||
{Ignore(Call("f2"))}, {Stage(ast::PipelineStage::kCompute)});
|
||||
{Ignore(Call("f2"))},
|
||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(),
|
||||
|
||||
@@ -1365,6 +1365,16 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func,
|
||||
}
|
||||
}
|
||||
|
||||
if (func->pipeline_stage() == ast::PipelineStage::kCompute) {
|
||||
if (!ast::HasDecoration<ast::WorkgroupDecoration>(func->decorations())) {
|
||||
AddError(
|
||||
"a compute shader must include 'workgroup_size' in its "
|
||||
"attributes",
|
||||
func->source());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate there are no resource variable binding collisions
|
||||
std::unordered_map<sem::BindingPoint, const ast::Variable*> binding_points;
|
||||
for (auto* var_info : info->referenced_module_vars) {
|
||||
|
||||
@@ -1107,7 +1107,7 @@ TEST_F(ResolverTest, Function_ReturnStatements) {
|
||||
}
|
||||
|
||||
TEST_F(ResolverTest, Function_WorkgroupSize_NotSet) {
|
||||
// [[stage(compute)]]
|
||||
// [[stage(compute), workgroup_size(1)]]
|
||||
// fn main() {}
|
||||
auto* func = Func("main", ast::VariableList{}, ty.void_(), {}, {});
|
||||
|
||||
@@ -2067,17 +2067,15 @@ TEST_F(ResolverTest, Function_EntryPoints_StageDecoration) {
|
||||
Assign("call_a", Call("a")),
|
||||
Assign("call_b", Call("b")),
|
||||
},
|
||||
ast::DecorationList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
});
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
|
||||
auto* ep_2 = Func("ep_2", params, ty.void_(),
|
||||
{
|
||||
Assign("call_c", Call("c")),
|
||||
},
|
||||
ast::DecorationList{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
});
|
||||
ast::DecorationList{Stage(ast::PipelineStage::kCompute),
|
||||
WorkgroupSize(1)});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
@@ -2154,9 +2152,7 @@ TEST_F(ResolverTest, Function_EntryPoints_LinearTime) {
|
||||
create<ast::CallStatement>(Call(fn_a(0))),
|
||||
create<ast::CallStatement>(Call(fn_b(0))),
|
||||
},
|
||||
{
|
||||
Stage(ast::PipelineStage::kCompute),
|
||||
});
|
||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ TEST_F(ResolverPipelineStageUseTest, StructUsedAsComputeShaderParam) {
|
||||
{Member("a", ty.u32(), {Builtin(ast::Builtin::kLocalInvocationIndex)})});
|
||||
|
||||
Func("main", {Param("param", ty.Of(s))}, ty.void_(), {},
|
||||
{Stage(ast::PipelineStage::kCompute)});
|
||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1)});
|
||||
|
||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user