[validation] v-15001: front_facing builtin must be boolean

To declare a front_facing builtin variable
- declare as a parameter of the entry point function or it can be
- declared as members of structures that are entry point function parameters
The type of the function-parameter/structure-member must be boolean.

Bug: tint:357
Change-Id: I09c380ae5784d29e776e483d966a0f7d8cd2286c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/53821
Reviewed-by: Sarah Mashayekhi <sarahmashay@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Sarah Mashayekhi <sarahmashay@google.com>
This commit is contained in:
Sarah 2021-06-09 16:01:29 +00:00 committed by Tint LUCI CQ
parent 0d6d905bc0
commit c58738a49e
2 changed files with 92 additions and 0 deletions

View File

@ -20,6 +20,73 @@ namespace {
class ResolverBuiltinsValidationTest : public resolver::TestHelper, class ResolverBuiltinsValidationTest : public resolver::TestHelper,
public testing::Test {}; public testing::Test {};
TEST_F(ResolverBuiltinsValidationTest, FrontFacingParamIsBool_Pass) {
// [[stage(fragment)]]
// fn fs_main(
// [[builtin(front_facing)]] is_front: bool
// ) -> [[location(0)]] f32 { return 1.0; }
auto* is_front =
Param("is_front", ty.bool_(),
ast::DecorationList{Builtin(ast::Builtin::kFrontFacing)});
Func("fs_main", ast::VariableList{is_front}, ty.f32(), {Return(1.0f)},
ast::DecorationList{Stage(ast::PipelineStage::kFragment)},
{Location(0)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverBuiltinsValidationTest, FrontFacingMemberIsBool_Pass) {
// struct MyInputs {
// [[builtin(front_facing)]] pos: bool;
// };
// [[stage(fragment)]]
// fn fragShader(is_front: MyInputs) -> [[location(0)]] f32 { return 1.0; }
auto* s = Structure(
"MyInputs",
{Member("pos", ty.bool_(),
ast::DecorationList{Builtin(ast::Builtin::kFrontFacing)})});
Func("fragShader", {Param("is_front", ty.Of(s))}, ty.f32(), {Return(1.0f)},
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
EXPECT_TRUE(r()->Resolve()) << r()->error();
}
TEST_F(ResolverBuiltinsValidationTest, FrontFacingParamIsNotBool_Fail) {
// [[stage(fragment)]]
// fn fs_main(
// [[builtin(front_facing)]] is_front: i32;
// ) -> [[location(0)]] f32 { return 1.0; }
auto* is_front = Param("is_front", ty.i32(),
ast::DecorationList{Builtin(
Source{{12, 34}}, ast::Builtin::kFrontFacing)});
Func("fs_main", ast::VariableList{is_front}, ty.f32(), {Return(1.0f)},
ast::DecorationList{Stage(ast::PipelineStage::kFragment)},
{Location(0)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error v-15001: front_facing builtin must be boolean");
}
TEST_F(ResolverBuiltinsValidationTest, FrontFacingMemberIsNotBool_Fail) {
// struct MyInputs {
// [[builtin(front_facing)]] pos: f32;
// };
// [[stage(fragment)]]
// fn fragShader(is_front: MyInputs) -> [[location(0)]] f32 { return 1.0; }
auto* s = Structure(
"MyInputs", {Member("pos", ty.f32(),
ast::DecorationList{Builtin(
Source{{12, 34}}, ast::Builtin::kFrontFacing)})});
Func("fragShader", {Param("is_front", ty.Of(s))}, ty.f32(), {Return(1.0f)},
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
"12:34 error v-15001: front_facing builtin must be boolean");
}
TEST_F(ResolverBuiltinsValidationTest, Length_Float_Scalar) { TEST_F(ResolverBuiltinsValidationTest, Length_Float_Scalar) {
auto* builtin = Call("length", 1.0f); auto* builtin = Call("length", 1.0f);
WrapInFunction(builtin); WrapInFunction(builtin);

View File

@ -808,6 +808,21 @@ bool Resolver::ValidateVariable(const VariableInfo* info) {
} }
bool Resolver::ValidateParameter(const VariableInfo* info) { bool Resolver::ValidateParameter(const VariableInfo* info) {
auto* var = info->declaration;
for (auto* deco : var->decorations()) {
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
if (builtin->value() == ast::Builtin::kFrontFacing) {
auto* storage_type = info->type->UnwrapRef();
if (!(storage_type->Is<sem::Bool>())) {
diagnostics_.add_error("v-15001",
"front_facing builtin must be boolean",
deco->source());
return false;
}
}
}
}
return ValidateVariable(info); return ValidateVariable(info);
} }
@ -2876,6 +2891,16 @@ bool Resolver::ValidateStructure(const sem::Struct* str) {
deco->source()); deco->source());
return false; return false;
} }
if (auto* builtin = deco->As<ast::BuiltinDecoration>()) {
if (builtin->value() == ast::Builtin::kFrontFacing) {
if (!(member->Type()->Is<sem::Bool>())) {
diagnostics_.add_error("v-15001",
"front_facing builtin must be boolean",
deco->source());
return false;
}
}
}
} }
} }