validation: location decoration is not valid for compute shaders
Bug: tint:981
Change-Id: I15024e0cf836af4f3ad7a14b8cd51c24fc3cd536
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/58067
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Auto-Submit: Sarah Mashayekhi <sarahmashay@google.com>
diff --git a/src/resolver/decoration_validation_test.cc b/src/resolver/decoration_validation_test.cc
index 6b893ac..6e9aa0a 100644
--- a/src/resolver/decoration_validation_test.cc
+++ b/src/resolver/decoration_validation_test.cc
@@ -146,7 +146,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"error: decoration is not valid for non-entry point function "
"parameters");
@@ -184,7 +184,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"error: decoration is not valid for function parameters");
}
@@ -197,7 +197,8 @@
TestParams{DecorationKind::kBuiltin, true},
TestParams{DecorationKind::kGroup, false},
TestParams{DecorationKind::kInterpolate, true},
- TestParams{DecorationKind::kInvariant, false},
+ // TODO(crbug.com/tint/1008)
+ // kInvariant tested separately (requires position builtin)
TestParams{DecorationKind::kLocation, true},
TestParams{DecorationKind::kOverride, false},
TestParams{DecorationKind::kOffset, false},
@@ -238,6 +239,19 @@
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
+TEST_F(EntryPointParameterDecorationTest, ComputeShaderLocation) {
+ auto* input = Param("input", ty.vec4<f32>(),
+ ast::DecorationList{Location(Source{{12, 34}}, 1)});
+ Func("main", {input}, ty.void_(), {},
+ {Stage(ast::PipelineStage::kCompute),
+ create<ast::WorkgroupDecoration>(Source{{12, 34}}, Expr(1))});
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(),
+ "12:34 error: decoration is not valid for compute shader function "
+ "parameters");
+}
+
using FunctionReturnTypeDecorationTest = TestWithParams;
TEST_P(FunctionReturnTypeDecorationTest, IsValid) {
auto& params = GetParam();
@@ -248,7 +262,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"error: decoration is not valid for non-entry point function "
"return types");
@@ -285,9 +299,16 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
- EXPECT_EQ(r()->error(),
- "error: decoration is not valid for entry point return types");
+ EXPECT_FALSE(r()->Resolve());
+ if (params.kind == DecorationKind::kLocation ||
+ params.kind == DecorationKind::kInterpolate) {
+ EXPECT_EQ(r()->error(),
+ "error: decoration is not valid for compute shader entry point "
+ "return types");
+ } else {
+ EXPECT_EQ(r()->error(),
+ "error: decoration is not valid for entry point return types");
+ }
}
}
@@ -298,9 +319,9 @@
TestParams{DecorationKind::kBinding, false},
TestParams{DecorationKind::kBuiltin, true},
TestParams{DecorationKind::kGroup, false},
- TestParams{DecorationKind::kInterpolate, true},
+ TestParams{DecorationKind::kInterpolate, false},
// kInvariant tested separately (requires position builtin)
- TestParams{DecorationKind::kLocation, true},
+ TestParams{DecorationKind::kLocation, false},
TestParams{DecorationKind::kOverride, false},
TestParams{DecorationKind::kOffset, false},
TestParams{DecorationKind::kSize, false},
@@ -367,7 +388,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: decoration is not valid for array types");
}
@@ -403,7 +424,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: decoration is not valid for struct declarations");
}
@@ -467,7 +488,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: decoration is not valid for structure members");
}
@@ -528,7 +549,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
if (!IsBindingDecoration(params.kind)) {
EXPECT_EQ(r()->error(),
"12:34 error: decoration is not valid for variables");
@@ -582,7 +603,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: decoration is not valid for constants");
}
@@ -632,7 +653,7 @@
if (params.should_pass) {
EXPECT_TRUE(r()->Resolve()) << r()->error();
} else {
- EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error: decoration is not valid for functions");
}
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index 604972b..dd37815 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -1165,7 +1165,14 @@
if (!ValidateInterpolateDecoration(interpolate, info->type)) {
return false;
}
- } else if (!deco->IsAnyOf<ast::LocationDecoration, ast::BuiltinDecoration,
+ } else if (deco->Is<ast::LocationDecoration>()) {
+ if (func->pipeline_stage() == ast::PipelineStage::kCompute) {
+ AddError(
+ "decoration is not valid for compute shader function parameters",
+ deco->source());
+ return false;
+ }
+ } else if (!deco->IsAnyOf<ast::BuiltinDecoration,
ast::InternalDecoration>() &&
(IsValidationEnabled(
info->declaration->decorations(),
@@ -1421,9 +1428,16 @@
if (!ValidateInterpolateDecoration(interpolate, info->return_type)) {
return false;
}
- } else if (!deco->IsAnyOf<ast::LocationDecoration, ast::BuiltinDecoration,
- ast::InvariantDecoration,
- ast::InternalDecoration>() &&
+ } else if (deco->Is<ast::LocationDecoration>()) {
+ if (func->pipeline_stage() == ast::PipelineStage::kCompute) {
+ AddError(
+ "decoration is not valid for compute shader entry point return "
+ "types",
+ deco->source());
+ return false;
+ }
+ } else if (!deco->IsAnyOf<ast::BuiltinDecoration, ast::InternalDecoration,
+ ast::InvariantDecoration>() &&
(IsValidationEnabled(
info->declaration->decorations(),
ast::DisabledValidation::kEntryPointParameter) &&