mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-17 08:57:26 +00:00
Test that entry point IO attributes are of valid types
BUG=tint:773 Change-Id: I94e8624647c645efe7ed558caa3d3bd05dd72f63 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/50260 Commit-Queue: Ryan Harrison <rharrison@chromium.org> Auto-Submit: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Ben Clayton <bclayton@google.com> Reviewed-by: James Price <jrprice@google.com>
This commit is contained in:
committed by
Commit Bot service account
parent
ff7a5f8dc9
commit
74490e118e
@@ -23,13 +23,14 @@
|
||||
#include "gmock/gmock.h"
|
||||
|
||||
namespace tint {
|
||||
namespace resolver {
|
||||
namespace {
|
||||
|
||||
class ResolverEntryPointValidationTest : public resolver::TestHelper,
|
||||
class ResolverEntryPointValidationTest : public TestHelper,
|
||||
public testing::Test {};
|
||||
|
||||
TEST_F(ResolverEntryPointValidationTest, ReturnTypeAttribute_Location) {
|
||||
// [[stage(vertex)]]
|
||||
// [[stage(fragment)]]
|
||||
// fn main() -> [[location(0)]] f32 { return 1.0; }
|
||||
Func(Source{{12, 34}}, "main", {}, ty.f32(), {Return(1.0f)},
|
||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
||||
@@ -514,5 +515,118 @@ TEST_F(ResolverEntryPointValidationTest,
|
||||
"in its return type");
|
||||
}
|
||||
|
||||
namespace TypeValidationTests {
|
||||
struct Params {
|
||||
create_ast_type_func_ptr create_ast_type;
|
||||
bool is_valid;
|
||||
};
|
||||
|
||||
using TypeValidationTest = resolver::ResolverTestWithParam<Params>;
|
||||
|
||||
static constexpr Params cases[] = {
|
||||
{ast_f32, true},
|
||||
{ast_i32, true},
|
||||
{ast_u32, true},
|
||||
{ast_bool, false},
|
||||
{ast_vec2<ast_f32>, true},
|
||||
{ast_vec3<ast_f32>, true},
|
||||
{ast_vec4<ast_f32>, true},
|
||||
{ast_mat2x2<ast_f32>, false},
|
||||
{ast_mat2x2<ast_i32>, false},
|
||||
{ast_mat2x2<ast_u32>, false},
|
||||
{ast_mat2x2<ast_bool>, false},
|
||||
{ast_mat3x3<ast_f32>, false},
|
||||
{ast_mat3x3<ast_i32>, false},
|
||||
{ast_mat3x3<ast_u32>, false},
|
||||
{ast_mat3x3<ast_bool>, false},
|
||||
{ast_mat4x4<ast_f32>, false},
|
||||
{ast_mat4x4<ast_i32>, false},
|
||||
{ast_mat4x4<ast_u32>, false},
|
||||
{ast_mat4x4<ast_bool>, false},
|
||||
{ast_alias<ast_f32>, true},
|
||||
{ast_alias<ast_i32>, true},
|
||||
{ast_alias<ast_u32>, true},
|
||||
{ast_alias<ast_bool>, false},
|
||||
};
|
||||
|
||||
TEST_P(TypeValidationTest, BareInputs) {
|
||||
// [[stage(fragment)]]
|
||||
// fn main([[location(0)]] a : *) {}
|
||||
auto params = GetParam();
|
||||
auto* a = Param("a", params.create_ast_type(ty), {Location(0)});
|
||||
Func(Source{{12, 34}}, "main", {a}, ty.void_(), {},
|
||||
{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
if (params.is_valid) {
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
} else {
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TypeValidationTest, StructInputs) {
|
||||
// struct Input {
|
||||
// [[location(0)]] a : *;
|
||||
// };
|
||||
// [[stage(fragment)]]
|
||||
// fn main(a : Input) {}
|
||||
auto params = GetParam();
|
||||
auto* input = Structure(
|
||||
"Input", {Member("a", params.create_ast_type(ty), {Location(0)})});
|
||||
auto* a = Param("a", input, {});
|
||||
Func(Source{{12, 34}}, "main", {a}, ty.void_(), {},
|
||||
{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
if (params.is_valid) {
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
} else {
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TypeValidationTest, BareOutputs) {
|
||||
// [[stage(fragment)]]
|
||||
// fn main() -> [[location(0)]] * {
|
||||
// return *();
|
||||
// }
|
||||
auto params = GetParam();
|
||||
Func(Source{{12, 34}}, "main", {}, params.create_ast_type(ty),
|
||||
{Return(Construct(params.create_ast_type(ty)))},
|
||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
||||
|
||||
if (params.is_valid) {
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
} else {
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(TypeValidationTest, StructOutputs) {
|
||||
// struct Output {
|
||||
// [[location(0)]] a : *;
|
||||
// };
|
||||
// [[stage(fragment)]]
|
||||
// fn main() -> Output {
|
||||
// return Output();
|
||||
// }
|
||||
auto params = GetParam();
|
||||
auto* output = Structure(
|
||||
"Output", {Member("a", params.create_ast_type(ty), {Location(0)})});
|
||||
Func(Source{{12, 34}}, "main", {}, output, {Return(Construct(output))},
|
||||
{Stage(ast::PipelineStage::kFragment)});
|
||||
|
||||
if (params.is_valid) {
|
||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||
} else {
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
}
|
||||
}
|
||||
INSTANTIATE_TEST_SUITE_P(ResolverEntryPointValidationTest,
|
||||
TypeValidationTest,
|
||||
testing::ValuesIn(cases));
|
||||
|
||||
} // namespace TypeValidationTests
|
||||
|
||||
} // namespace
|
||||
} // namespace resolver
|
||||
} // namespace tint
|
||||
|
||||
@@ -832,6 +832,19 @@ bool Resolver::ValidateEntryPoint(const ast::Function* func,
|
||||
diagnostics_.add_error(err, source);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that all user defined attributes are numeric scalars, vectors
|
||||
// of numeric scalars.
|
||||
// Testing for being a struct is handled by the if portion above.
|
||||
if (!pipeline_io_attribute->Is<ast::BuiltinDecoration>()) {
|
||||
if (!Canonical(ty)->is_numeric_scalar_or_vector()) {
|
||||
diagnostics_.add_error(
|
||||
"User defined entry point IO types must be a numeric scalar, "
|
||||
"a numeric vector, or a structure",
|
||||
source);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user