[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:
parent
0d6d905bc0
commit
c58738a49e
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue