tint: Clean up Func() usage
Drop the vector typename from the initializer lists. These don't really provide any significant help in understanding the arguments types, as the list of element types can be easily inferred. This is done to simplify the refactor ast::VariableList -> ast::ParameterList. Bug: tint:1580 Change-Id: Ibf8564ca9b2bafd2eaa2e4aa54c29be6bbe7a682 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/93600 Reviewed-by: Antonio Maiorano <amaiorano@google.com> Commit-Queue: Ben Clayton <bclayton@chromium.org>
This commit is contained in:
parent
93928b0d19
commit
7164b97272
|
@ -26,11 +26,10 @@ namespace {
|
||||||
using FunctionTest = TestHelper;
|
using FunctionTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(FunctionTest, Creation) {
|
TEST_F(FunctionTest, Creation) {
|
||||||
VariableList params;
|
VariableList params{Param("var", ty.i32())};
|
||||||
params.push_back(Param("var", ty.i32()));
|
|
||||||
auto* var = params[0];
|
auto* var = params[0];
|
||||||
|
|
||||||
auto* f = Func("func", params, ty.void_(), StatementList{}, AttributeList{});
|
auto* f = Func("func", params, ty.void_(), {});
|
||||||
EXPECT_EQ(f->symbol, Symbols().Get("func"));
|
EXPECT_EQ(f->symbol, Symbols().Get("func"));
|
||||||
ASSERT_EQ(f->params.size(), 1u);
|
ASSERT_EQ(f->params.size(), 1u);
|
||||||
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
EXPECT_TRUE(f->return_type->Is<ast::Void>());
|
||||||
|
@ -38,11 +37,9 @@ TEST_F(FunctionTest, Creation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FunctionTest, Creation_WithSource) {
|
TEST_F(FunctionTest, Creation_WithSource) {
|
||||||
VariableList params;
|
VariableList params{Param("var", ty.i32())};
|
||||||
params.push_back(Param("var", ty.i32()));
|
|
||||||
|
|
||||||
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(), StatementList{},
|
auto* f = Func(Source{Source::Location{20, 2}}, "func", params, ty.void_(), {});
|
||||||
AttributeList{});
|
|
||||||
auto src = f->source;
|
auto src = f->source;
|
||||||
EXPECT_EQ(src.range.begin.line, 20u);
|
EXPECT_EQ(src.range.begin.line, 20u);
|
||||||
EXPECT_EQ(src.range.begin.column, 2u);
|
EXPECT_EQ(src.range.begin.column, 2u);
|
||||||
|
@ -52,7 +49,7 @@ TEST_F(FunctionTest, Assert_InvalidName) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.Func("", VariableList{}, b.ty.void_(), StatementList{}, AttributeList{});
|
b.Func("", {}, b.ty.void_(), {});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -61,7 +58,7 @@ TEST_F(FunctionTest, Assert_Null_ReturnType) {
|
||||||
EXPECT_FATAL_FAILURE(
|
EXPECT_FATAL_FAILURE(
|
||||||
{
|
{
|
||||||
ProgramBuilder b;
|
ProgramBuilder b;
|
||||||
b.Func("f", VariableList{}, nullptr, StatementList{}, AttributeList{});
|
b.Func("f", {}, nullptr, {});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -74,7 +71,7 @@ TEST_F(FunctionTest, Assert_Null_Param) {
|
||||||
params.push_back(b.Param("var", b.ty.i32()));
|
params.push_back(b.Param("var", b.ty.i32()));
|
||||||
params.push_back(nullptr);
|
params.push_back(nullptr);
|
||||||
|
|
||||||
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
|
b.Func("f", params, b.ty.void_(), {});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -84,7 +81,7 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_Symbol) {
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.Func(b2.Sym("func"), VariableList{}, b1.ty.void_(), StatementList{});
|
b1.Func(b2.Sym("func"), {}, b1.ty.void_(), {});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -94,8 +91,7 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.Func("func", VariableList{b2.Param("var", b2.ty.i32())}, b1.ty.void_(),
|
b1.Func("func", {b2.Param("var", b2.ty.i32())}, b1.ty.void_(), {});
|
||||||
StatementList{});
|
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -105,8 +101,8 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_Attr) {
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{},
|
b1.Func("func", {}, b1.ty.void_(), {},
|
||||||
AttributeList{
|
{
|
||||||
b2.WorkgroupSize(2_i, 4_i, 6_i),
|
b2.WorkgroupSize(2_i, 4_i, 6_i),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -118,8 +114,8 @@ TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnAttr) {
|
||||||
{
|
{
|
||||||
ProgramBuilder b1;
|
ProgramBuilder b1;
|
||||||
ProgramBuilder b2;
|
ProgramBuilder b2;
|
||||||
b1.Func("func", VariableList{}, b1.ty.void_(), StatementList{}, AttributeList{},
|
b1.Func("func", {}, b1.ty.void_(), {}, {},
|
||||||
AttributeList{
|
{
|
||||||
b2.WorkgroupSize(2_i, 4_i, 6_i),
|
b2.WorkgroupSize(2_i, 4_i, 6_i),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -133,7 +129,7 @@ TEST_F(FunctionTest, Assert_NonConstParam) {
|
||||||
VariableList params;
|
VariableList params;
|
||||||
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
|
params.push_back(b.Var("var", b.ty.i32(), ast::StorageClass::kNone));
|
||||||
|
|
||||||
b.Func("f", params, b.ty.void_(), StatementList{}, AttributeList{});
|
b.Func("f", params, b.ty.void_(), {});
|
||||||
},
|
},
|
||||||
"internal compiler error");
|
"internal compiler error");
|
||||||
}
|
}
|
||||||
|
@ -141,7 +137,7 @@ TEST_F(FunctionTest, Assert_NonConstParam) {
|
||||||
using FunctionListTest = TestHelper;
|
using FunctionListTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(FunctionListTest, FindSymbol) {
|
TEST_F(FunctionListTest, FindSymbol) {
|
||||||
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{}, ast::AttributeList{});
|
auto* func = Func("main", {}, ty.f32(), {});
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
list.Add(func);
|
list.Add(func);
|
||||||
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
|
EXPECT_EQ(func, list.Find(Symbols().Register("main")));
|
||||||
|
@ -153,12 +149,12 @@ TEST_F(FunctionListTest, FindSymbolMissing) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(FunctionListTest, FindSymbolStage) {
|
TEST_F(FunctionListTest, FindSymbolStage) {
|
||||||
auto* fs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
auto* fs = Func("main", {}, ty.f32(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(PipelineStage::kFragment),
|
Stage(PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
auto* vs = Func("main", VariableList{}, ty.f32(), StatementList{},
|
auto* vs = Func("main", {}, ty.f32(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(PipelineStage::kVertex),
|
Stage(PipelineStage::kVertex),
|
||||||
});
|
});
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
|
@ -170,8 +166,8 @@ TEST_F(FunctionListTest, FindSymbolStage) {
|
||||||
|
|
||||||
TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
list.Add(Func("main", {}, ty.f32(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(PipelineStage::kFragment),
|
Stage(PipelineStage::kFragment),
|
||||||
}));
|
}));
|
||||||
EXPECT_EQ(nullptr, list.Find(Symbols().Register("main"), PipelineStage::kVertex));
|
EXPECT_EQ(nullptr, list.Find(Symbols().Register("main"), PipelineStage::kVertex));
|
||||||
|
@ -179,8 +175,8 @@ TEST_F(FunctionListTest, FindSymbolStageMissing) {
|
||||||
|
|
||||||
TEST_F(FunctionListTest, HasStage) {
|
TEST_F(FunctionListTest, HasStage) {
|
||||||
FunctionList list;
|
FunctionList list;
|
||||||
list.Add(Func("main", VariableList{}, ty.f32(), StatementList{},
|
list.Add(Func("main", {}, ty.f32(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(PipelineStage::kFragment),
|
Stage(PipelineStage::kFragment),
|
||||||
}));
|
}));
|
||||||
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
|
EXPECT_TRUE(list.HasStage(PipelineStage::kFragment));
|
||||||
|
|
|
@ -26,7 +26,7 @@ TEST_F(ModuleTest, Creation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ModuleTest, LookupFunction) {
|
TEST_F(ModuleTest, LookupFunction) {
|
||||||
auto* func = Func("main", VariableList{}, ty.f32(), StatementList{}, ast::AttributeList{});
|
auto* func = Func("main", {}, ty.f32(), {});
|
||||||
|
|
||||||
Program program(std::move(*this));
|
Program program(std::move(*this));
|
||||||
EXPECT_EQ(func, program.AST().Functions().Find(program.Symbols().Get("main")));
|
EXPECT_EQ(func, program.AST().Functions().Find(program.Symbols().Get("main")));
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -28,7 +28,7 @@ InspectorBuilder::InspectorBuilder() = default;
|
||||||
InspectorBuilder::~InspectorBuilder() = default;
|
InspectorBuilder::~InspectorBuilder() = default;
|
||||||
|
|
||||||
void InspectorBuilder::MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes) {
|
void InspectorBuilder::MakeEmptyBodyFunction(std::string name, ast::AttributeList attributes) {
|
||||||
Func(name, ast::VariableList(), ty.void_(), ast::StatementList{Return()}, attributes);
|
Func(name, {}, ty.void_(), {Return()}, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
||||||
|
@ -41,7 +41,7 @@ void InspectorBuilder::MakeCallerBodyFunction(std::string caller,
|
||||||
}
|
}
|
||||||
body.push_back(Return());
|
body.push_back(Return());
|
||||||
|
|
||||||
Func(caller, ast::VariableList(), ty.void_(), body, attributes);
|
Func(caller, {}, ty.void_(), body, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Struct* InspectorBuilder::MakeInOutStruct(
|
const ast::Struct* InspectorBuilder::MakeInOutStruct(
|
||||||
|
@ -67,7 +67,7 @@ const ast::Function* InspectorBuilder::MakePlainGlobalReferenceBodyFunction(
|
||||||
stmts.emplace_back(Assign("local_" + var, var));
|
stmts.emplace_back(Assign("local_" + var, var));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func, ast::VariableList(), ty.void_(), stmts, attributes);
|
return Func(func, {}, ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec,
|
bool InspectorBuilder::ContainsName(const std::vector<StageVariable>& vec,
|
||||||
|
@ -169,7 +169,7 @@ void InspectorBuilder::MakeStructVariableReferenceBodyFunction(
|
||||||
|
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
Func(func_name, ast::VariableList(), ty.void_(), stmts, ast::AttributeList{});
|
Func(func_name, {}, ty.void_(), stmts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InspectorBuilder::AddSampler(const std::string& name, uint32_t group, uint32_t binding) {
|
void InspectorBuilder::AddSampler(const std::string& name, uint32_t group, uint32_t binding) {
|
||||||
|
@ -221,7 +221,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
||||||
Assign(result_name, Call("textureSample", texture_name, sampler_name, coords_name)));
|
Assign(result_name, Call("textureSample", texture_name, sampler_name, coords_name)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
return Func(func_name, {}, ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
||||||
|
@ -242,7 +242,7 @@ const ast::Function* InspectorBuilder::MakeSamplerReferenceBodyFunction(
|
||||||
coords_name, array_index)));
|
coords_name, array_index)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
return Func(func_name, {}, ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
|
const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunction(
|
||||||
|
@ -262,7 +262,7 @@ const ast::Function* InspectorBuilder::MakeComparisonSamplerReferenceBodyFunctio
|
||||||
sampler_name, coords_name, depth_name)));
|
sampler_name, coords_name, depth_name)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
return Func(func_name, {}, ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Type* InspectorBuilder::GetBaseType(ResourceBinding::SampledKind sampled_kind) {
|
const ast::Type* InspectorBuilder::GetBaseType(ResourceBinding::SampledKind sampled_kind) {
|
||||||
|
@ -323,7 +323,7 @@ const ast::Function* InspectorBuilder::MakeStorageTextureBodyFunction(
|
||||||
stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
|
stmts.emplace_back(Assign("dim", Call("textureDimensions", st_name)));
|
||||||
stmts.emplace_back(Return());
|
stmts.emplace_back(Return());
|
||||||
|
|
||||||
return Func(func_name, ast::VariableList(), ty.void_(), stmts, attributes);
|
return Func(func_name, {}, ty.void_(), stmts, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(ComponentType component,
|
std::function<const ast::Type*()> InspectorBuilder::GetTypeFunction(ComponentType component,
|
||||||
|
|
|
@ -126,9 +126,11 @@ const ast::Statement* ProgramBuilder::WrapInStatement(const ast::Statement* stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::Function* ProgramBuilder::WrapInFunction(const ast::StatementList stmts) {
|
const ast::Function* ProgramBuilder::WrapInFunction(const ast::StatementList stmts) {
|
||||||
return Func(
|
return Func("test_function", {}, ty.void_(), std::move(stmts),
|
||||||
"test_function", {}, ty.void_(), std::move(stmts),
|
{
|
||||||
{create<ast::StageAttribute>(ast::PipelineStage::kCompute), WorkgroupSize(1_i, 1_i, 1_i)});
|
create<ast::StageAttribute>(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i, 1_i, 1_i),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tint
|
} // namespace tint
|
||||||
|
|
|
@ -225,13 +225,12 @@ TEST_F(ResolverIndexAccessorTest, Array_Dynamic_I32) {
|
||||||
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
|
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
|
||||||
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
|
auto* idx = Var("idx", ty.i32(), Construct(ty.i32()));
|
||||||
auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
|
auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(a),
|
Decl(a),
|
||||||
Decl(idx),
|
Decl(idx),
|
||||||
Decl(f),
|
Decl(f),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve());
|
EXPECT_TRUE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "");
|
EXPECT_EQ(r()->error(), "");
|
||||||
|
@ -242,12 +241,11 @@ TEST_F(ResolverIndexAccessorTest, Array_Literal_F32) {
|
||||||
// var f : f32 = a[2.0f];
|
// var f : f32 = a[2.0f];
|
||||||
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
|
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
|
||||||
auto* f = Var("a_2", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, 2_f)));
|
auto* f = Var("a_2", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, 2_f)));
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(a),
|
Decl(a),
|
||||||
Decl(f),
|
Decl(f),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
||||||
}
|
}
|
||||||
|
@ -257,12 +255,11 @@ TEST_F(ResolverIndexAccessorTest, Array_Literal_I32) {
|
||||||
// var f : f32 = a[2i];
|
// var f : f32 = a[2i];
|
||||||
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
|
auto* a = Let("a", ty.array<f32, 3>(), array<f32, 3>());
|
||||||
auto* f = Var("a_2", ty.f32(), IndexAccessor("a", 2_i));
|
auto* f = Var("a_2", ty.f32(), IndexAccessor("a", 2_i));
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(a),
|
Decl(a),
|
||||||
Decl(f),
|
Decl(f),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,9 @@ TEST_P(FunctionParameterAttributeTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
|
||||||
Func("main",
|
Func("main",
|
||||||
ast::VariableList{Param("a", ty.vec4<f32>(), createAttributes({}, *this, params.kind))},
|
{
|
||||||
|
Param("a", ty.vec4<f32>(), createAttributes({}, *this, params.kind)),
|
||||||
|
},
|
||||||
ty.void_(), {});
|
ty.void_(), {});
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
|
@ -161,8 +163,11 @@ using FunctionReturnTypeAttributeTest = TestWithParams;
|
||||||
TEST_P(FunctionReturnTypeAttributeTest, IsValid) {
|
TEST_P(FunctionReturnTypeAttributeTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.f32(), ast::StatementList{Return(1_f)}, {},
|
Func("main", {}, ty.f32(),
|
||||||
createAttributes({}, *this, params.kind));
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{}, createAttributes({}, *this, params.kind));
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -195,9 +200,15 @@ namespace EntryPointInputAndOutputTests {
|
||||||
using ComputeShaderParameterAttributeTest = TestWithParams;
|
using ComputeShaderParameterAttributeTest = TestWithParams;
|
||||||
TEST_P(ComputeShaderParameterAttributeTest, IsValid) {
|
TEST_P(ComputeShaderParameterAttributeTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
auto* p = Param("a", ty.vec4<f32>(), createAttributes(Source{{12, 34}}, *this, params.kind));
|
Func("main",
|
||||||
Func("main", ast::VariableList{p}, ty.void_(), {},
|
{
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
Param("a", ty.vec4<f32>(), createAttributes(Source{{12, 34}}, *this, params.kind)),
|
||||||
|
},
|
||||||
|
ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -242,7 +253,10 @@ TEST_P(FragmentShaderParameterAttributeTest, IsValid) {
|
||||||
attrs.push_back(Builtin(Source{{34, 56}}, ast::Builtin::kPosition));
|
attrs.push_back(Builtin(Source{{34, 56}}, ast::Builtin::kPosition));
|
||||||
}
|
}
|
||||||
auto* p = Param("a", ty.vec4<f32>(), attrs);
|
auto* p = Param("a", ty.vec4<f32>(), attrs);
|
||||||
Func("frag_main", {p}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
|
Func("frag_main", {p}, ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -276,8 +290,16 @@ TEST_P(VertexShaderParameterAttributeTest, IsValid) {
|
||||||
attrs.push_back(Location(Source{{34, 56}}, 2));
|
attrs.push_back(Location(Source{{34, 56}}, 2));
|
||||||
}
|
}
|
||||||
auto* p = Param("a", ty.vec4<f32>(), attrs);
|
auto* p = Param("a", ty.vec4<f32>(), attrs);
|
||||||
Func("vertex_main", ast::VariableList{p}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
|
Func("vertex_main", {p}, ty.vec4<f32>(),
|
||||||
{Stage(ast::PipelineStage::kVertex)}, {Builtin(ast::Builtin::kPosition)});
|
{
|
||||||
|
Return(Construct(ty.vec4<f32>())),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kVertex),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kPosition),
|
||||||
|
});
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -316,8 +338,14 @@ INSTANTIATE_TEST_SUITE_P(ResolverAttributeValidationTest,
|
||||||
using ComputeShaderReturnTypeAttributeTest = TestWithParams;
|
using ComputeShaderReturnTypeAttributeTest = TestWithParams;
|
||||||
TEST_P(ComputeShaderReturnTypeAttributeTest, IsValid) {
|
TEST_P(ComputeShaderReturnTypeAttributeTest, IsValid) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
Func("main", ast::VariableList{}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>(), 1_f))},
|
Func("main", {}, ty.vec4<f32>(),
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)},
|
{
|
||||||
|
Return(Construct(ty.vec4<f32>(), 1_f)),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
},
|
||||||
createAttributes(Source{{12, 34}}, *this, params.kind));
|
createAttributes(Source{{12, 34}}, *this, params.kind));
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
|
@ -363,7 +391,10 @@ TEST_P(FragmentShaderReturnTypeAttributeTest, IsValid) {
|
||||||
auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
|
auto attrs = createAttributes(Source{{12, 34}}, *this, params.kind);
|
||||||
attrs.push_back(Location(Source{{34, 56}}, 2));
|
attrs.push_back(Location(Source{{34, 56}}, 2));
|
||||||
Func("frag_main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
|
Func("frag_main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
|
||||||
{Stage(ast::PipelineStage::kFragment)}, attrs);
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
attrs);
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -413,8 +444,14 @@ TEST_P(VertexShaderReturnTypeAttributeTest, IsValid) {
|
||||||
if (params.kind != AttributeKind::kBuiltin) {
|
if (params.kind != AttributeKind::kBuiltin) {
|
||||||
attrs.push_back(Builtin(Source{{34, 56}}, ast::Builtin::kPosition));
|
attrs.push_back(Builtin(Source{{34, 56}}, ast::Builtin::kPosition));
|
||||||
}
|
}
|
||||||
Func("vertex_main", ast::VariableList{}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
|
Func("vertex_main", {}, ty.vec4<f32>(),
|
||||||
{Stage(ast::PipelineStage::kVertex)}, attrs);
|
{
|
||||||
|
Return(Construct(ty.vec4<f32>())),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kVertex),
|
||||||
|
},
|
||||||
|
attrs);
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -450,8 +487,13 @@ INSTANTIATE_TEST_SUITE_P(ResolverAttributeValidationTest,
|
||||||
|
|
||||||
using EntryPointParameterAttributeTest = TestWithParams;
|
using EntryPointParameterAttributeTest = TestWithParams;
|
||||||
TEST_F(EntryPointParameterAttributeTest, DuplicateAttribute) {
|
TEST_F(EntryPointParameterAttributeTest, DuplicateAttribute) {
|
||||||
Func("main", ast::VariableList{}, ty.f32(), ast::StatementList{Return(1_f)},
|
Func("main", {}, ty.f32(),
|
||||||
{Stage(ast::PipelineStage::kFragment)},
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Location(Source{{12, 34}}, 2),
|
Location(Source{{12, 34}}, 2),
|
||||||
Location(Source{{56, 78}}, 3),
|
Location(Source{{56, 78}}, 3),
|
||||||
|
@ -471,15 +513,23 @@ TEST_F(EntryPointParameterAttributeTest, DuplicateInternalAttribute) {
|
||||||
Disable(ast::DisabledValidation::kBindingPointCollision),
|
Disable(ast::DisabledValidation::kBindingPointCollision),
|
||||||
Disable(ast::DisabledValidation::kEntryPointParameter),
|
Disable(ast::DisabledValidation::kEntryPointParameter),
|
||||||
});
|
});
|
||||||
Func("f", {s}, ty.void_(), {}, {Stage(ast::PipelineStage::kFragment)});
|
Func("f", {s}, ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
using EntryPointReturnTypeAttributeTest = ResolverTest;
|
using EntryPointReturnTypeAttributeTest = ResolverTest;
|
||||||
TEST_F(EntryPointReturnTypeAttributeTest, DuplicateAttribute) {
|
TEST_F(EntryPointReturnTypeAttributeTest, DuplicateAttribute) {
|
||||||
Func("main", ast::VariableList{}, ty.f32(), ast::StatementList{Return(1_f)},
|
Func("main", {}, ty.f32(),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)},
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
ast::AttributeList{
|
ast::AttributeList{
|
||||||
Location(Source{{12, 34}}, 2),
|
Location(Source{{12, 34}}, 2),
|
||||||
Location(Source{{56, 78}}, 3),
|
Location(Source{{56, 78}}, 3),
|
||||||
|
@ -492,7 +542,10 @@ TEST_F(EntryPointReturnTypeAttributeTest, DuplicateAttribute) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(EntryPointReturnTypeAttributeTest, DuplicateInternalAttribute) {
|
TEST_F(EntryPointReturnTypeAttributeTest, DuplicateInternalAttribute) {
|
||||||
Func("f", {}, ty.i32(), {Return(1_i)}, {Stage(ast::PipelineStage::kFragment)},
|
Func("f", {}, ty.i32(), {Return(1_i)},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
ast::AttributeList{
|
ast::AttributeList{
|
||||||
Disable(ast::DisabledValidation::kBindingPointCollision),
|
Disable(ast::DisabledValidation::kBindingPointCollision),
|
||||||
Disable(ast::DisabledValidation::kEntryPointParameter),
|
Disable(ast::DisabledValidation::kEntryPointParameter),
|
||||||
|
@ -972,7 +1025,9 @@ TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByEntryPoint) {
|
||||||
Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
|
Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
|
||||||
Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
|
Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kFragment)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
|
@ -1000,13 +1055,17 @@ TEST_F(ResourceAttributeTest, BindingPointUsedTwiceByDifferentEntryPoints) {
|
||||||
Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
|
Decl(Var("a", ty.vec4<f32>(), ast::StorageClass::kNone,
|
||||||
Call("textureLoad", "A", vec2<i32>(1_i, 2_i), 0_i))),
|
Call("textureLoad", "A", vec2<i32>(1_i, 2_i), 0_i))),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kFragment)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
Func("F_B", {}, ty.void_(),
|
Func("F_B", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
|
Decl(Var("b", ty.vec4<f32>(), ast::StorageClass::kNone,
|
||||||
Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
|
Call("textureLoad", "B", vec2<i32>(1_i, 2_i), 0_i))),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kFragment)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
@ -1033,10 +1092,14 @@ TEST_F(InvariantAttributeTests, InvariantWithPosition) {
|
||||||
auto* param =
|
auto* param =
|
||||||
Param("p", ty.vec4<f32>(),
|
Param("p", ty.vec4<f32>(),
|
||||||
{Invariant(Source{{12, 34}}), Builtin(Source{{56, 78}}, ast::Builtin::kPosition)});
|
{Invariant(Source{{12, 34}}), Builtin(Source{{56, 78}}, ast::Builtin::kPosition)});
|
||||||
Func("main", ast::VariableList{param}, ty.vec4<f32>(),
|
Func("main", {param}, ty.vec4<f32>(),
|
||||||
ast::StatementList{Return(Construct(ty.vec4<f32>()))},
|
{
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)},
|
Return(Construct(ty.vec4<f32>())),
|
||||||
ast::AttributeList{
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
Location(0),
|
Location(0),
|
||||||
});
|
});
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -1044,10 +1107,14 @@ TEST_F(InvariantAttributeTests, InvariantWithPosition) {
|
||||||
|
|
||||||
TEST_F(InvariantAttributeTests, InvariantWithoutPosition) {
|
TEST_F(InvariantAttributeTests, InvariantWithoutPosition) {
|
||||||
auto* param = Param("p", ty.vec4<f32>(), {Invariant(Source{{12, 34}}), Location(0)});
|
auto* param = Param("p", ty.vec4<f32>(), {Invariant(Source{{12, 34}}), Location(0)});
|
||||||
Func("main", ast::VariableList{param}, ty.vec4<f32>(),
|
Func("main", {param}, ty.vec4<f32>(),
|
||||||
ast::StatementList{Return(Construct(ty.vec4<f32>()))},
|
{
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)},
|
Return(Construct(ty.vec4<f32>())),
|
||||||
ast::AttributeList{
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
Location(0),
|
Location(0),
|
||||||
});
|
});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -1135,10 +1202,17 @@ TEST_P(InterpolateParameterTest, All) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
|
||||||
Func("main",
|
Func("main",
|
||||||
ast::VariableList{
|
{
|
||||||
Param("a", ty.f32(),
|
Param("a", ty.f32(),
|
||||||
{Location(0), Interpolate(Source{{12, 34}}, params.type, params.sampling)})},
|
{
|
||||||
ty.void_(), {}, ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
Location(0),
|
||||||
|
Interpolate(Source{{12, 34}}, params.type, params.sampling),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
if (params.should_pass) {
|
if (params.should_pass) {
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -1154,10 +1228,17 @@ TEST_P(InterpolateParameterTest, IntegerScalar) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
|
||||||
Func("main",
|
Func("main",
|
||||||
ast::VariableList{
|
{
|
||||||
Param("a", ty.i32(),
|
Param("a", ty.i32(),
|
||||||
{Location(0), Interpolate(Source{{12, 34}}, params.type, params.sampling)})},
|
{
|
||||||
ty.void_(), {}, ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
Location(0),
|
||||||
|
Interpolate(Source{{12, 34}}, params.type, params.sampling),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
if (params.type != ast::InterpolationType::kFlat) {
|
if (params.type != ast::InterpolationType::kFlat) {
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -1178,10 +1259,17 @@ TEST_P(InterpolateParameterTest, IntegerVector) {
|
||||||
auto& params = GetParam();
|
auto& params = GetParam();
|
||||||
|
|
||||||
Func("main",
|
Func("main",
|
||||||
ast::VariableList{
|
{
|
||||||
Param("a", ty.vec4<u32>(),
|
Param("a", ty.vec4<u32>(),
|
||||||
{Location(0), Interpolate(Source{{12, 34}}, params.type, params.sampling)})},
|
{
|
||||||
ty.void_(), {}, ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
Location(0),
|
||||||
|
Interpolate(Source{{12, 34}}, params.type, params.sampling),
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
if (params.type != ast::InterpolationType::kFlat) {
|
if (params.type != ast::InterpolationType::kFlat) {
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -1217,8 +1305,10 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
Params{ast::InterpolationType::kFlat, ast::InterpolationSampling::kSample, false}));
|
Params{ast::InterpolationType::kFlat, ast::InterpolationSampling::kSample, false}));
|
||||||
|
|
||||||
TEST_F(InterpolateTest, FragmentInput_Integer_MissingFlatInterpolation) {
|
TEST_F(InterpolateTest, FragmentInput_Integer_MissingFlatInterpolation) {
|
||||||
Func("main", ast::VariableList{Param(Source{{12, 34}}, "a", ty.i32(), {Location(0)})},
|
Func("main", {Param(Source{{12, 34}}, "a", ty.i32(), {Location(0)})}, ty.void_(), {},
|
||||||
ty.void_(), {}, ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
|
@ -1231,8 +1321,13 @@ TEST_F(InterpolateTest, VertexOutput_Integer_MissingFlatInterpolation) {
|
||||||
Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)}),
|
Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)}),
|
||||||
Member(Source{{12, 34}}, "u", ty.u32(), {Location(0)}),
|
Member(Source{{12, 34}}, "u", ty.u32(), {Location(0)}),
|
||||||
});
|
});
|
||||||
Func("main", {}, ty.Of(s), {Return(Construct(ty.Of(s)))},
|
Func("main", {}, ty.Of(s),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kVertex)});
|
{
|
||||||
|
Return(Construct(ty.Of(s))),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kVertex),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
|
@ -1243,11 +1338,18 @@ note: while analysing entry point 'main')");
|
||||||
|
|
||||||
TEST_F(InterpolateTest, MissingLocationAttribute_Parameter) {
|
TEST_F(InterpolateTest, MissingLocationAttribute_Parameter) {
|
||||||
Func("main",
|
Func("main",
|
||||||
ast::VariableList{Param("a", ty.vec4<f32>(),
|
{
|
||||||
{Builtin(ast::Builtin::kPosition),
|
Param("a", ty.vec4<f32>(),
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kPosition),
|
||||||
Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
|
Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
|
||||||
ast::InterpolationSampling::kNone)})},
|
ast::InterpolationSampling::kNone),
|
||||||
ty.void_(), {}, ast::AttributeList{Stage(ast::PipelineStage::kFragment)});
|
}),
|
||||||
|
},
|
||||||
|
ty.void_(), {},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
|
@ -1255,11 +1357,18 @@ TEST_F(InterpolateTest, MissingLocationAttribute_Parameter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(InterpolateTest, MissingLocationAttribute_ReturnType) {
|
TEST_F(InterpolateTest, MissingLocationAttribute_ReturnType) {
|
||||||
Func("main", {}, ty.vec4<f32>(), {Return(Construct(ty.vec4<f32>()))},
|
Func("main", {}, ty.vec4<f32>(),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kVertex)},
|
{
|
||||||
{Builtin(ast::Builtin::kPosition),
|
Return(Construct(ty.vec4<f32>())),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kVertex),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kPosition),
|
||||||
Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
|
Interpolate(Source{{12, 34}}, ast::InterpolationType::kFlat,
|
||||||
ast::InterpolationSampling::kNone)});
|
ast::InterpolationSampling::kNone),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
|
|
|
@ -38,8 +38,14 @@ TEST_F(ResolverBuiltinValidationTest, InvalidPipelineStageDirect) {
|
||||||
|
|
||||||
auto* dpdx =
|
auto* dpdx =
|
||||||
create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"), ast::ExpressionList{Expr(1_f)});
|
create<ast::CallExpression>(Source{{3, 4}}, Expr("dpdx"), ast::ExpressionList{Expr(1_f)});
|
||||||
Func(Source{{1, 2}}, "func", ast::VariableList{}, ty.void_(), {CallStmt(dpdx)},
|
Func(Source{{1, 2}}, "func", {}, ty.void_(),
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
CallStmt(dpdx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "3:4 error: built-in cannot be used by compute pipeline stage");
|
EXPECT_EQ(r()->error(), "3:4 error: built-in cannot be used by compute pipeline stage");
|
||||||
|
|
|
@ -93,8 +93,7 @@ TEST_P(ResolverBuiltinsStageTest, All_input) {
|
||||||
const Params& params = GetParam();
|
const Params& params = GetParam();
|
||||||
|
|
||||||
auto* p = Global("p", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
auto* p = Global("p", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* input = Param("input", params.type(*this),
|
auto* input = Param("input", params.type(*this), {Builtin(Source{{12, 34}}, params.builtin)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, params.builtin)});
|
|
||||||
switch (params.stage) {
|
switch (params.stage) {
|
||||||
case ast::PipelineStage::kVertex:
|
case ast::PipelineStage::kVertex:
|
||||||
Func("main", {input}, ty.vec4<f32>(), {Return(p)}, {Stage(ast::PipelineStage::kVertex)},
|
Func("main", {input}, ty.vec4<f32>(), {Return(p)}, {Stage(ast::PipelineStage::kVertex)},
|
||||||
|
@ -105,7 +104,10 @@ TEST_P(ResolverBuiltinsStageTest, All_input) {
|
||||||
break;
|
break;
|
||||||
case ast::PipelineStage::kCompute:
|
case ast::PipelineStage::kCompute:
|
||||||
Func("main", {input}, ty.void_(), {},
|
Func("main", {input}, ty.void_(), {},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -130,10 +132,20 @@ TEST_F(ResolverBuiltinsValidationTest, FragDepthIsInput_Fail) {
|
||||||
// fn fs_main(
|
// fn fs_main(
|
||||||
// @builtin(frag_depth) fd: f32,
|
// @builtin(frag_depth) fd: f32,
|
||||||
// ) -> @location(0) f32 { return 1.0; }
|
// ) -> @location(0) f32 { return 1.0; }
|
||||||
auto* fd = Param("fd", ty.f32(),
|
Func("fs_main",
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)});
|
{
|
||||||
Func("fs_main", ast::VariableList{fd}, ty.f32(), {Return(1_f)},
|
Param("fd", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)}),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
},
|
||||||
|
ty.f32(),
|
||||||
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: builtin(frag_depth) cannot be used in input of "
|
"12:34 error: builtin(frag_depth) cannot be used in input of "
|
||||||
|
@ -149,11 +161,24 @@ TEST_F(ResolverBuiltinsValidationTest, FragDepthIsInputStruct_Fail) {
|
||||||
|
|
||||||
auto* s = Structure(
|
auto* s = Structure(
|
||||||
"MyInputs",
|
"MyInputs",
|
||||||
{Member("frag_depth", ty.f32(),
|
{
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)})});
|
Member("frag_depth", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)}),
|
||||||
|
});
|
||||||
|
|
||||||
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
Func("fragShader",
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
{
|
||||||
|
Param("arg", ty.Of(s)),
|
||||||
|
},
|
||||||
|
ty.f32(),
|
||||||
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
"12:34 error: builtin(frag_depth) cannot be used in input of "
|
"12:34 error: builtin(frag_depth) cannot be used in input of "
|
||||||
|
@ -184,11 +209,25 @@ TEST_F(ResolverBuiltinsValidationTest, PositionNotF32_Struct_Fail) {
|
||||||
// @fragment
|
// @fragment
|
||||||
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
|
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
|
||||||
|
|
||||||
auto* m = Member("position", ty.vec4<u32>(),
|
auto* s =
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kPosition)});
|
Structure("MyInputs", {
|
||||||
auto* s = Structure("MyInputs", {m});
|
Member("position", ty.vec4<u32>(),
|
||||||
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
{Builtin(Source{{12, 34}}, ast::Builtin::kPosition)}),
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
});
|
||||||
|
Func("fragShader",
|
||||||
|
{
|
||||||
|
Param("arg", ty.Of(s)),
|
||||||
|
},
|
||||||
|
ty.f32(),
|
||||||
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(position) must be 'vec4<f32>'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(position) must be 'vec4<f32>'");
|
||||||
|
@ -211,11 +250,21 @@ TEST_F(ResolverBuiltinsValidationTest, FragDepthNotF32_Struct_Fail) {
|
||||||
// @fragment
|
// @fragment
|
||||||
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
|
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
|
||||||
|
|
||||||
auto* m = Member("frag_depth", ty.i32(),
|
auto* s = Structure(
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)});
|
"MyInputs",
|
||||||
auto* s = Structure("MyInputs", {m});
|
{
|
||||||
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
Member("frag_depth", ty.i32(), {Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)}),
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
});
|
||||||
|
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(),
|
||||||
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(frag_depth) must be 'f32'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(frag_depth) must be 'f32'");
|
||||||
|
@ -228,10 +277,11 @@ TEST_F(ResolverBuiltinsValidationTest, SampleMaskNotU32_Struct_Fail) {
|
||||||
// @fragment
|
// @fragment
|
||||||
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
|
// fn fragShader(is_front: MyInputs) -> @location(0) f32 { return 1.0; }
|
||||||
|
|
||||||
auto* s = Structure(
|
auto* s =
|
||||||
"MyInputs",
|
Structure("MyInputs",
|
||||||
{Member("m", ty.f32(),
|
{
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kSampleMask)})});
|
Member("m", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kSampleMask)}),
|
||||||
|
});
|
||||||
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
||||||
|
|
||||||
|
@ -254,10 +304,20 @@ TEST_F(ResolverBuiltinsValidationTest, SampleMaskIsNotU32_Fail) {
|
||||||
// fn fs_main(
|
// fn fs_main(
|
||||||
// @builtin(sample_mask) arg: bool
|
// @builtin(sample_mask) arg: bool
|
||||||
// ) -> @location(0) f32 { return 1.0; }
|
// ) -> @location(0) f32 { return 1.0; }
|
||||||
auto* arg = Param("arg", ty.bool_(),
|
Func("fs_main",
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kSampleMask)});
|
{
|
||||||
Func("fs_main", ast::VariableList{arg}, ty.f32(), {Return(1_f)},
|
Param("arg", ty.bool_(), {Builtin(Source{{12, 34}}, ast::Builtin::kSampleMask)}),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
},
|
||||||
|
ty.f32(),
|
||||||
|
{
|
||||||
|
Return(1_f),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_mask) must be 'u32'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_mask) must be 'u32'");
|
||||||
}
|
}
|
||||||
|
@ -271,8 +331,9 @@ TEST_F(ResolverBuiltinsValidationTest, SampleIndexIsNotU32_Struct_Fail) {
|
||||||
|
|
||||||
auto* s = Structure(
|
auto* s = Structure(
|
||||||
"MyInputs",
|
"MyInputs",
|
||||||
{Member("m", ty.f32(),
|
{
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kSampleIndex)})});
|
Member("m", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kSampleIndex)}),
|
||||||
|
});
|
||||||
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
||||||
|
|
||||||
|
@ -285,10 +346,17 @@ TEST_F(ResolverBuiltinsValidationTest, SampleIndexIsNotU32_Fail) {
|
||||||
// fn fs_main(
|
// fn fs_main(
|
||||||
// @builtin(sample_index) arg: bool
|
// @builtin(sample_index) arg: bool
|
||||||
// ) -> @location(0) f32 { return 1.0; }
|
// ) -> @location(0) f32 { return 1.0; }
|
||||||
auto* arg = Param("arg", ty.bool_(),
|
Func("fs_main",
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kSampleIndex)});
|
{
|
||||||
Func("fs_main", ast::VariableList{arg}, ty.f32(), {Return(1_f)},
|
Param("arg", ty.bool_(), {Builtin(Source{{12, 34}}, ast::Builtin::kSampleIndex)}),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
},
|
||||||
|
ty.f32(), {Return(1_f)},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_index) must be 'u32'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(sample_index) must be 'u32'");
|
||||||
}
|
}
|
||||||
|
@ -298,10 +366,17 @@ TEST_F(ResolverBuiltinsValidationTest, PositionIsNotF32_Fail) {
|
||||||
// fn fs_main(
|
// fn fs_main(
|
||||||
// @builtin(kPosition) p: vec3<f32>,
|
// @builtin(kPosition) p: vec3<f32>,
|
||||||
// ) -> @location(0) f32 { return 1.0; }
|
// ) -> @location(0) f32 { return 1.0; }
|
||||||
auto* p = Param("p", ty.vec3<f32>(),
|
Func("fs_main",
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kPosition)});
|
{
|
||||||
Func("fs_main", ast::VariableList{p}, ty.f32(), {Return(1_f)},
|
Param("p", ty.vec3<f32>(), {Builtin(Source{{12, 34}}, ast::Builtin::kPosition)}),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
},
|
||||||
|
ty.f32(), {Return(1_f)},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(0),
|
||||||
|
});
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(position) must be 'vec4<f32>'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(position) must be 'vec4<f32>'");
|
||||||
}
|
}
|
||||||
|
@ -310,9 +385,8 @@ TEST_F(ResolverBuiltinsValidationTest, FragDepthIsNotF32_Fail) {
|
||||||
// @fragment
|
// @fragment
|
||||||
// fn fs_main() -> @builtin(kFragDepth) f32 { var fd: i32; return fd; }
|
// fn fs_main() -> @builtin(kFragDepth) f32 { var fd: i32; return fd; }
|
||||||
auto* fd = Var("fd", ty.i32());
|
auto* fd = Var("fd", ty.i32());
|
||||||
Func("fs_main", {}, ty.i32(), {Decl(fd), Return(fd)},
|
Func("fs_main", {}, ty.i32(), {Decl(fd), Return(fd)}, {Stage(ast::PipelineStage::kFragment)},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)},
|
{Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kFragDepth)});
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(frag_depth) must be 'f32'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(frag_depth) must be 'f32'");
|
||||||
}
|
}
|
||||||
|
@ -323,12 +397,10 @@ TEST_F(ResolverBuiltinsValidationTest, VertexIndexIsNotU32_Fail) {
|
||||||
// @builtin(kVertexIndex) vi : f32,
|
// @builtin(kVertexIndex) vi : f32,
|
||||||
// @builtin(kPosition) p :vec4<f32>
|
// @builtin(kPosition) p :vec4<f32>
|
||||||
// ) -> @builtin(kPosition) vec4<f32> { return vec4<f32>(); }
|
// ) -> @builtin(kPosition) vec4<f32> { return vec4<f32>(); }
|
||||||
auto* p = Param("p", ty.vec4<f32>(), ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
auto* p = Param("p", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
||||||
auto* vi = Param("vi", ty.f32(),
|
auto* vi = Param("vi", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kVertexIndex)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kVertexIndex)});
|
Func("main", {vi, p}, ty.vec4<f32>(), {Return(Expr("p"))}, {Stage(ast::PipelineStage::kVertex)},
|
||||||
Func("main", ast::VariableList{vi, p}, ty.vec4<f32>(), {Return(Expr("p"))},
|
{Builtin(ast::Builtin::kPosition)});
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kVertex)},
|
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(vertex_index) must be 'u32'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(vertex_index) must be 'u32'");
|
||||||
}
|
}
|
||||||
|
@ -339,12 +411,10 @@ TEST_F(ResolverBuiltinsValidationTest, InstanceIndexIsNotU32) {
|
||||||
// @builtin(kInstanceIndex) ii : f32,
|
// @builtin(kInstanceIndex) ii : f32,
|
||||||
// @builtin(kPosition) p :vec4<f32>
|
// @builtin(kPosition) p :vec4<f32>
|
||||||
// ) -> @builtin(kPosition) vec4<f32> { return vec4<f32>(); }
|
// ) -> @builtin(kPosition) vec4<f32> { return vec4<f32>(); }
|
||||||
auto* p = Param("p", ty.vec4<f32>(), ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
auto* p = Param("p", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
||||||
auto* ii = Param("ii", ty.f32(),
|
auto* ii = Param("ii", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kInstanceIndex)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kInstanceIndex)});
|
Func("main", {ii, p}, ty.vec4<f32>(), {Return(Expr("p"))}, {Stage(ast::PipelineStage::kVertex)},
|
||||||
Func("main", ast::VariableList{ii, p}, ty.vec4<f32>(), {Return(Expr("p"))},
|
{Builtin(ast::Builtin::kPosition)});
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kVertex)},
|
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(instance_index) must be 'u32'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(instance_index) must be 'u32'");
|
||||||
}
|
}
|
||||||
|
@ -357,14 +427,13 @@ TEST_F(ResolverBuiltinsValidationTest, FragmentBuiltin_Pass) {
|
||||||
// @builtin(sample_index) si: u32,
|
// @builtin(sample_index) si: u32,
|
||||||
// @builtin(sample_mask) sm : u32
|
// @builtin(sample_mask) sm : u32
|
||||||
// ) -> @builtin(frag_depth) f32 { var fd: f32; return fd; }
|
// ) -> @builtin(frag_depth) f32 { var fd: f32; return fd; }
|
||||||
auto* p = Param("p", ty.vec4<f32>(), ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
auto* p = Param("p", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
||||||
auto* ff = Param("ff", ty.bool_(), ast::AttributeList{Builtin(ast::Builtin::kFrontFacing)});
|
auto* ff = Param("ff", ty.bool_(), {Builtin(ast::Builtin::kFrontFacing)});
|
||||||
auto* si = Param("si", ty.u32(), ast::AttributeList{Builtin(ast::Builtin::kSampleIndex)});
|
auto* si = Param("si", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)});
|
||||||
auto* sm = Param("sm", ty.u32(), ast::AttributeList{Builtin(ast::Builtin::kSampleMask)});
|
auto* sm = Param("sm", ty.u32(), {Builtin(ast::Builtin::kSampleMask)});
|
||||||
auto* var_fd = Var("fd", ty.f32());
|
auto* var_fd = Var("fd", ty.f32());
|
||||||
Func("fs_main", ast::VariableList{p, ff, si, sm}, ty.f32(), {Decl(var_fd), Return(var_fd)},
|
Func("fs_main", {p, ff, si, sm}, ty.f32(), {Decl(var_fd), Return(var_fd)},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)},
|
{Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::Builtin::kFragDepth)});
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kFragDepth)});
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,19 +443,16 @@ TEST_F(ResolverBuiltinsValidationTest, VertexBuiltin_Pass) {
|
||||||
// @builtin(vertex_index) vi : u32,
|
// @builtin(vertex_index) vi : u32,
|
||||||
// @builtin(instance_index) ii : u32,
|
// @builtin(instance_index) ii : u32,
|
||||||
// ) -> @builtin(position) vec4<f32> { var p :vec4<f32>; return p; }
|
// ) -> @builtin(position) vec4<f32> { var p :vec4<f32>; return p; }
|
||||||
auto* vi = Param("vi", ty.u32(),
|
auto* vi = Param("vi", ty.u32(), {Builtin(Source{{12, 34}}, ast::Builtin::kVertexIndex)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kVertexIndex)});
|
|
||||||
|
|
||||||
auto* ii = Param("ii", ty.u32(),
|
auto* ii = Param("ii", ty.u32(), {Builtin(Source{{12, 34}}, ast::Builtin::kInstanceIndex)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kInstanceIndex)});
|
|
||||||
auto* p = Var("p", ty.vec4<f32>());
|
auto* p = Var("p", ty.vec4<f32>());
|
||||||
Func("main", ast::VariableList{vi, ii}, ty.vec4<f32>(),
|
Func("main", {vi, ii}, ty.vec4<f32>(),
|
||||||
{
|
{
|
||||||
Decl(p),
|
Decl(p),
|
||||||
Return(p),
|
Return(p),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kVertex)},
|
{Stage(ast::PipelineStage::kVertex)}, {Builtin(ast::Builtin::kPosition)});
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
@ -401,28 +467,23 @@ TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_Pass) {
|
||||||
// @builtin(num_workgroups) nwgs: vec3<u32>,
|
// @builtin(num_workgroups) nwgs: vec3<u32>,
|
||||||
// ) {}
|
// ) {}
|
||||||
|
|
||||||
auto* li_id = Param("li_id", ty.vec3<u32>(),
|
auto* li_id = Param("li_id", ty.vec3<u32>(), {Builtin(ast::Builtin::kLocalInvocationId)});
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kLocalInvocationId)});
|
auto* li_index = Param("li_index", ty.u32(), {Builtin(ast::Builtin::kLocalInvocationIndex)});
|
||||||
auto* li_index = Param("li_index", ty.u32(),
|
auto* gi = Param("gi", ty.vec3<u32>(), {Builtin(ast::Builtin::kGlobalInvocationId)});
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kLocalInvocationIndex)});
|
auto* wi = Param("wi", ty.vec3<u32>(), {Builtin(ast::Builtin::kWorkgroupId)});
|
||||||
auto* gi =
|
auto* nwgs = Param("nwgs", ty.vec3<u32>(), {Builtin(ast::Builtin::kNumWorkgroups)});
|
||||||
Param("gi", ty.vec3<u32>(), ast::AttributeList{Builtin(ast::Builtin::kGlobalInvocationId)});
|
|
||||||
auto* wi = Param("wi", ty.vec3<u32>(), ast::AttributeList{Builtin(ast::Builtin::kWorkgroupId)});
|
|
||||||
auto* nwgs =
|
|
||||||
Param("nwgs", ty.vec3<u32>(), ast::AttributeList{Builtin(ast::Builtin::kNumWorkgroups)});
|
|
||||||
|
|
||||||
Func("main", ast::VariableList{li_id, li_index, gi, wi, nwgs}, ty.void_(), {},
|
Func("main", {li_id, li_index, gi, wi, nwgs}, ty.void_(), {},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
{Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_WorkGroupIdNotVec3U32) {
|
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_WorkGroupIdNotVec3U32) {
|
||||||
auto* wi = Param("wi", ty.f32(),
|
auto* wi = Param("wi", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kWorkgroupId)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kWorkgroupId)});
|
Func("main", {wi}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{wi}, ty.void_(), {},
|
{Stage(ast::PipelineStage::kCompute),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
|
||||||
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -432,10 +493,9 @@ TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_WorkGroupIdNotVec3U32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_NumWorkgroupsNotVec3U32) {
|
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_NumWorkgroupsNotVec3U32) {
|
||||||
auto* nwgs = Param("nwgs", ty.f32(),
|
auto* nwgs = Param("nwgs", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kNumWorkgroups)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kNumWorkgroups)});
|
Func("main", {nwgs}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{nwgs}, ty.void_(), {},
|
{Stage(ast::PipelineStage::kCompute),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
|
||||||
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -446,10 +506,9 @@ TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_NumWorkgroupsNotVec3U32) {
|
||||||
|
|
||||||
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_GlobalInvocationNotVec3U32) {
|
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_GlobalInvocationNotVec3U32) {
|
||||||
auto* gi =
|
auto* gi =
|
||||||
Param("gi", ty.vec3<i32>(),
|
Param("gi", ty.vec3<i32>(), {Builtin(Source{{12, 34}}, ast::Builtin::kGlobalInvocationId)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kGlobalInvocationId)});
|
Func("main", {gi}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{gi}, ty.void_(), {},
|
{Stage(ast::PipelineStage::kCompute),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
|
||||||
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -459,11 +518,10 @@ TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_GlobalInvocationNotVec3U32
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationIndexNotU32) {
|
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationIndexNotU32) {
|
||||||
auto* li_index =
|
auto* li_index = Param("li_index", ty.vec3<u32>(),
|
||||||
Param("li_index", ty.vec3<u32>(),
|
{Builtin(Source{{12, 34}}, ast::Builtin::kLocalInvocationIndex)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kLocalInvocationIndex)});
|
Func("main", {li_index}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{li_index}, ty.void_(), {},
|
{Stage(ast::PipelineStage::kCompute),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
|
||||||
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -473,11 +531,10 @@ TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationIndexNotU32
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationNotVec3U32) {
|
TEST_F(ResolverBuiltinsValidationTest, ComputeBuiltin_LocalInvocationNotVec3U32) {
|
||||||
auto* li_id =
|
auto* li_id = Param("li_id", ty.vec2<u32>(),
|
||||||
Param("li_id", ty.vec2<u32>(),
|
{Builtin(Source{{12, 34}}, ast::Builtin::kLocalInvocationId)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kLocalInvocationId)});
|
Func("main", {li_id}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{li_id}, ty.void_(), {},
|
{Stage(ast::PipelineStage::kCompute),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute),
|
|
||||||
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
WorkgroupSize(Expr(Source{Source::Location{12, 34}}, 2_i))});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
@ -496,13 +553,11 @@ TEST_F(ResolverBuiltinsValidationTest, FragmentBuiltinStruct_Pass) {
|
||||||
// @fragment
|
// @fragment
|
||||||
// fn fragShader(arg: MyInputs) -> @location(0) f32 { return 1.0; }
|
// fn fragShader(arg: MyInputs) -> @location(0) f32 { return 1.0; }
|
||||||
|
|
||||||
auto* s = Structure(
|
auto* s = Structure("MyInputs",
|
||||||
"MyInputs",
|
{Member("position", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)}),
|
||||||
{Member("position", ty.vec4<f32>(), ast::AttributeList{Builtin(ast::Builtin::kPosition)}),
|
Member("front_facing", ty.bool_(), {Builtin(ast::Builtin::kFrontFacing)}),
|
||||||
Member("front_facing", ty.bool_(),
|
Member("sample_index", ty.u32(), {Builtin(ast::Builtin::kSampleIndex)}),
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kFrontFacing)}),
|
Member("sample_mask", ty.u32(), {Builtin(ast::Builtin::kSampleMask)})});
|
||||||
Member("sample_index", ty.u32(), ast::AttributeList{Builtin(ast::Builtin::kSampleIndex)}),
|
|
||||||
Member("sample_mask", ty.u32(), ast::AttributeList{Builtin(ast::Builtin::kSampleMask)})});
|
|
||||||
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
Func("fragShader", {Param("arg", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
@ -515,10 +570,9 @@ TEST_F(ResolverBuiltinsValidationTest, FrontFacingParamIsNotBool_Fail) {
|
||||||
// ) -> @location(0) f32 { return 1.0; }
|
// ) -> @location(0) f32 { return 1.0; }
|
||||||
|
|
||||||
auto* is_front =
|
auto* is_front =
|
||||||
Param("is_front", ty.i32(),
|
Param("is_front", ty.i32(), {Builtin(Source{{12, 34}}, ast::Builtin::kFrontFacing)});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kFrontFacing)});
|
Func("fs_main", {is_front}, ty.f32(), {Return(1_f)}, {Stage(ast::PipelineStage::kFragment)},
|
||||||
Func("fs_main", ast::VariableList{is_front}, ty.f32(), {Return(1_f)},
|
{Location(0)});
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(front_facing) must be 'bool'");
|
EXPECT_EQ(r()->error(), "12:34 error: store type of builtin(front_facing) must be 'bool'");
|
||||||
|
@ -533,8 +587,7 @@ TEST_F(ResolverBuiltinsValidationTest, FrontFacingMemberIsNotBool_Fail) {
|
||||||
|
|
||||||
auto* s = Structure(
|
auto* s = Structure(
|
||||||
"MyInputs",
|
"MyInputs",
|
||||||
{Member("pos", ty.f32(),
|
{Member("pos", ty.f32(), {Builtin(Source{{12, 34}}, ast::Builtin::kFrontFacing)})});
|
||||||
ast::AttributeList{Builtin(Source{{12, 34}}, ast::Builtin::kFrontFacing)})});
|
|
||||||
Func("fragShader", {Param("is_front", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
Func("fragShader", {Param("is_front", ty.Of(s))}, ty.f32(), {Return(1_f)},
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
{Stage(ast::PipelineStage::kFragment)}, {Location(0)});
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ TEST_F(ResolverCallValidationTest, PointerArgument_FunctionParamWithMain) {
|
||||||
Func("foo", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(), {});
|
Func("foo", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(), {});
|
||||||
Func("bar", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(),
|
Func("bar", {Param("p", ty.pointer<i32>(ast::StorageClass::kFunction))}, ty.void_(),
|
||||||
ast::StatementList{CallStmt(Call("foo", Expr("p")))});
|
ast::StatementList{CallStmt(Call("foo", Expr("p")))});
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Var("v", ty.i32(), Expr(1_i))),
|
Decl(Var("v", ty.i32(), Expr(1_i))),
|
||||||
CallStmt(Call("foo", AddressOf(Expr("v")))),
|
CallStmt(Call("foo", AddressOf(Expr("v")))),
|
||||||
|
@ -195,7 +195,7 @@ TEST_F(ResolverCallValidationTest, LetPointer) {
|
||||||
auto* v = Var("v", ty.i32());
|
auto* v = Var("v", ty.i32());
|
||||||
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kFunction), AddressOf(v));
|
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kFunction), AddressOf(v));
|
||||||
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("x", Expr(Source{{12, 34}}, p)));
|
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("x", Expr(Source{{12, 34}}, p)));
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(v),
|
Decl(v),
|
||||||
Decl(p),
|
Decl(p),
|
||||||
|
@ -222,7 +222,7 @@ TEST_F(ResolverCallValidationTest, LetPointerPrivate) {
|
||||||
auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
|
auto* v = Global("v", ty.i32(), ast::StorageClass::kPrivate);
|
||||||
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kPrivate), AddressOf(v));
|
auto* p = Let("p", ty.pointer(ty.i32(), ast::StorageClass::kPrivate), AddressOf(v));
|
||||||
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("foo", Expr(Source{{12, 34}}, p)));
|
auto* c = Var("c", ty.i32(), ast::StorageClass::kNone, Call("foo", Expr(Source{{12, 34}}, p)));
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(p),
|
Decl(p),
|
||||||
Decl(c),
|
Decl(c),
|
||||||
|
|
|
@ -394,7 +394,10 @@ TEST_F(ResolverFunctionValidationTest, FunctionVarInitWithParam) {
|
||||||
auto* bar = Param("bar", ty.f32());
|
auto* bar = Param("bar", ty.f32());
|
||||||
auto* baz = Var("baz", ty.f32(), Expr("bar"));
|
auto* baz = Var("baz", ty.f32(), Expr("bar"));
|
||||||
|
|
||||||
Func("foo", ast::VariableList{bar}, ty.void_(), {Decl(baz)});
|
Func("foo", {bar}, ty.void_(),
|
||||||
|
{
|
||||||
|
Decl(baz),
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
@ -407,7 +410,10 @@ TEST_F(ResolverFunctionValidationTest, FunctionConstInitWithParam) {
|
||||||
auto* bar = Param("bar", ty.f32());
|
auto* bar = Param("bar", ty.f32());
|
||||||
auto* baz = Let("baz", ty.f32(), Expr("bar"));
|
auto* baz = Let("baz", ty.f32(), Expr("bar"));
|
||||||
|
|
||||||
Func("foo", ast::VariableList{bar}, ty.void_(), {Decl(baz)});
|
Func("foo", {bar}, ty.void_(),
|
||||||
|
{
|
||||||
|
Decl(baz),
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
@ -709,7 +715,7 @@ TEST_F(ResolverFunctionValidationTest, ParameterStoreType_NonAtomicFree) {
|
||||||
Structure("S", {Member("m", ty.atomic(ty.i32()))});
|
Structure("S", {Member("m", ty.atomic(ty.i32()))});
|
||||||
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
|
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
|
||||||
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
|
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
|
||||||
Func("f", ast::VariableList{bar}, ty.void_(), {});
|
Func("f", {bar}, ty.void_(), {});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
|
@ -721,7 +727,7 @@ TEST_F(ResolverFunctionValidationTest, ParameterSotreType_AtomicFree) {
|
||||||
Structure("S", {Member("m", ty.i32())});
|
Structure("S", {Member("m", ty.i32())});
|
||||||
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
|
auto* ret_type = ty.type_name(Source{{12, 34}}, "S");
|
||||||
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
|
auto* bar = Param(Source{{12, 34}}, "bar", ret_type);
|
||||||
Func("f", ast::VariableList{bar}, ty.void_(), {});
|
Func("f", {bar}, ty.void_(), {});
|
||||||
|
|
||||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
}
|
}
|
||||||
|
@ -779,7 +785,7 @@ TEST_P(ResolverFunctionParameterValidationTest, StorageClass) {
|
||||||
auto& param = GetParam();
|
auto& param = GetParam();
|
||||||
auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.storage_class);
|
auto* ptr_type = ty.pointer(Source{{12, 34}}, ty.i32(), param.storage_class);
|
||||||
auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
|
auto* arg = Param(Source{{12, 34}}, "p", ptr_type);
|
||||||
Func("f", ast::VariableList{arg}, ty.void_(), {});
|
Func("f", {arg}, ty.void_(), {});
|
||||||
|
|
||||||
if (param.should_pass) {
|
if (param.should_pass) {
|
||||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
|
@ -270,8 +270,10 @@ TEST_F(ResolverTest, Stmt_Switch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Stmt_Call) {
|
TEST_F(ResolverTest, Stmt_Call) {
|
||||||
ast::VariableList params;
|
Func("my_func", {}, ty.void_(),
|
||||||
Func("my_func", params, ty.void_(), {Return()}, ast::AttributeList{});
|
{
|
||||||
|
Return(),
|
||||||
|
});
|
||||||
|
|
||||||
auto* expr = Call("my_func");
|
auto* expr = Call("my_func");
|
||||||
|
|
||||||
|
@ -333,8 +335,6 @@ TEST_F(ResolverTest, Stmt_VariableDecl_OuterScopeAfterInnerScope) {
|
||||||
// var bar : f32 = foo;
|
// var bar : f32 = foo;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
ast::VariableList params;
|
|
||||||
|
|
||||||
// Declare i32 "foo" inside a block
|
// Declare i32 "foo" inside a block
|
||||||
auto* foo_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
|
auto* foo_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
|
||||||
auto* foo_i32_init = foo_i32->constructor;
|
auto* foo_i32_init = foo_i32->constructor;
|
||||||
|
@ -357,7 +357,7 @@ TEST_F(ResolverTest, Stmt_VariableDecl_OuterScopeAfterInnerScope) {
|
||||||
auto* bar_f32_init = bar_f32->constructor;
|
auto* bar_f32_init = bar_f32->constructor;
|
||||||
auto* bar_f32_decl = Decl(bar_f32);
|
auto* bar_f32_decl = Decl(bar_f32);
|
||||||
|
|
||||||
Func("func", params, ty.void_(), {inner, foo_f32_decl, bar_f32_decl}, ast::AttributeList{});
|
Func("func", {}, ty.void_(), {inner, foo_f32_decl, bar_f32_decl});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
ASSERT_NE(TypeOf(foo_i32_init), nullptr);
|
ASSERT_NE(TypeOf(foo_i32_init), nullptr);
|
||||||
|
@ -389,13 +389,11 @@ TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScopeAfterFunctionScope) {
|
||||||
// var bar : f32 = foo;
|
// var bar : f32 = foo;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
ast::VariableList params;
|
|
||||||
|
|
||||||
// Declare i32 "foo" inside a function
|
// Declare i32 "foo" inside a function
|
||||||
auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
|
auto* fn_i32 = Var("foo", ty.i32(), ast::StorageClass::kNone, Expr(2_i));
|
||||||
auto* fn_i32_init = fn_i32->constructor;
|
auto* fn_i32_init = fn_i32->constructor;
|
||||||
auto* fn_i32_decl = Decl(fn_i32);
|
auto* fn_i32_decl = Decl(fn_i32);
|
||||||
Func("func_i32", params, ty.void_(), {fn_i32_decl}, ast::AttributeList{});
|
Func("func_i32", {}, ty.void_(), {fn_i32_decl});
|
||||||
|
|
||||||
// Declare f32 "foo" at module scope
|
// Declare f32 "foo" at module scope
|
||||||
auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kPrivate, Expr(2_f));
|
auto* mod_f32 = Var("foo", ty.f32(), ast::StorageClass::kPrivate, Expr(2_f));
|
||||||
|
@ -406,7 +404,7 @@ TEST_F(ResolverTest, Stmt_VariableDecl_ModuleScopeAfterFunctionScope) {
|
||||||
auto* fn_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
|
auto* fn_f32 = Var("bar", ty.f32(), ast::StorageClass::kNone, Expr("foo"));
|
||||||
auto* fn_f32_init = fn_f32->constructor;
|
auto* fn_f32_init = fn_f32->constructor;
|
||||||
auto* fn_f32_decl = Decl(fn_f32);
|
auto* fn_f32_decl = Decl(fn_f32);
|
||||||
Func("func_f32", params, ty.void_(), {fn_f32_decl}, ast::AttributeList{});
|
Func("func_f32", {}, ty.void_(), {fn_f32_decl});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
ASSERT_NE(TypeOf(mod_init), nullptr);
|
ASSERT_NE(TypeOf(mod_init), nullptr);
|
||||||
|
@ -493,8 +491,7 @@ TEST_F(ResolverTest, Expr_Bitcast) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Expr_Call) {
|
TEST_F(ResolverTest, Expr_Call) {
|
||||||
ast::VariableList params;
|
Func("my_func", {}, ty.f32(), {Return(0_f)});
|
||||||
Func("my_func", params, ty.f32(), {Return(0_f)}, ast::AttributeList{});
|
|
||||||
|
|
||||||
auto* call = Call("my_func");
|
auto* call = Call("my_func");
|
||||||
WrapInFunction(call);
|
WrapInFunction(call);
|
||||||
|
@ -506,8 +503,7 @@ TEST_F(ResolverTest, Expr_Call) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Expr_Call_InBinaryOp) {
|
TEST_F(ResolverTest, Expr_Call_InBinaryOp) {
|
||||||
ast::VariableList params;
|
Func("func", {}, ty.f32(), {Return(0_f)});
|
||||||
Func("func", params, ty.f32(), {Return(0_f)}, ast::AttributeList{});
|
|
||||||
|
|
||||||
auto* expr = Add(Call("func"), Call("func"));
|
auto* expr = Add(Call("func"), Call("func"));
|
||||||
WrapInFunction(expr);
|
WrapInFunction(expr);
|
||||||
|
@ -639,12 +635,11 @@ TEST_F(ResolverTest, Expr_Identifier_FunctionVariable_Const) {
|
||||||
auto* var = Let("my_var", ty.f32(), Construct(ty.f32()));
|
auto* var = Let("my_var", ty.f32(), Construct(ty.f32()));
|
||||||
auto* decl = Decl(Var("b", ty.f32(), ast::StorageClass::kNone, my_var_a));
|
auto* decl = Decl(Var("b", ty.f32(), ast::StorageClass::kNone, my_var_a));
|
||||||
|
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
decl,
|
decl,
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -663,13 +658,12 @@ TEST_F(ResolverTest, IndexAccessor_Dynamic_Ref_F32) {
|
||||||
auto* a = Var("a", ty.array<bool, 10>(), array<bool, 10>());
|
auto* a = Var("a", ty.array<bool, 10>(), array<bool, 10>());
|
||||||
auto* idx = Var("idx", ty.f32(), Construct(ty.f32()));
|
auto* idx = Var("idx", ty.f32(), Construct(ty.f32()));
|
||||||
auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
|
auto* f = Var("f", ty.f32(), IndexAccessor("a", Expr(Source{{12, 34}}, idx)));
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(a),
|
Decl(a),
|
||||||
Decl(idx),
|
Decl(idx),
|
||||||
Decl(f),
|
Decl(f),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
|
||||||
|
@ -682,12 +676,11 @@ TEST_F(ResolverTest, Expr_Identifier_FunctionVariable) {
|
||||||
|
|
||||||
auto* var = Var("my_var", ty.f32());
|
auto* var = Var("my_var", ty.f32());
|
||||||
|
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
assign,
|
assign,
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -712,13 +705,12 @@ TEST_F(ResolverTest, Expr_Identifier_Function_Ptr) {
|
||||||
auto* v_decl = Decl(Var("v", ty.f32()));
|
auto* v_decl = Decl(Var("v", ty.f32()));
|
||||||
auto* p_decl = Decl(Let("p", ty.pointer<f32>(ast::StorageClass::kFunction), AddressOf(v)));
|
auto* p_decl = Decl(Let("p", ty.pointer<f32>(ast::StorageClass::kFunction), AddressOf(v)));
|
||||||
auto* assign = Assign(Deref(p), 1.23_f);
|
auto* assign = Assign(Deref(p), 1.23_f);
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
v_decl,
|
v_decl,
|
||||||
p_decl,
|
p_decl,
|
||||||
assign,
|
assign,
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -733,7 +725,10 @@ TEST_F(ResolverTest, Expr_Identifier_Function_Ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Expr_Call_Function) {
|
TEST_F(ResolverTest, Expr_Call_Function) {
|
||||||
Func("my_func", ast::VariableList{}, ty.f32(), {Return(0_f)}, ast::AttributeList{});
|
Func("my_func", {}, ty.f32(),
|
||||||
|
{
|
||||||
|
Return(0_f),
|
||||||
|
});
|
||||||
|
|
||||||
auto* call = Call("my_func");
|
auto* call = Call("my_func");
|
||||||
WrapInFunction(call);
|
WrapInFunction(call);
|
||||||
|
@ -757,7 +752,7 @@ TEST_F(ResolverTest, Function_Parameters) {
|
||||||
auto* param_c = Param("c", ty.u32());
|
auto* param_c = Param("c", ty.u32());
|
||||||
|
|
||||||
auto* func = Func("my_func",
|
auto* func = Func("my_func",
|
||||||
ast::VariableList{
|
{
|
||||||
param_a,
|
param_a,
|
||||||
param_b,
|
param_b,
|
||||||
param_c,
|
param_c,
|
||||||
|
@ -789,7 +784,7 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables) {
|
||||||
auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
|
auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
|
||||||
auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
|
auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* func = Func("my_func", ast::VariableList{}, ty.void_(),
|
auto* func = Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign("wg_var", "wg_var"),
|
Assign("wg_var", "wg_var"),
|
||||||
Assign("sb_var", "sb_var"),
|
Assign("sb_var", "sb_var"),
|
||||||
|
@ -821,12 +816,11 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
|
||||||
auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
|
auto* wg_var = Global("wg_var", ty.f32(), ast::StorageClass::kWorkgroup);
|
||||||
auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
|
auto* priv_var = Global("priv_var", ty.f32(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
Func("my_func", ast::VariableList{}, ty.f32(),
|
Func("my_func", {}, ty.f32(),
|
||||||
{Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"), Assign("priv_var", "priv_var"),
|
{Assign("wg_var", "wg_var"), Assign("sb_var", "sb_var"), Assign("priv_var", "priv_var"),
|
||||||
Return(0_f)},
|
Return(0_f)});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
auto* func2 = Func("func", ast::VariableList{}, ty.void_(),
|
auto* func2 = Func("func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
WrapInStatement(Call("my_func")),
|
WrapInStatement(Call("my_func")),
|
||||||
},
|
},
|
||||||
|
@ -846,7 +840,7 @@ TEST_F(ResolverTest, Function_RegisterInputOutputVariables_SubFunction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Function_NotRegisterFunctionVariable) {
|
TEST_F(ResolverTest, Function_NotRegisterFunctionVariable) {
|
||||||
auto* func = Func("my_func", ast::VariableList{}, ty.void_(),
|
auto* func = Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Var("var", ty.f32())),
|
Decl(Var("var", ty.f32())),
|
||||||
Assign("var", 1_f),
|
Assign("var", 1_f),
|
||||||
|
@ -862,7 +856,7 @@ TEST_F(ResolverTest, Function_NotRegisterFunctionVariable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Function_NotRegisterFunctionConstant) {
|
TEST_F(ResolverTest, Function_NotRegisterFunctionConstant) {
|
||||||
auto* func = Func("my_func", ast::VariableList{}, ty.void_(),
|
auto* func = Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Let("var", ty.f32(), Construct(ty.f32()))),
|
Decl(Let("var", ty.f32(), Construct(ty.f32()))),
|
||||||
});
|
});
|
||||||
|
@ -877,7 +871,7 @@ TEST_F(ResolverTest, Function_NotRegisterFunctionConstant) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Function_NotRegisterFunctionParams) {
|
TEST_F(ResolverTest, Function_NotRegisterFunctionParams) {
|
||||||
auto* func = Func("my_func", {Let("var", ty.f32(), Construct(ty.f32()))}, ty.void_(), {});
|
auto* func = Func("my_func", {Param("var", ty.f32())}, ty.void_(), {});
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
auto* func_sem = Sem().Get(func);
|
auto* func_sem = Sem().Get(func);
|
||||||
|
@ -888,11 +882,11 @@ TEST_F(ResolverTest, Function_NotRegisterFunctionParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(ResolverTest, Function_CallSites) {
|
TEST_F(ResolverTest, Function_CallSites) {
|
||||||
auto* foo = Func("foo", ast::VariableList{}, ty.void_(), {});
|
auto* foo = Func("foo", {}, ty.void_(), {});
|
||||||
|
|
||||||
auto* call_1 = Call("foo");
|
auto* call_1 = Call("foo");
|
||||||
auto* call_2 = Call("foo");
|
auto* call_2 = Call("foo");
|
||||||
auto* bar = Func("bar", ast::VariableList{}, ty.void_(),
|
auto* bar = Func("bar", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
CallStmt(call_1),
|
CallStmt(call_1),
|
||||||
CallStmt(call_2),
|
CallStmt(call_2),
|
||||||
|
@ -914,7 +908,7 @@ TEST_F(ResolverTest, Function_CallSites) {
|
||||||
TEST_F(ResolverTest, Function_WorkgroupSize_NotSet) {
|
TEST_F(ResolverTest, Function_WorkgroupSize_NotSet) {
|
||||||
// @compute @workgroup_size(1)
|
// @compute @workgroup_size(1)
|
||||||
// fn main() {}
|
// fn main() {}
|
||||||
auto* func = Func("main", ast::VariableList{}, ty.void_(), {}, {});
|
auto* func = Func("main", {}, ty.void_(), {});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -932,8 +926,11 @@ TEST_F(ResolverTest, Function_WorkgroupSize_NotSet) {
|
||||||
TEST_F(ResolverTest, Function_WorkgroupSize_Literals) {
|
TEST_F(ResolverTest, Function_WorkgroupSize_Literals) {
|
||||||
// @compute @workgroup_size(8, 2, 3)
|
// @compute @workgroup_size(8, 2, 3)
|
||||||
// fn main() {}
|
// fn main() {}
|
||||||
auto* func = Func("main", ast::VariableList{}, ty.void_(), {},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(8_i, 2_i, 3_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(8_i, 2_i, 3_i),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -957,9 +954,11 @@ TEST_F(ResolverTest, Function_WorkgroupSize_Consts) {
|
||||||
GlobalConst("width", ty.i32(), Expr(16_i));
|
GlobalConst("width", ty.i32(), Expr(16_i));
|
||||||
GlobalConst("height", ty.i32(), Expr(8_i));
|
GlobalConst("height", ty.i32(), Expr(8_i));
|
||||||
GlobalConst("depth", ty.i32(), Expr(2_i));
|
GlobalConst("depth", ty.i32(), Expr(2_i));
|
||||||
auto* func =
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
{
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height", "depth")});
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -983,8 +982,11 @@ TEST_F(ResolverTest, Function_WorkgroupSize_Consts_NestedInitializer) {
|
||||||
Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 8_i))));
|
Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 8_i))));
|
||||||
GlobalConst("height", ty.i32(),
|
GlobalConst("height", ty.i32(),
|
||||||
Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 4_i))));
|
Construct(ty.i32(), Construct(ty.i32(), Construct(ty.i32(), 4_i))));
|
||||||
auto* func = Func("main", ast::VariableList{}, ty.void_(), {},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height")});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize("width", "height"),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1008,9 +1010,11 @@ TEST_F(ResolverTest, Function_WorkgroupSize_OverridableConsts) {
|
||||||
auto* width = Override("width", ty.i32(), Expr(16_i), {Id(0)});
|
auto* width = Override("width", ty.i32(), Expr(16_i), {Id(0)});
|
||||||
auto* height = Override("height", ty.i32(), Expr(8_i), {Id(1)});
|
auto* height = Override("height", ty.i32(), Expr(8_i), {Id(1)});
|
||||||
auto* depth = Override("depth", ty.i32(), Expr(2_i), {Id(2)});
|
auto* depth = Override("depth", ty.i32(), Expr(2_i), {Id(2)});
|
||||||
auto* func =
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
{
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height", "depth")});
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1034,9 +1038,11 @@ TEST_F(ResolverTest, Function_WorkgroupSize_OverridableConsts_NoInit) {
|
||||||
auto* width = Override("width", ty.i32(), nullptr, {Id(0)});
|
auto* width = Override("width", ty.i32(), nullptr, {Id(0)});
|
||||||
auto* height = Override("height", ty.i32(), nullptr, {Id(1)});
|
auto* height = Override("height", ty.i32(), nullptr, {Id(1)});
|
||||||
auto* depth = Override("depth", ty.i32(), nullptr, {Id(2)});
|
auto* depth = Override("depth", ty.i32(), nullptr, {Id(2)});
|
||||||
auto* func =
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
{
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize("width", "height", "depth")});
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1058,8 +1064,11 @@ TEST_F(ResolverTest, Function_WorkgroupSize_Mixed) {
|
||||||
// fn main() {}
|
// fn main() {}
|
||||||
auto* height = Override("height", ty.i32(), Expr(2_i), {Id(0)});
|
auto* height = Override("height", ty.i32(), Expr(2_i), {Id(0)});
|
||||||
GlobalConst("depth", ty.i32(), Expr(3_i));
|
GlobalConst("depth", ty.i32(), Expr(3_i));
|
||||||
auto* func = Func("main", ast::VariableList{}, ty.void_(), {},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(8_i, "height", "depth")});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(8_i, "height", "depth"),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1709,7 +1718,7 @@ TEST_F(ResolverTest, StorageClass_SetsIfMissing) {
|
||||||
auto* var = Var("var", ty.i32());
|
auto* var = Var("var", ty.i32());
|
||||||
|
|
||||||
auto* stmt = Decl(var);
|
auto* stmt = Decl(var);
|
||||||
Func("func", ast::VariableList{}, ty.void_(), {stmt}, ast::AttributeList{});
|
Func("func", {}, ty.void_(), {stmt});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1745,7 +1754,7 @@ TEST_F(ResolverTest, StorageClass_SetForTexture) {
|
||||||
TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
|
TEST_F(ResolverTest, StorageClass_DoesNotSetOnConst) {
|
||||||
auto* var = Let("var", ty.i32(), Construct(ty.i32()));
|
auto* var = Let("var", ty.i32(), Construct(ty.i32()));
|
||||||
auto* stmt = Decl(var);
|
auto* stmt = Decl(var);
|
||||||
Func("func", ast::VariableList{}, ty.void_(), {stmt}, ast::AttributeList{});
|
Func("func", {}, ty.void_(), {stmt});
|
||||||
|
|
||||||
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
EXPECT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1802,26 +1811,40 @@ TEST_F(ResolverTest, Function_EntryPoints_StageAttribute) {
|
||||||
Global("call_b", ty.f32(), ast::StorageClass::kPrivate);
|
Global("call_b", ty.f32(), ast::StorageClass::kPrivate);
|
||||||
Global("call_c", ty.f32(), ast::StorageClass::kPrivate);
|
Global("call_c", ty.f32(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
ast::VariableList params;
|
auto* func_b = Func("b", {}, ty.f32(),
|
||||||
auto* func_b = Func("b", params, ty.f32(), {Return(0_f)}, ast::AttributeList{});
|
{
|
||||||
auto* func_c = Func("c", params, ty.f32(), {Assign("second", Call("b")), Return(0_f)},
|
Return(0_f),
|
||||||
ast::AttributeList{});
|
});
|
||||||
|
auto* func_c = Func("c", {}, ty.f32(),
|
||||||
|
{
|
||||||
|
Assign("second", Call("b")),
|
||||||
|
Return(0_f),
|
||||||
|
});
|
||||||
|
|
||||||
auto* func_a = Func("a", params, ty.f32(), {Assign("first", Call("c")), Return(0_f)},
|
auto* func_a = Func("a", {}, ty.f32(),
|
||||||
ast::AttributeList{});
|
{
|
||||||
|
Assign("first", Call("c")),
|
||||||
|
Return(0_f),
|
||||||
|
});
|
||||||
|
|
||||||
auto* ep_1 = Func("ep_1", params, ty.void_(),
|
auto* ep_1 = Func("ep_1", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign("call_a", Call("a")),
|
Assign("call_a", Call("a")),
|
||||||
Assign("call_b", Call("b")),
|
Assign("call_b", Call("b")),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
|
|
||||||
auto* ep_2 = Func("ep_2", params, ty.void_(),
|
auto* ep_2 = Func("ep_2", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign("call_c", Call("c")),
|
Assign("call_c", Call("c")),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
|
|
||||||
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
ASSERT_TRUE(r()->Resolve()) << r()->error();
|
||||||
|
|
||||||
|
@ -1875,8 +1898,8 @@ TEST_F(ResolverTest, Function_EntryPoints_LinearTime) {
|
||||||
auto fn_a = [](int level) { return "l" + std::to_string(level + 1) + "a"; };
|
auto fn_a = [](int level) { return "l" + std::to_string(level + 1) + "a"; };
|
||||||
auto fn_b = [](int level) { return "l" + std::to_string(level + 1) + "b"; };
|
auto fn_b = [](int level) { return "l" + std::to_string(level + 1) + "b"; };
|
||||||
|
|
||||||
Func(fn_a(levels), {}, ty.void_(), {}, {});
|
Func(fn_a(levels), {}, ty.void_(), {});
|
||||||
Func(fn_b(levels), {}, ty.void_(), {}, {});
|
Func(fn_b(levels), {}, ty.void_(), {});
|
||||||
|
|
||||||
for (int i = levels - 1; i >= 0; i--) {
|
for (int i = levels - 1; i >= 0; i--) {
|
||||||
Func(fn_a(i), {}, ty.void_(),
|
Func(fn_a(i), {}, ty.void_(),
|
||||||
|
|
|
@ -121,9 +121,10 @@ TEST_F(ResolverTypeValidationTest, GlobalVariableFunctionVariableNotUnique_Pass)
|
||||||
// }
|
// }
|
||||||
// var a: f32 = 2.1;
|
// var a: f32 = 2.1;
|
||||||
|
|
||||||
auto* var = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2_f));
|
Func("my_func", {}, ty.void_(),
|
||||||
|
{
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(), {Decl(var)});
|
Decl(Var("a", ty.f32(), ast::StorageClass::kNone, Expr(2_f))),
|
||||||
|
});
|
||||||
|
|
||||||
Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
|
Global("a", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
|
||||||
|
|
||||||
|
@ -172,15 +173,14 @@ TEST_F(ResolverTypeValidationTest, RedeclaredIdentifierDifferentFunctions_Pass)
|
||||||
|
|
||||||
auto* var1 = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(1_f));
|
auto* var1 = Var("a", ty.f32(), ast::StorageClass::kNone, Expr(1_f));
|
||||||
|
|
||||||
Func("func0", ast::VariableList{}, ty.void_(),
|
Func("func0", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Source{{12, 34}}, var0),
|
Decl(Source{{12, 34}}, var0),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
Func("func1", ast::VariableList{}, ty.void_(),
|
Func("func1", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Source{{13, 34}}, var1),
|
Decl(Source{{13, 34}}, var1),
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -374,11 +374,11 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayInFunction_Fail) {
|
||||||
|
|
||||||
auto* var = Var(Source{{12, 34}}, "a", ty.array<i32>(), ast::StorageClass::kNone);
|
auto* var = Var(Source{{12, 34}}, "a", ty.array<i32>(), ast::StorageClass::kNone);
|
||||||
|
|
||||||
Func("func", ast::VariableList{}, ty.void_(),
|
Func("func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kVertex),
|
Stage(ast::PipelineStage::kVertex),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -556,17 +556,16 @@ TEST_F(ResolverTypeValidationTest, RuntimeArrayAsParameter_Fail) {
|
||||||
|
|
||||||
auto* param = Param(Source{{12, 34}}, "a", ty.array<i32>());
|
auto* param = Param(Source{{12, 34}}, "a", ty.array<i32>());
|
||||||
|
|
||||||
Func("func", ast::VariableList{param}, ty.void_(),
|
Func("func", {param}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kVertex),
|
Stage(ast::PipelineStage::kVertex),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -582,11 +581,10 @@ TEST_F(ResolverTypeValidationTest, PtrToRuntimeArrayAsParameter_Fail) {
|
||||||
auto* param =
|
auto* param =
|
||||||
Param(Source{{12, 34}}, "a", ty.pointer(ty.array<i32>(), ast::StorageClass::kWorkgroup));
|
Param(Source{{12, 34}}, "a", ty.pointer(ty.array<i32>(), ast::StorageClass::kWorkgroup));
|
||||||
|
|
||||||
Func("func", ast::VariableList{param}, ty.void_(),
|
Func("func", {param}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
EXPECT_FALSE(r()->Resolve()) << r()->error();
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
|
|
|
@ -65,9 +65,17 @@ TEST_F(ResolverValidationTest, WorkgroupMemoryUsedInVertexStage) {
|
||||||
Global("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
Global("dst", ty.vec4<f32>(), ast::StorageClass::kPrivate);
|
||||||
auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
|
auto* stmt = Assign(Expr("dst"), Expr(Source{{3, 4}}, "wg"));
|
||||||
|
|
||||||
Func(Source{{9, 10}}, "f0", ast::VariableList{}, ty.vec4<f32>(), {stmt, Return(Expr("dst"))},
|
Func(Source{{9, 10}}, "f0", {}, ty.vec4<f32>(),
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kVertex)},
|
{
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kPosition)});
|
stmt,
|
||||||
|
Return(Expr("dst")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kVertex),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kPosition),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
EXPECT_EQ(r()->error(),
|
EXPECT_EQ(r()->error(),
|
||||||
|
@ -215,7 +223,7 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariableGlobalVariable_Pass) {
|
||||||
|
|
||||||
Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
|
Global("global_var", ty.f32(), ast::StorageClass::kPrivate, Expr(2.1_f));
|
||||||
|
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign(Expr(Source{{12, 34}}, "global_var"), 3.14_f),
|
Assign(Expr(Source{{12, 34}}, "global_var"), 3.14_f),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -289,8 +297,10 @@ TEST_F(ResolverValidationTest, UsingUndefinedVariableDifferentScope_Fail) {
|
||||||
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
|
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
|
||||||
auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
|
auto* var = Var("var", ty.i32(), ast::StorageClass::kWorkgroup);
|
||||||
|
|
||||||
auto* stmt = Decl(var);
|
Func("func", {}, ty.void_(),
|
||||||
Func("func", ast::VariableList{}, ty.void_(), {stmt}, ast::AttributeList{});
|
{
|
||||||
|
Decl(var),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
|
||||||
|
@ -300,8 +310,10 @@ TEST_F(ResolverValidationTest, StorageClass_FunctionVariableWorkgroupClass) {
|
||||||
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableI32) {
|
TEST_F(ResolverValidationTest, StorageClass_FunctionVariableI32) {
|
||||||
auto* var = Var("s", ty.i32(), ast::StorageClass::kPrivate);
|
auto* var = Var("s", ty.i32(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* stmt = Decl(var);
|
Func("func", {}, ty.void_(),
|
||||||
Func("func", ast::VariableList{}, ty.void_(), {stmt}, ast::AttributeList{});
|
{
|
||||||
|
Decl(var),
|
||||||
|
});
|
||||||
|
|
||||||
EXPECT_FALSE(r()->Resolve());
|
EXPECT_FALSE(r()->Resolve());
|
||||||
|
|
||||||
|
|
|
@ -264,10 +264,16 @@ struct MultiplanarExternalTexture::State {
|
||||||
/// Creates the gammaCorrection function if needed and returns a call
|
/// Creates the gammaCorrection function if needed and returns a call
|
||||||
/// expression to it.
|
/// expression to it.
|
||||||
void createGammaCorrectionFn() {
|
void createGammaCorrectionFn() {
|
||||||
ast::VariableList varList = {b.Param("v", b.ty.vec3<f32>()),
|
gamma_correction_sym = b.Symbols().New("gammaCorrection");
|
||||||
b.Param("params", b.ty.type_name(gamma_transfer_struct_sym))};
|
|
||||||
|
|
||||||
ast::StatementList statementList = {
|
b.Func(
|
||||||
|
gamma_correction_sym,
|
||||||
|
{
|
||||||
|
b.Param("v", b.ty.vec3<f32>()),
|
||||||
|
b.Param("params", b.ty.type_name(gamma_transfer_struct_sym)),
|
||||||
|
},
|
||||||
|
b.ty.vec3<f32>(),
|
||||||
|
{
|
||||||
// let cond = abs(v) < vec3(params.D);
|
// let cond = abs(v) < vec3(params.D);
|
||||||
b.Decl(b.Let(
|
b.Decl(b.Let(
|
||||||
"cond", nullptr,
|
"cond", nullptr,
|
||||||
|
@ -279,20 +285,17 @@ struct MultiplanarExternalTexture::State {
|
||||||
b.MemberAccessor("params", "F"))))),
|
b.MemberAccessor("params", "F"))))),
|
||||||
// let f = (sign(v) * pow(((params.A * abs(v)) + params.B),
|
// let f = (sign(v) * pow(((params.A * abs(v)) + params.B),
|
||||||
// vec3(params.G))) + params.E;
|
// vec3(params.G))) + params.E;
|
||||||
b.Decl(b.Let(
|
b.Decl(b.Let("f", nullptr,
|
||||||
"f", nullptr,
|
|
||||||
b.Mul(b.Call("sign", "v"),
|
b.Mul(b.Call("sign", "v"),
|
||||||
b.Add(b.Call("pow",
|
b.Add(b.Call("pow",
|
||||||
b.Add(b.Mul(b.MemberAccessor("params", "A"), b.Call("abs", "v")),
|
b.Add(b.Mul(b.MemberAccessor("params", "A"),
|
||||||
|
b.Call("abs", "v")),
|
||||||
b.MemberAccessor("params", "B")),
|
b.MemberAccessor("params", "B")),
|
||||||
b.vec3<f32>(b.MemberAccessor("params", "G"))),
|
b.vec3<f32>(b.MemberAccessor("params", "G"))),
|
||||||
b.MemberAccessor("params", "E"))))),
|
b.MemberAccessor("params", "E"))))),
|
||||||
// return select(f, t, cond);
|
// return select(f, t, cond);
|
||||||
b.Return(b.Call("select", "f", "t", "cond"))};
|
b.Return(b.Call("select", "f", "t", "cond")),
|
||||||
|
});
|
||||||
gamma_correction_sym = b.Symbols().New("gammaCorrection");
|
|
||||||
|
|
||||||
b.Func(gamma_correction_sym, varList, b.ty.vec3<f32>(), statementList, {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a StatementList containing all the statements making up the
|
/// Constructs a StatementList containing all the statements making up the
|
||||||
|
@ -375,17 +378,19 @@ struct MultiplanarExternalTexture::State {
|
||||||
texture_sample_external_sym = b.Symbols().New("textureSampleExternal");
|
texture_sample_external_sym = b.Symbols().New("textureSampleExternal");
|
||||||
|
|
||||||
// Emit the textureSampleExternal function.
|
// Emit the textureSampleExternal function.
|
||||||
ast::VariableList varList = {
|
b.Func(
|
||||||
|
texture_sample_external_sym,
|
||||||
|
{
|
||||||
b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
||||||
b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
||||||
b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
|
b.Param("smp", b.ty.sampler(ast::SamplerKind::kSampler)),
|
||||||
b.Param("coord", b.ty.vec2(b.ty.f32())),
|
b.Param("coord", b.ty.vec2(b.ty.f32())),
|
||||||
b.Param("params", b.ty.type_name(params_struct_sym))};
|
b.Param("params", b.ty.type_name(params_struct_sym)),
|
||||||
|
},
|
||||||
ast::StatementList statementList =
|
b.ty.vec4(b.ty.f32()),
|
||||||
createTexFnExtStatementList(sem::BuiltinType::kTextureSampleLevel);
|
{
|
||||||
|
createTexFnExtStatementList(sem::BuiltinType::kTextureSampleLevel),
|
||||||
b.Func(texture_sample_external_sym, varList, b.ty.vec4(b.ty.f32()), statementList, {});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::IdentifierExpression* exp = b.Expr(texture_sample_external_sym);
|
const ast::IdentifierExpression* exp = b.Expr(texture_sample_external_sym);
|
||||||
|
@ -421,22 +426,22 @@ struct MultiplanarExternalTexture::State {
|
||||||
texture_load_external_sym = b.Symbols().New("textureLoadExternal");
|
texture_load_external_sym = b.Symbols().New("textureLoadExternal");
|
||||||
|
|
||||||
// Emit the textureLoadExternal function.
|
// Emit the textureLoadExternal function.
|
||||||
ast::VariableList var_list = {
|
b.Func(
|
||||||
|
texture_load_external_sym,
|
||||||
|
{
|
||||||
b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
b.Param("plane0", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
||||||
b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
b.Param("plane1", b.ty.sampled_texture(ast::TextureDimension::k2d, b.ty.f32())),
|
||||||
b.Param("coord", b.ty.vec2(b.ty.i32())),
|
b.Param("coord", b.ty.vec2(b.ty.i32())),
|
||||||
b.Param("params", b.ty.type_name(params_struct_sym))};
|
b.Param("params", b.ty.type_name(params_struct_sym)),
|
||||||
|
},
|
||||||
ast::StatementList statement_list =
|
b.ty.vec4(b.ty.f32()),
|
||||||
createTexFnExtStatementList(sem::BuiltinType::kTextureLoad);
|
{
|
||||||
|
createTexFnExtStatementList(sem::BuiltinType::kTextureLoad),
|
||||||
b.Func(texture_load_external_sym, var_list, b.ty.vec4(b.ty.f32()), statement_list, {});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const ast::IdentifierExpression* exp = b.Expr(texture_load_external_sym);
|
return b.Call(texture_load_external_sym, plane_0_binding_param, syms.plane_1,
|
||||||
params = {plane_0_binding_param, b.Expr(syms.plane_1), ctx.Clone(expr->args[1]),
|
ctx.Clone(expr->args[1]), syms.params);
|
||||||
b.Expr(syms.params)};
|
|
||||||
return b.Call(exp, params);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace {
|
||||||
using GlslGeneratorImplTest_Function = TestHelper;
|
using GlslGeneratorImplTest_Function = TestHelper;
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Function) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Function) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -48,7 +48,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Function) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
|
||||||
Func("centroid", ast::VariableList{}, ty.void_(),
|
Func("centroid", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -64,7 +64,12 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
||||||
Func("my_func", ast::VariableList{Param("a", ty.f32()), Param("b", ty.i32())}, ty.void_(),
|
Func("my_func",
|
||||||
|
{
|
||||||
|
Param("a", ty.f32()),
|
||||||
|
Param("b", ty.i32()),
|
||||||
|
},
|
||||||
|
ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -84,7 +89,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_NoReturn_Void) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_NoReturn_Void) {
|
||||||
Func("func", ast::VariableList{}, ty.void_(), {/* no explicit return */},
|
Func("func", {}, ty.void_(), {/* no explicit return */},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
@ -121,9 +126,20 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithInOutVars)
|
||||||
// fn frag_main(@location(0) foo : f32) -> @location(1) f32 {
|
// fn frag_main(@location(0) foo : f32) -> @location(1) f32 {
|
||||||
// return foo;
|
// return foo;
|
||||||
// }
|
// }
|
||||||
auto* foo_in = Param("foo", ty.f32(), {Location(0)});
|
Func("frag_main",
|
||||||
Func("frag_main", ast::VariableList{foo_in}, ty.f32(), {Return("foo")},
|
{
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(1)});
|
Param("foo", ty.f32(), {Location(0)}),
|
||||||
|
},
|
||||||
|
ty.f32(),
|
||||||
|
{
|
||||||
|
Return("foo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(1),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -150,8 +166,20 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithInOut_Built
|
||||||
// return coord.x;
|
// return coord.x;
|
||||||
// }
|
// }
|
||||||
auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
||||||
Func("frag_main", ast::VariableList{coord_in}, ty.f32(), {Return(MemberAccessor("coord", "x"))},
|
Func("frag_main",
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::Builtin::kFragDepth)});
|
{
|
||||||
|
coord_in,
|
||||||
|
},
|
||||||
|
ty.f32(),
|
||||||
|
{
|
||||||
|
Return(MemberAccessor("coord", "x")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kFragDepth),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -384,7 +412,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStr
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
|
||||||
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
|
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -428,7 +456,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RW_Storage
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -478,7 +506,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RO_Storage
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -527,7 +555,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_WO_Storage
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -575,7 +603,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_StorageBuf
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -619,14 +647,14 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("sub_func", ast::VariableList{Param("param", ty.f32())}, ty.f32(),
|
Func("sub_func", {Param("param", ty.f32())}, ty.f32(),
|
||||||
{
|
{
|
||||||
Return(MemberAccessor("coord", "x")),
|
Return(MemberAccessor("coord", "x")),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -668,14 +696,14 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("sub_func", ast::VariableList{Param("param", ty.f32())}, ty.f32(),
|
Func("sub_func", {Param("param", ty.f32())}, ty.f32(),
|
||||||
{
|
{
|
||||||
Return(MemberAccessor("coord", "x")),
|
Return(MemberAccessor("coord", "x")),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -715,7 +743,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollision) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollision) {
|
||||||
Func("centroid", ast::VariableList{}, ty.void_(), {},
|
Func("centroid", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
@ -737,11 +765,14 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute) {
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
@ -756,7 +787,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Literal) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Literal) {
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
Func("main", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(2_i, 4_i, 6_i),
|
WorkgroupSize(2_i, 4_i, 6_i),
|
||||||
|
@ -778,7 +809,7 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWor
|
||||||
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
|
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
|
||||||
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
|
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
|
||||||
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
|
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
Func("main", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize("width", "height", "depth"),
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
@ -804,7 +835,7 @@ TEST_F(GlslGeneratorImplTest_Function,
|
||||||
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
||||||
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
|
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
|
||||||
Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
|
Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
Func("main", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize("width", "height", "depth"),
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
@ -835,7 +866,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
|
TEST_F(GlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
|
||||||
Func("my_func", ast::VariableList{Param("a", ty.array<f32, 5>())}, ty.void_(),
|
Func("my_func", {Param("a", ty.array<f32, 5>())}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -900,23 +931,29 @@ TEST_F(GlslGeneratorImplTest_Function, Emit_Multiple_EntryPoint_With_Same_Module
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("a", ast::VariableList{}, ty.void_(),
|
Func("a", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("b", ast::VariableList{}, ty.void_(),
|
Func("b", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
|
@ -100,8 +100,8 @@ class GlslGeneratorImplTest_MemberAccessorBase : public BASE {
|
||||||
|
|
||||||
void SetupFunction(ast::StatementList statements) {
|
void SetupFunction(ast::StatementList statements) {
|
||||||
ProgramBuilder& b = *this;
|
ProgramBuilder& b = *this;
|
||||||
b.Func("main", ast::VariableList{}, b.ty.void_(), statements,
|
b.Func("main", {}, b.ty.void_(), statements,
|
||||||
ast::AttributeList{
|
{
|
||||||
b.Stage(ast::PipelineStage::kFragment),
|
b.Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,12 @@ TEST_F(GlslSanitizerTest, Call_ArrayLength) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -75,12 +75,12 @@ TEST_F(GlslSanitizerTest, Call_ArrayLength_OtherMembersInStruct) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -120,13 +120,13 @@ TEST_F(GlslSanitizerTest, Call_ArrayLength_ViaLets) {
|
||||||
auto* p = Let("p", nullptr, AddressOf("b"));
|
auto* p = Let("p", nullptr, AddressOf("b"));
|
||||||
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
|
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(p),
|
Decl(p),
|
||||||
Decl(p2),
|
Decl(p2),
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ TEST_F(GlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
||||||
auto* array_index = IndexAccessor(array_init, 3_i);
|
auto* array_index = IndexAccessor(array_init, 3_i);
|
||||||
auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
|
auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(pos),
|
Decl(pos),
|
||||||
},
|
},
|
||||||
|
@ -198,7 +198,7 @@ TEST_F(GlslSanitizerTest, PromoteStructInitializerToConstVar) {
|
||||||
auto* struct_access = MemberAccessor(struct_init, "b");
|
auto* struct_access = MemberAccessor(struct_init, "b");
|
||||||
auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
|
auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(pos),
|
Decl(pos),
|
||||||
},
|
},
|
||||||
|
@ -241,7 +241,7 @@ TEST_F(GlslSanitizerTest, InlinePtrLetsBasic) {
|
||||||
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
|
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
|
||||||
auto* x = Var("x", ty.i32(), ast::StorageClass::kNone, Deref(p));
|
auto* x = Var("x", ty.i32(), ast::StorageClass::kNone, Deref(p));
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(v),
|
Decl(v),
|
||||||
Decl(p),
|
Decl(p),
|
||||||
|
@ -287,7 +287,7 @@ TEST_F(GlslSanitizerTest, InlinePtrLetsComplexChain) {
|
||||||
AddressOf(IndexAccessor(Deref(mp), 2_i)));
|
AddressOf(IndexAccessor(Deref(mp), 2_i)));
|
||||||
auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
|
auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(a),
|
Decl(a),
|
||||||
Decl(ap),
|
Decl(ap),
|
||||||
|
|
|
@ -29,7 +29,7 @@ TEST_F(GlslGeneratorImplTest, InvalidProgram) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest, Generate) {
|
TEST_F(GlslGeneratorImplTest, Generate) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
Func("my_func", {}, ty.void_(), {});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ void my_func() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest, GenerateDesktop) {
|
TEST_F(GlslGeneratorImplTest, GenerateDesktop) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
Func("my_func", {}, ty.void_(), {});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
|
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
|
||||||
|
|
||||||
|
@ -58,10 +58,15 @@ void my_func() {
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexES) {
|
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexES) {
|
||||||
Global("gl_SampleID", ty.i32(),
|
Global("gl_SampleID", ty.i32(),
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kSampleIndex),
|
ast::AttributeList{
|
||||||
Disable(ast::DisabledValidation::kIgnoreStorageClass)},
|
Builtin(ast::Builtin::kSampleIndex),
|
||||||
|
Disable(ast::DisabledValidation::kIgnoreStorageClass),
|
||||||
|
},
|
||||||
ast::StorageClass::kInput);
|
ast::StorageClass::kInput);
|
||||||
Func("my_func", {}, ty.i32(), ast::StatementList{Return(Expr("gl_SampleID"))});
|
Func("my_func", {}, ty.i32(),
|
||||||
|
{
|
||||||
|
Return(Expr("gl_SampleID")),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build(Version(Version::Standard::kES, 3, 1));
|
GeneratorImpl& gen = Build(Version(Version::Standard::kES, 3, 1));
|
||||||
|
|
||||||
|
@ -78,10 +83,15 @@ int my_func() {
|
||||||
|
|
||||||
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexDesktop) {
|
TEST_F(GlslGeneratorImplTest, GenerateSampleIndexDesktop) {
|
||||||
Global("gl_SampleID", ty.i32(),
|
Global("gl_SampleID", ty.i32(),
|
||||||
ast::AttributeList{Builtin(ast::Builtin::kSampleIndex),
|
ast::AttributeList{
|
||||||
Disable(ast::DisabledValidation::kIgnoreStorageClass)},
|
Builtin(ast::Builtin::kSampleIndex),
|
||||||
|
Disable(ast::DisabledValidation::kIgnoreStorageClass),
|
||||||
|
},
|
||||||
ast::StorageClass::kInput);
|
ast::StorageClass::kInput);
|
||||||
Func("my_func", {}, ty.i32(), ast::StatementList{Return(Expr("gl_SampleID"))});
|
Func("my_func", {}, ty.i32(),
|
||||||
|
{
|
||||||
|
Return(Expr("gl_SampleID")),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
|
GeneratorImpl& gen = Build(Version(Version::Standard::kDesktop, 4, 4));
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace {
|
||||||
using HlslGeneratorImplTest_Function = TestHelper;
|
using HlslGeneratorImplTest_Function = TestHelper;
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Function) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Function) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -45,7 +45,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
|
||||||
Func("GeometryShader", ast::VariableList{}, ty.void_(),
|
Func("GeometryShader", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -61,7 +61,12 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function_Name_Collision) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
||||||
Func("my_func", ast::VariableList{Param("a", ty.f32()), Param("b", ty.i32())}, ty.void_(),
|
Func("my_func",
|
||||||
|
{
|
||||||
|
Param("a", ty.f32()),
|
||||||
|
Param("b", ty.i32()),
|
||||||
|
},
|
||||||
|
ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -78,7 +83,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_NoReturn_Void) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_NoReturn_Void) {
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {/* no explicit return */},
|
Func("main", {}, ty.void_(), {/* no explicit return */},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
@ -113,8 +118,16 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithInOutVars)
|
||||||
// return foo;
|
// return foo;
|
||||||
// }
|
// }
|
||||||
auto* foo_in = Param("foo", ty.f32(), {Location(0)});
|
auto* foo_in = Param("foo", ty.f32(), {Location(0)});
|
||||||
Func("frag_main", ast::VariableList{foo_in}, ty.f32(), {Return("foo")},
|
Func("frag_main", {foo_in}, ty.f32(),
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(1)});
|
{
|
||||||
|
Return("foo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(1),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -144,8 +157,16 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithInOut_Built
|
||||||
// return coord.x;
|
// return coord.x;
|
||||||
// }
|
// }
|
||||||
auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
||||||
Func("frag_main", ast::VariableList{coord_in}, ty.f32(), {Return(MemberAccessor("coord", "x"))},
|
Func("frag_main", {coord_in}, ty.f32(),
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::Builtin::kFragDepth)});
|
{
|
||||||
|
Return(MemberAccessor("coord", "x")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kFragDepth),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -381,7 +402,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_UniformStr
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone,
|
||||||
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
|
MemberAccessor(MemberAccessor("uniforms", "coord"), "x"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -418,7 +439,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RW_Storage
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -454,7 +475,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_RO_Storage
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -488,7 +509,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_WO_Storage
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -522,7 +543,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_With_StorageBuf
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
Assign(MemberAccessor("coord", "b"), Expr(2_f)),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -552,14 +573,18 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("sub_func", ast::VariableList{Param("param", ty.f32())}, ty.f32(),
|
Func("sub_func",
|
||||||
|
{
|
||||||
|
Param("param", ty.f32()),
|
||||||
|
},
|
||||||
|
ty.f32(),
|
||||||
{
|
{
|
||||||
Return(MemberAccessor("coord", "x")),
|
Return(MemberAccessor("coord", "x")),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -594,14 +619,18 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_Called_By_EntryPoint_With_
|
||||||
create<ast::GroupAttribute>(1),
|
create<ast::GroupAttribute>(1),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("sub_func", ast::VariableList{Param("param", ty.f32())}, ty.f32(),
|
Func("sub_func",
|
||||||
|
{
|
||||||
|
Param("param", ty.f32()),
|
||||||
|
},
|
||||||
|
ty.f32(),
|
||||||
{
|
{
|
||||||
Return(MemberAccessor("coord", "x")),
|
Return(MemberAccessor("coord", "x")),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
|
@ -628,7 +657,7 @@ void frag_main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollision) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollision) {
|
||||||
Func("GeometryShader", ast::VariableList{}, ty.void_(), {},
|
Func("GeometryShader", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
@ -643,7 +672,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_WithNameCollisi
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute) {
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
|
@ -660,7 +689,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Literal) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Literal) {
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
Func("main", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(2_i, 4_i, 6_i),
|
WorkgroupSize(2_i, 4_i, 6_i),
|
||||||
|
@ -680,7 +709,7 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWor
|
||||||
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
|
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
|
||||||
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
|
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
|
||||||
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
|
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
Func("main", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize("width", "height", "depth"),
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
@ -705,7 +734,7 @@ TEST_F(HlslGeneratorImplTest_Function,
|
||||||
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
||||||
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
|
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
|
||||||
Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
|
Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
|
||||||
Func("main", ast::VariableList{}, ty.void_(), {},
|
Func("main", {}, ty.void_(), {},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize("width", "height", "depth"),
|
WorkgroupSize("width", "height", "depth"),
|
||||||
|
@ -735,7 +764,11 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
|
TEST_F(HlslGeneratorImplTest_Function, Emit_Function_WithArrayParams) {
|
||||||
Func("my_func", ast::VariableList{Param("a", ty.array<f32, 5>())}, ty.void_(),
|
Func("my_func",
|
||||||
|
{
|
||||||
|
Param("a", ty.array<f32, 5>()),
|
||||||
|
},
|
||||||
|
ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -839,23 +872,29 @@ TEST_F(HlslGeneratorImplTest_Function, Emit_Multiple_EntryPoint_With_Same_Module
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("a", ast::VariableList{}, ty.void_(),
|
Func("a", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("b", ast::VariableList{}, ty.void_(),
|
Func("b", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{
|
||||||
|
Stage(ast::PipelineStage::kCompute),
|
||||||
|
WorkgroupSize(1_i),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
|
@ -100,8 +100,8 @@ class HlslGeneratorImplTest_MemberAccessorBase : public BASE {
|
||||||
|
|
||||||
void SetupFunction(ast::StatementList statements) {
|
void SetupFunction(ast::StatementList statements) {
|
||||||
ProgramBuilder& b = *this;
|
ProgramBuilder& b = *this;
|
||||||
b.Func("main", ast::VariableList{}, b.ty.void_(), statements,
|
b.Func("main", {}, b.ty.void_(), statements,
|
||||||
ast::AttributeList{
|
{
|
||||||
b.Stage(ast::PipelineStage::kFragment),
|
b.Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,12 @@ TEST_F(HlslSanitizerTest, Call_ArrayLength) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,12 +70,12 @@ TEST_F(HlslSanitizerTest, Call_ArrayLength_OtherMembersInStruct) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -109,13 +109,13 @@ TEST_F(HlslSanitizerTest, Call_ArrayLength_ViaLets) {
|
||||||
auto* p = Let("p", nullptr, AddressOf("b"));
|
auto* p = Let("p", nullptr, AddressOf("b"));
|
||||||
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
|
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(p),
|
Decl(p),
|
||||||
Decl(p2),
|
Decl(p2),
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -151,13 +151,13 @@ TEST_F(HlslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
|
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
|
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ TEST_F(HlslSanitizerTest, PromoteArrayInitializerToConstVar) {
|
||||||
auto* array_index = IndexAccessor(array_init, 3_i);
|
auto* array_index = IndexAccessor(array_init, 3_i);
|
||||||
auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
|
auto* pos = Var("pos", ty.i32(), ast::StorageClass::kNone, array_index);
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(pos),
|
Decl(pos),
|
||||||
},
|
},
|
||||||
|
@ -223,7 +223,7 @@ TEST_F(HlslSanitizerTest, PromoteStructInitializerToConstVar) {
|
||||||
auto* struct_access = MemberAccessor(struct_init, "b");
|
auto* struct_access = MemberAccessor(struct_init, "b");
|
||||||
auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
|
auto* pos = Var("pos", ty.vec3<f32>(), ast::StorageClass::kNone, struct_access);
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(pos),
|
Decl(pos),
|
||||||
},
|
},
|
||||||
|
@ -259,7 +259,7 @@ TEST_F(HlslSanitizerTest, InlinePtrLetsBasic) {
|
||||||
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
|
auto* p = Let("p", ty.pointer<i32>(ast::StorageClass::kFunction), AddressOf(v));
|
||||||
auto* x = Var("x", ty.i32(), ast::StorageClass::kNone, Deref(p));
|
auto* x = Var("x", ty.i32(), ast::StorageClass::kNone, Deref(p));
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(v),
|
Decl(v),
|
||||||
Decl(p),
|
Decl(p),
|
||||||
|
@ -298,7 +298,7 @@ TEST_F(HlslSanitizerTest, InlinePtrLetsComplexChain) {
|
||||||
AddressOf(IndexAccessor(Deref(mp), 2_i)));
|
AddressOf(IndexAccessor(Deref(mp), 2_i)));
|
||||||
auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
|
auto* v = Var("v", ty.vec4<f32>(), ast::StorageClass::kNone, Deref(vp));
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(a),
|
Decl(a),
|
||||||
Decl(ap),
|
Decl(ap),
|
||||||
|
|
|
@ -29,7 +29,7 @@ TEST_F(HlslGeneratorImplTest, InvalidProgram) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(HlslGeneratorImplTest, Generate) {
|
TEST_F(HlslGeneratorImplTest, Generate) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
Func("my_func", {}, ty.void_(), {});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,10 @@ namespace {
|
||||||
using MslGeneratorImplTest = TestHelper;
|
using MslGeneratorImplTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, Emit_Function) {
|
TEST_F(MslGeneratorImplTest, Emit_Function) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(),
|
Func("my_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
{});
|
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
@ -46,15 +45,15 @@ TEST_F(MslGeneratorImplTest, Emit_Function) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, Emit_Function_WithParams) {
|
TEST_F(MslGeneratorImplTest, Emit_Function_WithParams) {
|
||||||
ast::VariableList params;
|
Func("my_func",
|
||||||
params.push_back(Param("a", ty.f32()));
|
{
|
||||||
params.push_back(Param("b", ty.i32()));
|
Param("a", ty.f32()),
|
||||||
|
Param("b", ty.i32()),
|
||||||
Func("my_func", params, ty.void_(),
|
|
||||||
ast::StatementList{
|
|
||||||
Return(),
|
|
||||||
},
|
},
|
||||||
{});
|
ty.void_(),
|
||||||
|
{
|
||||||
|
Return(),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
@ -72,7 +71,7 @@ TEST_F(MslGeneratorImplTest, Emit_Function_WithParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, Emit_Attribute_EntryPoint_NoReturn_Void) {
|
TEST_F(MslGeneratorImplTest, Emit_Attribute_EntryPoint_NoReturn_Void) {
|
||||||
Func("main", ast::VariableList{}, ty.void_(), ast::StatementList{/* no explicit return */},
|
Func("main", {}, ty.void_(), {/* no explicit return */},
|
||||||
{Stage(ast::PipelineStage::kFragment)});
|
{Stage(ast::PipelineStage::kFragment)});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
@ -93,8 +92,16 @@ TEST_F(MslGeneratorImplTest, Emit_Attribute_EntryPoint_WithInOutVars) {
|
||||||
// return foo;
|
// return foo;
|
||||||
// }
|
// }
|
||||||
auto* foo_in = Param("foo", ty.f32(), {Location(0)});
|
auto* foo_in = Param("foo", ty.f32(), {Location(0)});
|
||||||
Func("frag_main", ast::VariableList{foo_in}, ty.f32(), {Return("foo")},
|
Func("frag_main", {foo_in}, ty.f32(),
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Location(1)});
|
{
|
||||||
|
Return("foo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Location(1),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -129,8 +136,16 @@ TEST_F(MslGeneratorImplTest, Emit_Attribute_EntryPoint_WithInOut_Builtins) {
|
||||||
// return coord.x;
|
// return coord.x;
|
||||||
// }
|
// }
|
||||||
auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
auto* coord_in = Param("coord", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)});
|
||||||
Func("frag_main", ast::VariableList{coord_in}, ty.f32(), {Return(MemberAccessor("coord", "x"))},
|
Func("frag_main", {coord_in}, ty.f32(),
|
||||||
{Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::Builtin::kFragDepth)});
|
{
|
||||||
|
Return(MemberAccessor("coord", "x")),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Builtin(ast::Builtin::kFragDepth),
|
||||||
|
});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -256,10 +271,10 @@ TEST_F(MslGeneratorImplTest, Emit_Attribute_EntryPoint_SharedStruct_HelperFuncti
|
||||||
"VertexOutput", {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})});
|
"VertexOutput", {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})});
|
||||||
|
|
||||||
Func("foo", {Param("x", ty.f32())}, ty.Of(vertex_output_struct),
|
Func("foo", {Param("x", ty.f32())}, ty.Of(vertex_output_struct),
|
||||||
{Return(Construct(ty.Of(vertex_output_struct),
|
{
|
||||||
Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f))))},
|
Return(Construct(ty.Of(vertex_output_struct),
|
||||||
{});
|
Construct(ty.vec4<f32>(), "x", "x", "x", Expr(1_f)))),
|
||||||
|
});
|
||||||
Func("vert_main1", {}, ty.Of(vertex_output_struct), {Return(Expr(Call("foo", Expr(0.5_f))))},
|
Func("vert_main1", {}, ty.Of(vertex_output_struct), {Return(Expr(Call("foo", Expr(0.5_f))))},
|
||||||
{Stage(ast::PipelineStage::kVertex)});
|
{Stage(ast::PipelineStage::kVertex)});
|
||||||
|
|
||||||
|
@ -328,8 +343,8 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_EntryPoint_With_RW_StorageBu
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
|
@ -370,8 +385,8 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_EntryPoint_With_RO_StorageBu
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("coord", "b"));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
|
@ -460,17 +475,19 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_Called_By_EntryPoint_With_RW
|
||||||
create<ast::GroupAttribute>(0),
|
create<ast::GroupAttribute>(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
ast::VariableList params;
|
Func("sub_func",
|
||||||
params.push_back(Param("param", ty.f32()));
|
{
|
||||||
|
Param("param", ty.f32()),
|
||||||
auto body = ast::StatementList{Return(MemberAccessor("coord", "b"))};
|
},
|
||||||
|
ty.f32(),
|
||||||
Func("sub_func", params, ty.f32(), body, {});
|
{
|
||||||
|
Return(MemberAccessor("coord", "b")),
|
||||||
|
});
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
|
@ -513,17 +530,19 @@ TEST_F(MslGeneratorImplTest, Emit_FunctionAttribute_Called_By_EntryPoint_With_RO
|
||||||
create<ast::GroupAttribute>(0),
|
create<ast::GroupAttribute>(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
ast::VariableList params;
|
Func("sub_func",
|
||||||
params.push_back(Param("param", ty.f32()));
|
{
|
||||||
|
Param("param", ty.f32()),
|
||||||
auto body = ast::StatementList{Return(MemberAccessor("coord", "b"))};
|
},
|
||||||
|
ty.f32(),
|
||||||
Func("sub_func", params, ty.f32(), body, {});
|
{
|
||||||
|
Return(MemberAccessor("coord", "b")),
|
||||||
|
});
|
||||||
|
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, Call("sub_func", 1_f));
|
||||||
|
|
||||||
Func("frag_main", ast::VariableList{}, ty.void_(),
|
Func("frag_main", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
|
@ -555,10 +574,11 @@ fragment void frag_main(const device Data* tint_symbol_1 [[buffer(0)]]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
|
TEST_F(MslGeneratorImplTest, Emit_Function_WithArrayParams) {
|
||||||
ast::VariableList params;
|
Func("my_func",
|
||||||
params.push_back(Param("a", ty.array<f32, 5>()));
|
{
|
||||||
|
Param("a", ty.array<f32, 5>()),
|
||||||
Func("my_func", params, ty.void_(),
|
},
|
||||||
|
ty.void_(),
|
||||||
{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
});
|
});
|
||||||
|
@ -636,8 +656,8 @@ TEST_F(MslGeneratorImplTest, Emit_Function_Multiple_EntryPoint_With_Same_ModuleV
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("a", ast::VariableList{}, ty.void_(),
|
Func("a", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
|
@ -650,7 +670,7 @@ TEST_F(MslGeneratorImplTest, Emit_Function_Multiple_EntryPoint_With_Same_ModuleV
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("b", ast::VariableList{}, ty.void_(), ast::StatementList{Decl(var), Return()},
|
Func("b", {}, ty.void_(), {Decl(var), Return()},
|
||||||
{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1_i),
|
WorkgroupSize(1_i),
|
||||||
|
|
|
@ -33,12 +33,12 @@ TEST_F(MslSanitizerTest, Call_ArrayLength) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -78,12 +78,12 @@ TEST_F(MslSanitizerTest, Call_ArrayLength_OtherMembersInStruct) {
|
||||||
create<ast::GroupAttribute>(2),
|
create<ast::GroupAttribute>(2),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
Call("arrayLength", AddressOf(MemberAccessor("b", "a"))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -125,13 +125,13 @@ TEST_F(MslSanitizerTest, Call_ArrayLength_ViaLets) {
|
||||||
auto* p = Let("p", nullptr, AddressOf("b"));
|
auto* p = Let("p", nullptr, AddressOf("b"));
|
||||||
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
|
auto* p2 = Let("p2", nullptr, AddressOf(MemberAccessor(Deref(p), "a")));
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(p),
|
Decl(p),
|
||||||
Decl(p2),
|
Decl(p2),
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone, Call("arrayLength", p2))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -174,13 +174,13 @@ TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniform) {
|
||||||
create<ast::GroupAttribute>(0),
|
create<ast::GroupAttribute>(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
|
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
|
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -226,13 +226,13 @@ TEST_F(MslSanitizerTest, Call_ArrayLength_ArrayLengthFromUniformMissingBinding)
|
||||||
create<ast::GroupAttribute>(0),
|
create<ast::GroupAttribute>(0),
|
||||||
});
|
});
|
||||||
|
|
||||||
Func("a_func", ast::VariableList{}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
Decl(Var("len", ty.u32(), ast::StorageClass::kNone,
|
||||||
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
|
Add(Call("arrayLength", AddressOf(MemberAccessor("b", "a"))),
|
||||||
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
|
Call("arrayLength", AddressOf(MemberAccessor("c", "a")))))),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -32,8 +32,8 @@ TEST_F(MslGeneratorImplTest, InvalidProgram) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, Generate) {
|
TEST_F(MslGeneratorImplTest, Generate) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{},
|
Func("my_func", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1_i),
|
WorkgroupSize(1_i),
|
||||||
});
|
});
|
||||||
|
@ -88,7 +88,7 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
TEST_F(MslGeneratorImplTest, HasInvariantAttribute_True) {
|
TEST_F(MslGeneratorImplTest, HasInvariantAttribute_True) {
|
||||||
auto* out = Structure(
|
auto* out = Structure(
|
||||||
"Out", {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition), Invariant()})});
|
"Out", {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition), Invariant()})});
|
||||||
Func("vert_main", ast::VariableList{}, ty.Of(out), {Return(Construct(ty.Of(out)))},
|
Func("vert_main", {}, ty.Of(out), {Return(Construct(ty.Of(out)))},
|
||||||
{Stage(ast::PipelineStage::kVertex)});
|
{Stage(ast::PipelineStage::kVertex)});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
@ -119,7 +119,7 @@ vertex Out vert_main() {
|
||||||
TEST_F(MslGeneratorImplTest, HasInvariantAttribute_False) {
|
TEST_F(MslGeneratorImplTest, HasInvariantAttribute_False) {
|
||||||
auto* out =
|
auto* out =
|
||||||
Structure("Out", {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})});
|
Structure("Out", {Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)})});
|
||||||
Func("vert_main", ast::VariableList{}, ty.Of(out), {Return(Construct(ty.Of(out)))},
|
Func("vert_main", {}, ty.Of(out), {Return(Construct(ty.Of(out)))},
|
||||||
{Stage(ast::PipelineStage::kVertex)});
|
{Stage(ast::PipelineStage::kVertex)});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
@ -142,7 +142,7 @@ vertex Out vert_main() {
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
|
TEST_F(MslGeneratorImplTest, WorkgroupMatrix) {
|
||||||
Global("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
|
Global("m", ty.mat2x2<f32>(), ast::StorageClass::kWorkgroup);
|
||||||
Func("comp_main", ast::VariableList{}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
|
Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
@ -179,7 +179,7 @@ kernel void comp_main(threadgroup tint_symbol_3* tint_symbol_2 [[threadgroup(0)]
|
||||||
|
|
||||||
TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
|
TEST_F(MslGeneratorImplTest, WorkgroupMatrixInArray) {
|
||||||
Global("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
|
Global("m", ty.array(ty.mat2x2<f32>(), 4_i), ast::StorageClass::kWorkgroup);
|
||||||
Func("comp_main", ast::VariableList{}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
|
Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("m")))},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
@ -228,7 +228,7 @@ TEST_F(MslGeneratorImplTest, WorkgroupMatrixInStruct) {
|
||||||
Member("s", ty.type_name("S1")),
|
Member("s", ty.type_name("S1")),
|
||||||
});
|
});
|
||||||
Global("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
|
Global("s", ty.type_name("S2"), ast::StorageClass::kWorkgroup);
|
||||||
Func("comp_main", ast::VariableList{}, ty.void_(), {Decl(Let("x", nullptr, Expr("s")))},
|
Func("comp_main", {}, ty.void_(), {Decl(Let("x", nullptr, Expr("s")))},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
@ -283,28 +283,28 @@ TEST_F(MslGeneratorImplTest, WorkgroupMatrix_Multiples) {
|
||||||
Global("m7", ty.mat4x2<f32>(), ast::StorageClass::kWorkgroup);
|
Global("m7", ty.mat4x2<f32>(), ast::StorageClass::kWorkgroup);
|
||||||
Global("m8", ty.mat4x3<f32>(), ast::StorageClass::kWorkgroup);
|
Global("m8", ty.mat4x3<f32>(), ast::StorageClass::kWorkgroup);
|
||||||
Global("m9", ty.mat4x4<f32>(), ast::StorageClass::kWorkgroup);
|
Global("m9", ty.mat4x4<f32>(), ast::StorageClass::kWorkgroup);
|
||||||
Func("main1", ast::VariableList{}, ty.void_(),
|
Func("main1", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Let("a1", nullptr, Expr("m1"))),
|
Decl(Let("a1", nullptr, Expr("m1"))),
|
||||||
Decl(Let("a2", nullptr, Expr("m2"))),
|
Decl(Let("a2", nullptr, Expr("m2"))),
|
||||||
Decl(Let("a3", nullptr, Expr("m3"))),
|
Decl(Let("a3", nullptr, Expr("m3"))),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
Func("main2", ast::VariableList{}, ty.void_(),
|
Func("main2", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Let("a1", nullptr, Expr("m4"))),
|
Decl(Let("a1", nullptr, Expr("m4"))),
|
||||||
Decl(Let("a2", nullptr, Expr("m5"))),
|
Decl(Let("a2", nullptr, Expr("m5"))),
|
||||||
Decl(Let("a3", nullptr, Expr("m6"))),
|
Decl(Let("a3", nullptr, Expr("m6"))),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
Func("main3", ast::VariableList{}, ty.void_(),
|
Func("main3", {}, ty.void_(),
|
||||||
{
|
{
|
||||||
Decl(Let("a1", nullptr, Expr("m7"))),
|
Decl(Let("a1", nullptr, Expr("m7"))),
|
||||||
Decl(Let("a2", nullptr, Expr("m8"))),
|
Decl(Let("a2", nullptr, Expr("m8"))),
|
||||||
Decl(Let("a3", nullptr, Expr("m9"))),
|
Decl(Let("a3", nullptr, Expr("m9"))),
|
||||||
},
|
},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
Func("main4_no_usages", ast::VariableList{}, ty.void_(), {},
|
Func("main4_no_usages", {}, ty.void_(), {},
|
||||||
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
|
|
||||||
GeneratorImpl& gen = SanitizeAndBuild();
|
GeneratorImpl& gen = SanitizeAndBuild();
|
||||||
|
|
|
@ -25,11 +25,12 @@ namespace {
|
||||||
using BuilderTest = TestHelper;
|
using BuilderTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuilderTest, Expression_Call) {
|
TEST_F(BuilderTest, Expression_Call) {
|
||||||
ast::VariableList func_params;
|
auto* a_func = Func("a_func",
|
||||||
func_params.push_back(Param("a", ty.f32()));
|
{
|
||||||
func_params.push_back(Param("b", ty.f32()));
|
Param("a", ty.f32()),
|
||||||
|
Param("b", ty.f32()),
|
||||||
auto* a_func = Func("a_func", func_params, ty.f32(), {Return(Add("a", "b"))});
|
},
|
||||||
|
ty.f32(), {Return(Add("a", "b"))});
|
||||||
auto* func = Func("main", {}, ty.void_(), {Assign(Phony(), Call("a_func", 1_f, 1_f))});
|
auto* func = Func("main", {}, ty.void_(), {Assign(Phony(), Call("a_func", 1_f, 1_f))});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
@ -62,11 +63,12 @@ OpFunctionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, Statement_Call) {
|
TEST_F(BuilderTest, Statement_Call) {
|
||||||
ast::VariableList func_params;
|
auto* a_func = Func("a_func",
|
||||||
func_params.push_back(Param("a", ty.f32()));
|
{
|
||||||
func_params.push_back(Param("b", ty.f32()));
|
Param("a", ty.f32()),
|
||||||
|
Param("b", ty.f32()),
|
||||||
auto* a_func = Func("a_func", func_params, ty.f32(), {Return(Add("a", "b"))});
|
},
|
||||||
|
ty.f32(), {Return(Add("a", "b"))});
|
||||||
|
|
||||||
auto* func = Func("main", {}, ty.void_(), {CallStmt(Call("a_func", 1_f, 1_f))});
|
auto* func = Func("main", {}, ty.void_(), {CallStmt(Call("a_func", 1_f, 1_f))});
|
||||||
|
|
||||||
|
|
|
@ -46,9 +46,8 @@ TEST_F(BuilderTest, EntryPoint_Parameters) {
|
||||||
auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
|
auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
|
||||||
auto* mul = Mul(Expr(MemberAccessor("coord", "x")), Expr("loc1"));
|
auto* mul = Mul(Expr(MemberAccessor("coord", "x")), Expr("loc1"));
|
||||||
auto* col = Var("col", ty.f32(), ast::StorageClass::kNone, mul);
|
auto* col = Var("col", ty.f32(), ast::StorageClass::kNone, mul);
|
||||||
Func("frag_main", ast::VariableList{coord, loc1}, ty.void_(),
|
Func("frag_main", {coord, loc1}, ty.void_(), {WrapInStatement(col)},
|
||||||
ast::StatementList{WrapInStatement(col)},
|
{
|
||||||
ast::AttributeList{
|
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -116,15 +115,15 @@ TEST_F(BuilderTest, EntryPoint_ReturnValue) {
|
||||||
auto* loc_in = Param("loc_in", ty.u32(), {Location(0), Flat()});
|
auto* loc_in = Param("loc_in", ty.u32(), {Location(0), Flat()});
|
||||||
auto* cond =
|
auto* cond =
|
||||||
create<ast::BinaryExpression>(ast::BinaryOp::kGreaterThan, Expr("loc_in"), Expr(10_u));
|
create<ast::BinaryExpression>(ast::BinaryOp::kGreaterThan, Expr("loc_in"), Expr(10_u));
|
||||||
Func("frag_main", ast::VariableList{loc_in}, ty.f32(),
|
Func("frag_main", {loc_in}, ty.f32(),
|
||||||
ast::StatementList{
|
{
|
||||||
If(cond, Block(Return(0.5_f))),
|
If(cond, Block(Return(0.5_f))),
|
||||||
Return(1_f),
|
Return(1_f),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Location(0)});
|
{Location(0)});
|
||||||
|
|
||||||
spirv::Builder& b = SanitizeAndBuild();
|
spirv::Builder& b = SanitizeAndBuild();
|
||||||
|
|
||||||
|
@ -198,20 +197,21 @@ TEST_F(BuilderTest, EntryPoint_SharedStruct) {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
auto* interface = Structure(
|
auto* interface = Structure(
|
||||||
"Interface",
|
"Interface", {
|
||||||
{
|
Member("value", ty.f32(), {Location(1u)}),
|
||||||
Member("value", ty.f32(), ast::AttributeList{Location(1u)}),
|
Member("pos", ty.vec4<f32>(), {Builtin(ast::Builtin::kPosition)}),
|
||||||
Member("pos", ty.vec4<f32>(), ast::AttributeList{Builtin(ast::Builtin::kPosition)}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* vert_retval = Construct(ty.Of(interface), 42_f, Construct(ty.vec4<f32>()));
|
auto* vert_retval = Construct(ty.Of(interface), 42_f, Construct(ty.vec4<f32>()));
|
||||||
Func("vert_main", ast::VariableList{}, ty.Of(interface), {Return(vert_retval)},
|
Func("vert_main", {}, ty.Of(interface), {Return(vert_retval)},
|
||||||
{Stage(ast::PipelineStage::kVertex)});
|
{Stage(ast::PipelineStage::kVertex)});
|
||||||
|
|
||||||
auto* frag_inputs = Param("inputs", ty.Of(interface));
|
auto* frag_inputs = Param("inputs", ty.Of(interface));
|
||||||
Func("frag_main", ast::VariableList{frag_inputs}, ty.f32(),
|
Func("frag_main", {frag_inputs}, ty.f32(),
|
||||||
{Return(MemberAccessor(Expr("inputs"), "value"))}, {Stage(ast::PipelineStage::kFragment)},
|
{
|
||||||
{Builtin(ast::Builtin::kFragDepth)});
|
Return(MemberAccessor(Expr("inputs"), "value")),
|
||||||
|
},
|
||||||
|
{Stage(ast::PipelineStage::kFragment)}, {Builtin(ast::Builtin::kFragDepth)});
|
||||||
|
|
||||||
spirv::Builder& b = SanitizeAndBuild();
|
spirv::Builder& b = SanitizeAndBuild();
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace {
|
||||||
using BuilderTest = TestHelper;
|
using BuilderTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuilderTest, Attribute_Stage) {
|
TEST_F(BuilderTest, Attribute_Stage) {
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ INSTANTIATE_TEST_SUITE_P(
|
||||||
FunctionStageData{ast::PipelineStage::kCompute, SpvExecutionModelGLCompute}));
|
FunctionStageData{ast::PipelineStage::kCompute, SpvExecutionModelGLCompute}));
|
||||||
|
|
||||||
TEST_F(BuilderTest, Decoration_ExecutionMode_Fragment_OriginUpperLeft) {
|
TEST_F(BuilderTest, Decoration_ExecutionMode_Fragment_OriginUpperLeft) {
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -105,8 +105,8 @@ TEST_F(BuilderTest, Decoration_ExecutionMode_Fragment_OriginUpperLeft) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Default) {
|
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Default) {
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func =
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
Func("main", {}, ty.void_(), {}, {Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -117,8 +117,8 @@ TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Default) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Literals) {
|
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Literals) {
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
WorkgroupSize(2_i, 4_i, 6_i),
|
WorkgroupSize(2_i, 4_i, 6_i),
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
});
|
});
|
||||||
|
@ -135,8 +135,8 @@ TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Const) {
|
||||||
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
|
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
|
||||||
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
|
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
|
||||||
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
|
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
WorkgroupSize("width", "height", "depth"),
|
WorkgroupSize("width", "height", "depth"),
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
});
|
});
|
||||||
|
@ -153,8 +153,8 @@ TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_OverridableConst) {
|
||||||
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
||||||
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
|
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
|
||||||
Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
|
Override("depth", ty.i32(), Construct(ty.i32(), 4_i), {Id(9u)});
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
WorkgroupSize("width", "height", "depth"),
|
WorkgroupSize("width", "height", "depth"),
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
});
|
});
|
||||||
|
@ -182,8 +182,8 @@ OpDecorate %3 BuiltIn WorkgroupSize
|
||||||
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
|
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
|
||||||
Override("height", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
Override("height", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
|
||||||
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3_i));
|
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3_i));
|
||||||
auto* func = Func("main", {}, ty.void_(), ast::StatementList{},
|
auto* func = Func("main", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
WorkgroupSize(4_i, "height", "depth"),
|
WorkgroupSize(4_i, "height", "depth"),
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
});
|
});
|
||||||
|
@ -207,13 +207,13 @@ OpDecorate %3 BuiltIn WorkgroupSize
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, Decoration_ExecutionMode_MultipleFragment) {
|
TEST_F(BuilderTest, Decoration_ExecutionMode_MultipleFragment) {
|
||||||
auto* func1 = Func("main1", {}, ty.void_(), ast::StatementList{},
|
auto* func1 = Func("main1", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
auto* func2 = Func("main2", {}, ty.void_(), ast::StatementList{},
|
auto* func2 = Func("main2", {}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -242,12 +242,14 @@ OpFunctionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, Decoration_ExecutionMode_FragDepth) {
|
TEST_F(BuilderTest, Decoration_ExecutionMode_FragDepth) {
|
||||||
Func("main", ast::VariableList{}, ty.f32(),
|
Func("main", {}, ty.f32(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(Expr(1_f)),
|
Return(Expr(1_f)),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kFragment)},
|
{
|
||||||
ast::AttributeList{
|
Stage(ast::PipelineStage::kFragment),
|
||||||
|
},
|
||||||
|
{
|
||||||
Builtin(ast::Builtin::kFragDepth),
|
Builtin(ast::Builtin::kFragDepth),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace {
|
||||||
using BuilderTest = TestHelper;
|
using BuilderTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(BuilderTest, Function_Empty) {
|
TEST_F(BuilderTest, Function_Empty) {
|
||||||
Func("a_func", {}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
Func("a_func", {}, ty.void_(), {});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -42,10 +42,9 @@ OpFunctionEnd
|
||||||
|
|
||||||
TEST_F(BuilderTest, Function_Terminator_Return) {
|
TEST_F(BuilderTest, Function_Terminator_Return) {
|
||||||
Func("a_func", {}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ OpFunctionEnd
|
||||||
TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
|
TEST_F(BuilderTest, Function_Terminator_ReturnValue) {
|
||||||
Global("a", ty.f32(), ast::StorageClass::kPrivate);
|
Global("a", ty.f32(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
Func("a_func", {}, ty.f32(), ast::StatementList{Return("a")}, ast::AttributeList{});
|
Func("a_func", {}, ty.f32(), {Return("a")}, {});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -90,10 +89,9 @@ OpFunctionEnd
|
||||||
|
|
||||||
TEST_F(BuilderTest, Function_Terminator_Discard) {
|
TEST_F(BuilderTest, Function_Terminator_Discard) {
|
||||||
Func("a_func", {}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
create<ast::DiscardStatement>(),
|
create<ast::DiscardStatement>(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -110,9 +108,12 @@ OpFunctionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, Function_WithParams) {
|
TEST_F(BuilderTest, Function_WithParams) {
|
||||||
ast::VariableList params = {Param("a", ty.f32()), Param("b", ty.i32())};
|
Func("a_func",
|
||||||
|
{
|
||||||
Func("a_func", params, ty.f32(), ast::StatementList{Return("a")}, ast::AttributeList{});
|
Param("a", ty.f32()),
|
||||||
|
Param("b", ty.i32()),
|
||||||
|
},
|
||||||
|
ty.f32(), {Return("a")}, {});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -135,10 +136,9 @@ OpFunctionEnd
|
||||||
|
|
||||||
TEST_F(BuilderTest, Function_WithBody) {
|
TEST_F(BuilderTest, Function_WithBody) {
|
||||||
Func("a_func", {}, ty.void_(),
|
Func("a_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ OpFunctionEnd
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, FunctionType) {
|
TEST_F(BuilderTest, FunctionType) {
|
||||||
Func("a_func", {}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
Func("a_func", {}, ty.void_(), {}, {});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -167,8 +167,8 @@ TEST_F(BuilderTest, FunctionType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BuilderTest, FunctionType_DeDuplicate) {
|
TEST_F(BuilderTest, FunctionType_DeDuplicate) {
|
||||||
auto* func1 = Func("a_func", {}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
auto* func1 = Func("a_func", {}, ty.void_(), {}, {});
|
||||||
auto* func2 = Func("b_func", {}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
auto* func2 = Func("b_func", {}, ty.void_(), {}, {});
|
||||||
|
|
||||||
spirv::Builder& b = Build();
|
spirv::Builder& b = Build();
|
||||||
|
|
||||||
|
@ -207,23 +207,23 @@ TEST_F(BuilderTest, Emit_Multiple_EntryPoint_With_Same_ModuleVar) {
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("a", ast::VariableList{}, ty.void_(),
|
Func("a", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("b", ast::VariableList{}, ty.void_(),
|
Func("b", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::AttributeList{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
{Stage(ast::PipelineStage::kCompute), WorkgroupSize(1_i)});
|
||||||
}
|
}
|
||||||
|
|
||||||
spirv::Builder& b = SanitizeAndBuild();
|
spirv::Builder& b = SanitizeAndBuild();
|
||||||
|
|
|
@ -25,11 +25,10 @@ namespace {
|
||||||
using WgslGeneratorImplTest = TestHelper;
|
using WgslGeneratorImplTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_Function) {
|
TEST_F(WgslGeneratorImplTest, Emit_Function) {
|
||||||
auto* func = Func("my_func", ast::VariableList{}, ty.void_(),
|
auto* func = Func("my_func", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
@ -43,12 +42,10 @@ TEST_F(WgslGeneratorImplTest, Emit_Function) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
|
TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
|
||||||
auto* func =
|
auto* func = Func("my_func", {Param("a", ty.f32()), Param("b", ty.i32())}, ty.void_(),
|
||||||
Func("my_func", ast::VariableList{Param("a", ty.f32()), Param("b", ty.i32())}, ty.void_(),
|
{
|
||||||
ast::StatementList{
|
|
||||||
Return(),
|
Return(),
|
||||||
},
|
});
|
||||||
ast::AttributeList{});
|
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
@ -62,8 +59,8 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_WithParams) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize) {
|
TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize) {
|
||||||
auto* func = Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{Return()},
|
auto* func = Func("my_func", {}, ty.void_(), {Return()},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(2_i, 4_i, 6_i),
|
WorkgroupSize(2_i, 4_i, 6_i),
|
||||||
});
|
});
|
||||||
|
@ -82,8 +79,8 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize) {
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize_WithIdent) {
|
TEST_F(WgslGeneratorImplTest, Emit_Function_WithAttribute_WorkgroupSize_WithIdent) {
|
||||||
GlobalConst("height", ty.i32(), Expr(2_i));
|
GlobalConst("height", ty.i32(), Expr(2_i));
|
||||||
auto* func = Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{Return()},
|
auto* func = Func("my_func", {}, ty.void_(), {Return()},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(2_i, "height"),
|
WorkgroupSize(2_i, "height"),
|
||||||
});
|
});
|
||||||
|
@ -104,8 +101,8 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_Parameters) {
|
||||||
auto* vec4 = ty.vec4<f32>();
|
auto* vec4 = ty.vec4<f32>();
|
||||||
auto* coord = Param("coord", vec4, {Builtin(ast::Builtin::kPosition)});
|
auto* coord = Param("coord", vec4, {Builtin(ast::Builtin::kPosition)});
|
||||||
auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
|
auto* loc1 = Param("loc1", ty.f32(), {Location(1u)});
|
||||||
auto* func = Func("frag_main", ast::VariableList{coord, loc1}, ty.void_(), ast::StatementList{},
|
auto* func = Func("frag_main", {coord, loc1}, ty.void_(), {},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -121,14 +118,14 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_Parameters) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_ReturnValue) {
|
TEST_F(WgslGeneratorImplTest, Emit_Function_EntryPoint_ReturnValue) {
|
||||||
auto* func = Func("frag_main", ast::VariableList{}, ty.f32(),
|
auto* func = Func("frag_main", {}, ty.f32(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return(1_f),
|
Return(1_f),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kFragment),
|
Stage(ast::PipelineStage::kFragment),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Location(1u),
|
Location(1u),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -172,12 +169,12 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_Multiple_EntryPoint_With_Same_Module
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("a", ast::VariableList{}, ty.void_(),
|
Func("a", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1_i),
|
WorkgroupSize(1_i),
|
||||||
});
|
});
|
||||||
|
@ -186,12 +183,12 @@ TEST_F(WgslGeneratorImplTest, Emit_Function_Multiple_EntryPoint_With_Same_Module
|
||||||
{
|
{
|
||||||
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
auto* var = Var("v", ty.f32(), ast::StorageClass::kNone, MemberAccessor("data", "d"));
|
||||||
|
|
||||||
Func("b", ast::VariableList{}, ty.void_(),
|
Func("b", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(var),
|
Decl(var),
|
||||||
Return(),
|
Return(),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1_i),
|
WorkgroupSize(1_i),
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,23 +49,23 @@ TEST_F(WgslGeneratorImplTest, Emit_GlobalsInterleaved) {
|
||||||
|
|
||||||
auto* s0 = Structure("S0", {Member("a", ty.i32())});
|
auto* s0 = Structure("S0", {Member("a", ty.i32())});
|
||||||
|
|
||||||
Func("func", ast::VariableList{}, ty.f32(),
|
Func("func", {}, ty.f32(),
|
||||||
ast::StatementList{
|
{
|
||||||
Return("a0"),
|
Return("a0"),
|
||||||
},
|
},
|
||||||
ast::AttributeList{});
|
{});
|
||||||
|
|
||||||
Global("a1", ty.f32(), ast::StorageClass::kPrivate);
|
Global("a1", ty.f32(), ast::StorageClass::kPrivate);
|
||||||
|
|
||||||
auto* s1 = Structure("S1", {Member("a", ty.i32())});
|
auto* s1 = Structure("S1", {Member("a", ty.i32())});
|
||||||
|
|
||||||
Func("main", ast::VariableList{}, ty.void_(),
|
Func("main", {}, ty.void_(),
|
||||||
ast::StatementList{
|
{
|
||||||
Decl(Var("s0", ty.Of(s0))),
|
Decl(Var("s0", ty.Of(s0))),
|
||||||
Decl(Var("s1", ty.Of(s1))),
|
Decl(Var("s1", ty.Of(s1))),
|
||||||
Assign("a1", Call("func")),
|
Assign("a1", Call("func")),
|
||||||
},
|
},
|
||||||
ast::AttributeList{
|
{
|
||||||
Stage(ast::PipelineStage::kCompute),
|
Stage(ast::PipelineStage::kCompute),
|
||||||
WorkgroupSize(1_i),
|
WorkgroupSize(1_i),
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace {
|
||||||
using WgslGeneratorImplTest = TestHelper;
|
using WgslGeneratorImplTest = TestHelper;
|
||||||
|
|
||||||
TEST_F(WgslGeneratorImplTest, Generate) {
|
TEST_F(WgslGeneratorImplTest, Generate) {
|
||||||
Func("my_func", ast::VariableList{}, ty.void_(), ast::StatementList{}, ast::AttributeList{});
|
Func("my_func", {}, ty.void_(), {}, {});
|
||||||
|
|
||||||
GeneratorImpl& gen = Build();
|
GeneratorImpl& gen = Build();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue