tint/writer: Handle and emit 'const' variables

Bug: tint:1580
Change-Id: Ib3a5ff5c567e19eca1ba8fb3c2f7e83dee68e2a0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/94686
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2022-06-28 12:44:16 +00:00 committed by Dawn LUCI CQ
parent b3b324c0d1
commit 19576e9015
34 changed files with 2946 additions and 335 deletions

View File

@ -1772,15 +1772,10 @@ bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* exp
// TODO(crbug.com/tint/1580): Once 'const' is implemented, 'let' will no longer resolve
// to a shader-creation time constant value, and this can be removed.
if (auto constant = sem->ConstantValue()) {
// We do not want to inline array constants, as this will undo the work of
// PromoteInitializersToLet, which ensures that arrays are declarated in 'let's
// before their usage.
if (!constant.Type()->Is<sem::Array>()) {
return EmitConstant(out, constant);
}
}
}
}
return Switch(
expr,
[&](const ast::IndexAccessorExpression* a) { //
@ -1938,6 +1933,9 @@ bool GeneratorImpl::EmitGlobalVariable(const ast::Variable* global) {
},
[&](const ast::Let* let) { return EmitProgramConstVariable(let); },
[&](const ast::Override* override) { return EmitOverride(override); },
[&](const ast::Const*) {
return true; // Constants are embedded at their use
},
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled global variable type " << global->TypeInfo().name;
@ -2252,10 +2250,7 @@ bool GeneratorImpl::EmitConstantRange(std::ostream& out,
ScopedParen sp(out);
if (constant.AllEqual(start, end)) {
if (!EmitConstantRange(out, constant, v->type(), start, start + 1)) {
return false;
}
return true;
return EmitConstantRange(out, constant, v->type(), start, start + 1);
}
for (size_t i = start; i < end; i++) {
@ -2287,6 +2282,28 @@ bool GeneratorImpl::EmitConstantRange(std::ostream& out,
}
return true;
},
[&](const sem::Array* a) {
if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
ScopedParen sp(out);
auto* el_ty = a->ElemType();
uint32_t step = 0;
sem::Type::DeepestElementOf(el_ty, &step);
for (size_t i = start; i < end; i += step) {
if (i > start) {
out << ", ";
}
if (!EmitConstantRange(out, constant, el_ty, i, i + step)) {
return false;
}
}
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
@ -2655,6 +2672,9 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
[&](const ast::Const*) {
return true; // Constants are embedded at their use
},
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown variable type: " << v->variable->TypeInfo().name;

View File

@ -189,8 +189,7 @@ TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array_Empty) {
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_THAT(gen.result(), HasSubstr("vec3[3](vec3(0.0f, 0.0f, 0.0f), vec3(0.0f, 0.0f, 0.0f),"
" vec3(0.0f, 0.0f, 0.0f))"));
EXPECT_THAT(gen.result(), HasSubstr("vec3[3](vec3(0.0f), vec3(0.0f), vec3(0.0f))"));
}
TEST_F(GlslGeneratorImplTest_Constructor, EmitConstructor_Type_Struct) {

View File

@ -805,7 +805,7 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Let) {
GlobalLet("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalLet("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalLet("depth", ty.i32(), Construct(ty.i32(), 4_i));
@ -830,6 +830,28 @@ void main() {
)");
}
TEST_F(GlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
Func("main", {}, ty.void_(), {},
{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
layout(local_size_x = 2, local_size_y = 3, local_size_z = 4) in;
void main() {
return;
}
)");
}
TEST_F(GlslGeneratorImplTest_Function,
Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});

View File

@ -22,7 +22,7 @@ namespace {
using GlslGeneratorImplTest_ModuleConstant = TestHelper;
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalLet) {
auto* var = Let("pos", ty.array<f32, 3>(), array<f32, 3>(1_f, 2_f, 3_f));
WrapInFunction(Decl(var));
@ -32,7 +32,216 @@ TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
EXPECT_EQ(gen.result(), "const float pos[3] = float[3](1.0f, 2.0f, 3.0f);\n");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AInt) {
auto* var = GlobalConst("G", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
int l = 1;
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AFloat) {
auto* var = GlobalConst("G", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
float l = 1.0f;
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_i32) {
auto* var = GlobalConst("G", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
int l = 1;
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_u32) {
auto* var = GlobalConst("G", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
uint l = 1u;
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) {
auto* var = GlobalConst("G", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
float l = 1.0f;
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
ivec3 l = ivec3(1, 2, 3);
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
vec3 l = vec3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) {
auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
vec3 l = vec3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) {
auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
float l[3] = float[3](1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_vec2_bool) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
bvec2 l[3] = bvec2[3](bvec2(true, false), bvec2(false, true), bvec2(true));
}
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(23),
@ -48,7 +257,7 @@ const float pos = WGSL_SPEC_CONSTANT_23;
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override_NoConstructor) {
auto* var = Override("pos", ty.f32(), nullptr,
ast::AttributeList{
Id(23),
@ -64,7 +273,7 @@ const float pos = WGSL_SPEC_CONSTANT_23;
)");
}
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoId) {
TEST_F(GlslGeneratorImplTest_ModuleConstant, Emit_Override_NoId) {
auto* a = Override("a", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(0),

View File

@ -16,6 +16,8 @@
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/writer/glsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT
namespace tint::writer::glsl {
namespace {
@ -36,7 +38,7 @@ TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Let) {
auto* var = Let("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
@ -49,6 +51,228 @@ TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
auto* var = Const("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
GeneratorImpl& gen = Build();
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), ""); // Not a mistake - 'const' is inlined
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
int l = 1;
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
float l = 1.0f;
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
int l = 1;
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
uint l = 1u;
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
float l = 1.0f;
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
ivec3 l = ivec3(1, 2, 3);
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
vec3 l = vec3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
vec3 l = vec3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
mat2x3 l = mat2x3(vec3(1.0f, 2.0f, 3.0f), vec3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
float l[3] = float[3](1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
auto* C = Const("C", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#version 310 es
void f() {
bvec2 l[3] = bvec2[3](bvec2(true, false), bvec2(false, true), bvec2(true));
}
)");
}
TEST_F(GlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
auto* var = Var("a", ty.array<f32, 5>());

View File

@ -2617,15 +2617,10 @@ bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* exp
// TODO(crbug.com/tint/1580): Once 'const' is implemented, 'let' will no longer resolve
// to a shader-creation time constant value, and this can be removed.
if (auto constant = sem->ConstantValue()) {
// We do not want to inline array constants, as this will undo the work of
// PromoteInitializersToLet, which ensures that arrays are declarated in 'let's
// before their usage.
if (!constant.Type()->Is<sem::Array>()) {
return EmitConstant(out, constant);
}
}
}
}
return Switch(
expr,
[&](const ast::IndexAccessorExpression* a) { //
@ -2856,6 +2851,9 @@ bool GeneratorImpl::EmitGlobalVariable(const ast::Variable* global) {
},
[&](const ast::Let* let) { return EmitProgramConstVariable(let); },
[&](const ast::Override* override) { return EmitOverride(override); },
[&](const ast::Const*) {
return true; // Constants are embedded at their use
},
[&](Default) {
TINT_ICE(Writer, diagnostics_)
<< "unhandled global variable type " << global->TypeInfo().name;
@ -3174,8 +3172,7 @@ bool GeneratorImpl::EmitConstantRange(std::ostream& out,
return true;
},
[&](const sem::Matrix* m) {
if (!EmitType(out, constant.Type(), ast::StorageClass::kNone, ast::Access::kUndefined,
"")) {
if (!EmitType(out, m, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
@ -3193,6 +3190,34 @@ bool GeneratorImpl::EmitConstantRange(std::ostream& out,
}
return true;
},
[&](const sem::Array* a) {
if (constant.AllZero(start, end)) {
out << "(";
if (!EmitType(out, a, ast::StorageClass::kNone, ast::Access::kUndefined, "")) {
return false;
}
out << ")0";
return true;
}
out << "{";
TINT_DEFER(out << "}");
auto* el_ty = a->ElemType();
uint32_t step = 0;
sem::Type::DeepestElementOf(el_ty, &step);
for (size_t i = start; i < end; i += step) {
if (i > start) {
out << ", ";
}
if (!EmitConstantRange(out, constant, el_ty, i, i + step)) {
return false;
}
}
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
@ -3571,6 +3596,9 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
[&](const ast::Const*) {
return true; // Constants are embedded at their use
},
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown variable type: " << v->variable->TypeInfo().name;

View File

@ -41,7 +41,7 @@ TEST_F(HlslGeneratorImplTest_Assign, Emit_Assign) {
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_ConstantIndex) {
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_LetIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.vec3<f32>())),
@ -63,6 +63,27 @@ TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_ConstantIndex) {
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_ConstIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.vec3<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Const("index", ty.u32(), Expr(0_u))),
Assign(IndexAccessor("lhs", "index"), "rhs"),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(),
R"(void fn() {
float3 lhs = float3(0.0f, 0.0f, 0.0f);
float rhs = 0.0f;
lhs[0u] = rhs;
}
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Vector_Assign_DynamicIndex) {
Func("fn", {}, ty.void_(),
{
@ -89,7 +110,7 @@ void fn() {
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_ConstantIndex) {
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_LetIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.mat4x2<f32>())),
@ -111,6 +132,27 @@ TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_ConstantIndex) {
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_ConstIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.vec2<f32>())),
Decl(Const("index", ty.u32(), Expr(0_u))),
Assign(IndexAccessor("lhs", "index"), "rhs"),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(),
R"(void fn() {
float4x2 lhs = float4x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
float2 rhs = float2(0.0f, 0.0f);
lhs[0u] = rhs;
}
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Vector_DynamicIndex) {
Func("fn", {}, ty.void_(),
{
@ -142,7 +184,7 @@ void fn() {
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_ConstantIndex) {
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_LetIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.mat4x2<f32>())),
@ -164,6 +206,27 @@ TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_ConstantIndex) {
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_ConstIndex) {
Func("fn", {}, ty.void_(),
{
Decl(Var("lhs", ty.mat4x2<f32>())),
Decl(Var("rhs", ty.f32())),
Decl(Const("index", ty.u32(), Expr(0_u))),
Assign(IndexAccessor(IndexAccessor("lhs", "index"), "index"), "rhs"),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate());
EXPECT_EQ(gen.result(),
R"(void fn() {
float4x2 lhs = float4x2(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
float rhs = 0.0f;
lhs[0u][0u] = rhs;
}
)");
}
TEST_F(HlslGeneratorImplTest_Assign, Emit_Matrix_Assign_Scalar_DynamicIndex) {
Func("fn", {}, ty.void_(),
{

View File

@ -705,7 +705,7 @@ void main() {
)");
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Let) {
GlobalLet("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalLet("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalLet("depth", ty.i32(), Construct(ty.i32(), 4_i));
@ -729,6 +729,26 @@ void main() {
)");
}
TEST_F(HlslGeneratorImplTest_Function, Emit_Attribute_EntryPoint_Compute_WithWorkgroup_Const) {
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
Func("main", {}, ty.void_(), {},
{
Stage(ast::PipelineStage::kCompute),
WorkgroupSize("width", "height", "depth"),
});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"([numthreads(2, 3, 4)]
void main() {
return;
}
)");
}
TEST_F(HlslGeneratorImplTest_Function,
Emit_Attribute_EntryPoint_Compute_WithWorkgroup_OverridableConst) {
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});

View File

@ -22,7 +22,7 @@ namespace {
using HlslGeneratorImplTest_ModuleConstant = TestHelper;
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalLet) {
auto* var = Let("pos", ty.array<f32, 3>(), array<f32, 3>(1_f, 2_f, 3_f));
WrapInFunction(Decl(var));
@ -32,7 +32,180 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_ModuleConstant) {
EXPECT_EQ(gen.result(), "static const float pos[3] = {1.0f, 2.0f, 3.0f};\n");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant) {
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AInt) {
auto* var = GlobalConst("G", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const int l = 1;
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_AFloat) {
auto* var = GlobalConst("G", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float l = 1.0f;
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_i32) {
auto* var = GlobalConst("G", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const int l = 1;
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_u32) {
auto* var = GlobalConst("G", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const uint l = 1u;
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) {
auto* var = GlobalConst("G", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float l = 1.0f;
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AInt) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const int3 l = int3(1, 2, 3);
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_AFloat) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float3 l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) {
auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float3 l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_AFloat) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) {
auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) {
auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float l[3] = {1.0f, 2.0f, 3.0f};
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_vec2_bool) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const bool2 l[3] = {bool2(true, false), bool2(false, true), (true).xx};
}
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(23),
@ -48,7 +221,7 @@ static const float pos = WGSL_SPEC_CONSTANT_23;
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoConstructor) {
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override_NoConstructor) {
auto* var = Override("pos", ty.f32(), nullptr,
ast::AttributeList{
Id(23),
@ -64,7 +237,7 @@ static const float pos = WGSL_SPEC_CONSTANT_23;
)");
}
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_SpecConstant_NoId) {
TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_Override_NoId) {
auto* a = Override("a", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(0),

View File

@ -16,6 +16,8 @@
#include "src/tint/ast/variable_decl_statement.h"
#include "src/tint/writer/hlsl/test_helper.h"
using namespace tint::number_suffixes; // NOLINT
namespace tint::writer::hlsl {
namespace {
@ -36,7 +38,7 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement) {
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Let) {
auto* var = Let("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
@ -49,6 +51,192 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
EXPECT_EQ(gen.result(), " const float a = 0.0f;\n");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const) {
auto* var = Const("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
GeneratorImpl& gen = Build();
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), ""); // Not a mistake - 'const' is inlined
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const int l = 1;
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float l = 1.0f;
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const int l = 1;
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const uint l = 1u;
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float l = 1.0f;
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const int3 l = int3(1, 2, 3);
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float3 l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float3 l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float2x3 l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const float l[3] = {1.0f, 2.0f, 3.0f};
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
auto* C = Const("C", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(void f() {
const bool2 l[3] = {bool2(true, false), bool2(false, true), (true).xx};
}
)");
}
TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Array) {
auto* var = Var("a", ty.array<f32, 5>());

View File

@ -255,6 +255,9 @@ bool GeneratorImpl::Generate() {
TINT_DEFER(line());
return EmitProgramConstVariable(let);
},
[&](const ast::Const*) {
return true; // Constants are embedded at their use
},
[&](const ast::Override* override) {
TINT_DEFER(line());
return EmitOverride(override);
@ -1660,6 +1663,34 @@ bool GeneratorImpl::EmitConstantRange(std::ostream& out,
}
return true;
},
[&](const sem::Array* a) {
if (!EmitType(out, a, "")) {
return false;
}
if (constant.AllZero(start, end)) {
out << "{}";
return true;
}
out << "{";
TINT_DEFER(out << "}");
auto* el_ty = a->ElemType();
uint32_t step = 0;
sem::Type::DeepestElementOf(el_ty, &step);
for (size_t i = start; i < end; i += step) {
if (i > start) {
out << ", ";
}
if (!EmitConstantRange(out, constant, el_ty, i, i + step)) {
return false;
}
}
return true;
},
[&](Default) {
diagnostics_.add_error(
diag::System::Writer,
@ -1708,15 +1739,10 @@ bool GeneratorImpl::EmitExpression(std::ostream& out, const ast::Expression* exp
// TODO(crbug.com/tint/1580): Once 'const' is implemented, 'let' will no longer resolve
// to a shader-creation time constant value, and this can be removed.
if (auto constant = sem->ConstantValue()) {
// We do not want to inline array constants, as this will undo the work of
// PromoteInitializersToLet, which ensures that arrays are declarated in 'let's
// before their usage.
if (!constant.Type()->Is<sem::Array>()) {
return EmitConstant(out, constant);
}
}
}
}
return Switch(
expr,
[&](const ast::IndexAccessorExpression* a) { //
@ -2356,6 +2382,9 @@ bool GeneratorImpl::EmitStatement(const ast::Statement* stmt) {
v->variable, //
[&](const ast::Var* var) { return EmitVar(var); },
[&](const ast::Let* let) { return EmitLet(let); },
[&](const ast::Const*) {
return true; // Constants are embedded at their use
},
[&](Default) { //
TINT_ICE(Writer, diagnostics_)
<< "unknown statement type: " << stmt->TypeInfo().name;

View File

@ -22,16 +22,264 @@ namespace {
using MslGeneratorImplTest = TestHelper;
TEST_F(MslGeneratorImplTest, Emit_ModuleConstant) {
TEST_F(MslGeneratorImplTest, Emit_GlobalLet) {
auto* var = GlobalLet("pos", ty.array<f32, 3>(), array<f32, 3>(1_f, 2_f, 3_f));
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.EmitProgramConstVariable(var)) << gen.error();
EXPECT_EQ(gen.result(), "constant tint_array<float, 3> pos = tint_array<float, 3>{1.0f, 2.0f, 3.0f};\n");
EXPECT_EQ(gen.result(),
"constant tint_array<float, 3> pos = tint_array<float, 3>{1.0f, 2.0f, 3.0f};\n");
}
TEST_F(MslGeneratorImplTest, Emit_SpecConstant) {
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_AInt) {
auto* var = GlobalConst("G", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
int const l = 1;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_AFloat) {
auto* var = GlobalConst("G", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float const l = 1.0f;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_i32) {
auto* var = GlobalConst("G", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
int const l = 1;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_u32) {
auto* var = GlobalConst("G", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
uint const l = 1u;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_f32) {
auto* var = GlobalConst("G", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float const l = 1.0f;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AInt) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
int3 const l = int3(1, 2, 3);
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_AFloat) {
auto* var = GlobalConst("G", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float3 const l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_vec3_f32) {
auto* var = GlobalConst("G", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float3 const l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_AFloat) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_mat2x3_f32) {
auto* var = GlobalConst("G", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_f32) {
auto* var = GlobalConst("G", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
void f() {
tint_array<float, 3> const l = tint_array<float, 3>{1.0f, 2.0f, 3.0f};
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_GlobalConst_arr_vec2_bool) {
auto* var = GlobalConst("G", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
void f() {
tint_array<bool2, 3> const l = tint_array<bool2, 3>{bool2(true, false), bool2(false, true), bool2(true)};
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_Override) {
auto* var = Override("pos", ty.f32(), Expr(3_f),
ast::AttributeList{
Id(23),
@ -43,7 +291,7 @@ TEST_F(MslGeneratorImplTest, Emit_SpecConstant) {
EXPECT_EQ(gen.result(), "constant float pos [[function_constant(23)]];\n");
}
TEST_F(MslGeneratorImplTest, Emit_SpecConstant_NoId) {
TEST_F(MslGeneratorImplTest, Emit_Override_NoId) {
auto* var_a = Override("a", ty.f32(), nullptr,
ast::AttributeList{
Id(0),

View File

@ -38,7 +38,7 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement) {
EXPECT_EQ(gen.result(), " float a = 0.0f;\n");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Let) {
auto* var = Let("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
@ -51,6 +51,266 @@ TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
EXPECT_EQ(gen.result(), " float const a = 0.0f;\n");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) {
auto* var = Const("a", ty.f32(), Construct(ty.f32()));
auto* stmt = Decl(var);
WrapInFunction(stmt);
GeneratorImpl& gen = Build();
gen.increment_indent();
ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error();
EXPECT_EQ(gen.result(), ""); // Not a mistake - 'const' is inlined
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
int const l = 1;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float const l = 1.0f;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
int const l = 1;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
uint const l = 1u;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float const l = 1.0f;
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
int3 const l = int3(1, 2, 3);
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float3 const l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float3 const l = float3(1.0f, 2.0f, 3.0f);
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
void f() {
float2x3 const l = float2x3(float3(1.0f, 2.0f, 3.0f), float3(4.0f, 5.0f, 6.0f));
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
void f() {
tint_array<float, 3> const l = tint_array<float, 3>{1.0f, 2.0f, 3.0f};
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
auto* C = Const("C", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(#include <metal_stdlib>
using namespace metal;
template<typename T, size_t N>
struct tint_array {
const constant T& operator[](size_t i) const constant { return elements[i]; }
device T& operator[](size_t i) device { return elements[i]; }
const device T& operator[](size_t i) const device { return elements[i]; }
thread T& operator[](size_t i) thread { return elements[i]; }
const thread T& operator[](size_t i) const thread { return elements[i]; }
threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
T elements[N];
};
void f() {
tint_array<bool2, 3> const l = tint_array<bool2, 3>{bool2(true, false), bool2(false, true), bool2(true)};
}
)");
}
TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) {
auto* var = Var("a", ty.array<f32, 5>(), ast::StorageClass::kNone);
auto* stmt = Decl(var);

View File

@ -693,6 +693,12 @@ uint32_t Builder::GenerateFunctionTypeIfNeeded(const sem::Function* func) {
}
bool Builder::GenerateFunctionVariable(const ast::Variable* v) {
if (v->Is<ast::Const>()) {
// Constants are generated at their use. This is required as the 'const' declaration may be
// abstract-numeric, which has no SPIR-V type.
return true;
}
uint32_t init_id = 0;
if (v->constructor) {
init_id = GenerateExpressionWithLoadIfNeeded(v->constructor);
@ -703,9 +709,9 @@ bool Builder::GenerateFunctionVariable(const ast::Variable* v) {
auto* sem = builder_.Sem().Get(v);
if (auto* let = v->As<ast::Let>()) {
if (!let->constructor) {
error_ = "missing constructor for constant";
if (v->Is<ast::Let>()) {
if (!v->constructor) {
error_ = "missing constructor for let";
return false;
}
RegisterVariable(sem, init_id);
@ -748,6 +754,12 @@ bool Builder::GenerateStore(uint32_t to, uint32_t from) {
}
bool Builder::GenerateGlobalVariable(const ast::Variable* v) {
if (v->Is<ast::Const>()) {
// Constants are generated at their use. This is required as the 'const' declaration may be
// abstract-numeric, which has no SPIR-V type.
return true;
}
auto* sem = builder_.Sem().Get(v);
auto* type = sem->Type()->UnwrapRef();
@ -1280,9 +1292,17 @@ uint32_t Builder::GetGLSLstd450Import() {
uint32_t Builder::GenerateConstructorExpression(const ast::Variable* var,
const ast::Expression* expr) {
if (Is<ast::Override>(var)) {
if (auto* literal = expr->As<ast::LiteralExpression>()) {
return GenerateLiteralIfNeeded(var, literal);
}
} else {
if (auto* sem = builder_.Sem().Get(expr)) {
if (auto constant = sem->ConstantValue()) {
return GenerateConstantIfNeeded(constant);
}
}
}
if (auto* call = builder_.Sem().Get<sem::Call>(expr)) {
if (call->Target()->IsAnyOf<sem::TypeConstructor, sem::TypeConversion>()) {
return GenerateTypeConstructorOrConversion(call, var);

View File

@ -22,7 +22,7 @@ namespace {
using BuilderTest = TestHelper;
TEST_F(BuilderTest, Const_IndexAccessor_Vector) {
TEST_F(BuilderTest, Let_IndexAccessor_Vector) {
// let ary = vec3<i32>(1, 2, 3);
// var x = ary[1i];
@ -54,6 +54,35 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Vector) {
// const ary = vec3<i32>(1, 2, 3);
// var x = ary[1i];
auto* ary = Const("ary", nullptr, vec3<i32>(1_i, 2_i, 3_i));
auto* x = Var("x", nullptr, IndexAccessor(ary, 1_i));
WrapInFunction(ary, x);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeInt 32 1
%6 = OpConstant %5 2
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(OpStore %7 %6
OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, Runtime_IndexAccessor_Vector) {
// var ary : vec3<u32>;
// var x = ary[1i];
@ -244,7 +273,7 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Array_MultiLevel) {
TEST_F(BuilderTest, Let_IndexAccessor_Array_MultiLevel) {
// let ary = array<vec3<f32>, 2u>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
// var x = ary[1i][2i];
@ -287,6 +316,37 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Array_MultiLevel) {
// const ary = array<vec3<f32>, 2u>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
// var x = ary[1i][2i];
auto* ary =
Const("ary", nullptr,
array(ty.vec3<f32>(), 2_u, vec3<f32>(1._f, 2._f, 3._f), vec3<f32>(4._f, 5._f, 6._f)));
auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(ary, 1_i), 2_i));
WrapInFunction(ary, x);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 32
%6 = OpConstant %5 6
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(OpStore %7 %6
OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, Runtime_IndexAccessor_Array_MultiLevel) {
// var ary : array<vec3<f32>, 4u>;
// var x = ary[1i][2i];
@ -510,7 +570,7 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Nested_Array_f32) {
TEST_F(BuilderTest, Let_IndexAccessor_Nested_Array_f32) {
// let pos : array<array<f32, 2>, 3u> = array<vec2<f32, 2>, 3u>(
// array<f32, 2>(0.0, 0.5),
// array<f32, 2>(-0.5, -0.5),
@ -553,6 +613,40 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Nested_Array_f32) {
// const pos : array<array<f32, 2>, 3u> = array<vec2<f32, 2>, 3u>(
// array<f32, 2>(0.0, 0.5),
// array<f32, 2>(-0.5, -0.5),
// array<f32, 2>(0.5, -0.5));
// var x = pos[1u][0u];
auto* pos = Const("pos", ty.array(ty.vec2<f32>(), 3_u),
Construct(ty.array(ty.vec2<f32>(), 3_u), vec2<f32>(0_f, 0.5_f),
vec2<f32>(-0.5_f, -0.5_f), vec2<f32>(0.5_f, -0.5_f)));
auto* x = Var("x", nullptr, IndexAccessor(IndexAccessor(pos, 1_u), 0_u));
WrapInFunction(pos, x);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 32
%6 = OpConstant %5 -0.5
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%7 = OpVariable %8 Function %9
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(OpStore %7 %6
OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, Runtime_IndexAccessor_Nested_Array_f32) {
// var pos : array<array<f32, 2>, 3u>;
// var x = pos[1u][2u];
@ -636,7 +730,7 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Matrix) {
TEST_F(BuilderTest, Let_IndexAccessor_Matrix) {
// let a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
// var x = a[1i]
@ -674,6 +768,40 @@ OpReturn
Validate(b);
}
TEST_F(BuilderTest, Const_IndexAccessor_Matrix) {
// const a : mat2x2<f32>(vec2<f32>(1., 2.), vec2<f32>(3., 4.));
// var x = a[1i]
auto* a = Const("a", ty.mat2x2<f32>(),
Construct(ty.mat2x2<f32>(), Construct(ty.vec2<f32>(), 1_f, 2_f),
Construct(ty.vec2<f32>(), 3_f, 4_f)));
auto* x = Var("x", nullptr, IndexAccessor("a", 1_i));
WrapInFunction(a, x);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 2
%7 = OpConstant %6 3
%8 = OpConstant %6 4
%9 = OpConstantComposite %5 %7 %8
%11 = OpTypePointer Function %5
%12 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"(%10 = OpVariable %11 Function %12
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(OpStore %10 %9
OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, Runtime_IndexAccessor_Matrix) {
// var a : mat2x2<f32>;
// var x = a[1i]

View File

@ -1073,7 +1073,7 @@ TEST_F(SpvBuilderConstructorTest, Type_Vec4_With_Vec4) {
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"()");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_F32_With_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_F32_With_F32) {
auto* ctor = Construct<f32>(2_f);
GlobalLet("g", ty.f32(), ctor);
@ -1088,7 +1088,45 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_F32_With_F32) {
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_U32_With_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_F32_With_F32) {
auto* ctor = Construct<f32>(2_f);
GlobalConst("g", ty.f32(), ctor);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeFloat 32
%6 = OpConstant %5 2
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_F32_With_F32) {
auto* ctor = Construct<f32>(2_f);
GlobalVar("g", ty.f32(), ast::StorageClass::kPrivate, ctor);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 2
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
%6 = OpTypeVoid
%5 = OpTypeFunction %6
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_U32_With_F32) {
auto* ctor = Construct<u32>(1.5_f);
GlobalLet("g", ty.u32(), ctor);
@ -1103,9 +1141,47 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_U32_With_F32) {
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_U32_With_F32) {
auto* ctor = Construct<u32>(1.5_f);
GlobalConst("g", ty.u32(), ctor);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%5 = OpTypeInt 32 0
%6 = OpConstant %5 1
%8 = OpTypePointer Function %5
%9 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %7 %6
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_U32_With_F32) {
auto* ctor = Construct<u32>(1.5_f);
GlobalVar("g", ty.u32(), ast::StorageClass::kPrivate, ctor);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 0
%2 = OpConstant %1 1
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
%6 = OpTypeVoid
%5 = OpTypeFunction %6
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec2_With_F32) {
auto* cast = vec2<f32>(2_f);
auto* g = GlobalVar("g", ty.vec2<f32>(), cast, ast::StorageClass::kPrivate);
auto* g = GlobalLet("g", ty.vec2<f32>(), cast);
spirv::Builder& b = Build();
@ -1119,7 +1195,46 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_F32) {
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_Vec2) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec2_With_F32) {
auto* cast = vec2<f32>(2_f);
GlobalConst("g", ty.vec2<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 2
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec2_With_F32) {
auto* cast = vec2<f32>(2_f);
auto* g = GlobalVar("g", ty.vec2<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec2_With_Vec2) {
auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
GlobalLet("a", ty.vec2<f32>(), cast);
@ -1137,7 +1252,50 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec2_With_Vec2) {
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec3) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec2_With_Vec2) {
auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
GlobalConst("g", ty.vec2<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 2
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec2_With_Vec2) {
auto* cast = vec2<f32>(vec2<f32>(2_f, 2_f));
GlobalVar("a", ty.vec2<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 2
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3
%6 = OpTypePointer Private %1
%5 = OpVariable %6 Private %4
%8 = OpTypeVoid
%7 = OpTypeFunction %8
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec3_With_Vec3) {
auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
GlobalLet("a", ty.vec3<f32>(), cast);
@ -1155,7 +1313,50 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec3) {
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec4) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_Vec3) {
auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
GlobalConst("g", ty.vec3<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_Vec3) {
auto* cast = vec3<f32>(vec3<f32>(2_f, 2_f, 2_f));
GlobalVar("a", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
%6 = OpTypePointer Private %1
%5 = OpVariable %6 Private %4
%8 = OpTypeVoid
%7 = OpTypeFunction %8
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_Vec4) {
auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
GlobalLet("a", ty.vec4<f32>(), cast);
@ -1173,9 +1374,51 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec4) {
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec4) {
auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec4) {
auto* cast = vec4<f32>(vec4<f32>(2_f, 2_f, 2_f, 2_f));
GlobalVar("a", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
%6 = OpTypePointer Private %1
%5 = OpVariable %6 Private %4
%8 = OpTypeVoid
%7 = OpTypeFunction %8
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec3_With_F32) {
auto* cast = vec3<f32>(2_f);
auto* g = GlobalVar("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
auto* g = GlobalLet("g", ty.vec3<f32>(), cast);
spirv::Builder& b = Build();
@ -1189,55 +1432,158 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32) {
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_F32_Vec2) {
auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
auto* g = GlobalVar("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_F32) {
auto* cast = vec3<f32>(2_f);
GlobalConst("g", ty.vec3<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_F32) {
auto* cast = vec3<f32>(2_f);
auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpTypeVector %2 2
%5 = OpConstantComposite %4 %3 %3
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%11 = OpSpecConstantComposite %1 %3 %6 %9
%4 = OpConstantComposite %1 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec3_With_Vec2_F32) {
auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
auto* g = GlobalVar("g", ty.vec3<f32>(), cast, ast::StorageClass::kPrivate);
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec3_With_F32_Vec2) {
auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
auto* g = GlobalLet("g", ty.vec3<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpTypeVector %2 2
%4 = OpConstant %2 2
%5 = OpConstantComposite %3 %4 %4
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%11 = OpSpecConstantComposite %1 %6 %9 %4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_F32_Vec2) {
auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
GlobalConst("g", ty.vec3<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_F32_Vec2) {
auto* cast = vec3<f32>(2_f, vec2<f32>(2_f, 2_f));
auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec3_With_Vec2_F32) {
auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
auto* g = GlobalLet("g", ty.vec3<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec3_With_Vec2_F32) {
auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
GlobalConst("g", ty.vec3<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 3
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec3_With_Vec2_F32) {
auto* cast = vec3<f32>(vec2<f32>(2_f, 2_f), 2_f);
auto* g = GlobalVar("g", ty.vec3<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_F32) {
auto* cast = vec4<f32>(2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
@ -1251,147 +1597,372 @@ TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32) {
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_F32_Vec2) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32) {
auto* cast = vec4<f32>(2_f);
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32) {
auto* cast = vec4<f32>(2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_F32_F32_Vec2) {
auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpTypeVector %2 2
%5 = OpConstantComposite %4 %3 %3
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%11 = OpSpecConstantComposite %1 %3 %3 %6 %9
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_Vec2_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32_F32_Vec2) {
auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_F32_Vec2) {
auto* cast = vec4<f32>(2_f, 2_f, vec2<f32>(2_f, 2_f));
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_F32_Vec2_F32) {
auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpTypeVector %2 2
%5 = OpConstantComposite %4 %3 %3
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%11 = OpSpecConstantComposite %1 %3 %6 %9 %3
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec2_F32_F32) {
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32_Vec2_F32) {
auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_Vec2_F32) {
auto* cast = vec4<f32>(2_f, vec2<f32>(2_f, 2_f), 2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_Vec2_F32_F32) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 11u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpTypeVector %2 2
%4 = OpConstant %2 2
%5 = OpConstantComposite %3 %4 %4
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%11 = OpSpecConstantComposite %1 %6 %9 %4 %4
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec2_Vec2) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpTypeVector %2 2
%4 = OpConstant %2 2
%5 = OpConstantComposite %3 %4 %4
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%11 = OpSpecConstantOp %2 CompositeExtract %5 8
%12 = OpSpecConstantOp %2 CompositeExtract %5 10
%13 = OpSpecConstantComposite %1 %6 %9 %11 %12
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_F32_Vec3) {
auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpTypeVector %2 3
%5 = OpConstantComposite %4 %3 %3 %3
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%12 = OpConstant %7 2
%11 = OpSpecConstantOp %2 CompositeExtract %5 12
%13 = OpSpecConstantComposite %1 %3 %6 %9 %11
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_ModuleScope_Vec4_With_Vec3_F32) {
auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), cast, ast::StorageClass::kPrivate);
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec2_F32_F32) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec2_F32_F32) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), 2_f, 2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 13u);
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpTypeVector %2 3
%4 = OpConstant %2 2
%5 = OpConstantComposite %3 %4 %4 %4
%7 = OpTypeInt 32 0
%8 = OpConstant %7 0
%6 = OpSpecConstantOp %2 CompositeExtract %5 8
%10 = OpConstant %7 1
%9 = OpSpecConstantOp %2 CompositeExtract %5 10
%12 = OpConstant %7 2
%11 = OpSpecConstantOp %2 CompositeExtract %5 12
%13 = OpSpecConstantComposite %1 %6 %9 %11 %4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_Vec2_Vec2) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec2_Vec2) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec2_Vec2) {
auto* cast = vec4<f32>(vec2<f32>(2_f, 2_f), vec2<f32>(2_f, 2_f));
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_F32_Vec3) {
auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_F32_Vec3) {
auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_F32_Vec3) {
auto* cast = vec4<f32>(2_f, vec3<f32>(2_f, 2_f, 2_f));
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalLet_Vec4_With_Vec3_F32) {
auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
auto* g = GlobalLet("g", ty.vec4<f32>(), cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalConst_Vec4_With_Vec3_F32) {
auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
GlobalConst("g", ty.vec4<f32>(), cast);
WrapInFunction(Decl(Var("l", nullptr, Expr("g"))));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build());
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeVoid
%1 = OpTypeFunction %2
%6 = OpTypeFloat 32
%5 = OpTypeVector %6 4
%7 = OpConstant %6 2
%8 = OpConstantComposite %5 %7 %7 %7 %7
%10 = OpTypePointer Function %5
%11 = OpConstantNull %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpStore %9 %8
OpReturn
)");
Validate(b);
}
TEST_F(SpvBuilderConstructorTest, Type_GlobalVar_Vec4_With_Vec3_F32) {
auto* cast = vec4<f32>(vec3<f32>(2_f, 2_f, 2_f), 2_f);
auto* g = GlobalVar("g", ty.vec4<f32>(), ast::StorageClass::kPrivate, cast);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_EQ(b.GenerateConstructorExpression(g, cast), 4u);
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 4
%3 = OpConstant %2 2
%4 = OpConstantComposite %1 %3 %3 %3 %3
)");
}

View File

@ -131,7 +131,7 @@ TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Literals) {
)");
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Const) {
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Let) {
GlobalLet("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalLet("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalLet("depth", ty.i32(), Construct(ty.i32(), 4_i));
@ -149,6 +149,24 @@ TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Const) {
)");
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_Const) {
GlobalConst("width", ty.i32(), Construct(ty.i32(), 2_i));
GlobalConst("height", ty.i32(), Construct(ty.i32(), 3_i));
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 4_i));
auto* func = Func("main", {}, ty.void_(), {},
{
WorkgroupSize("width", "height", "depth"),
Stage(ast::PipelineStage::kCompute),
});
spirv::Builder& b = Build();
ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
EXPECT_EQ(DumpInstructions(b.execution_modes()),
R"(OpExecutionMode %3 LocalSize 2 3 4
)");
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_OverridableConst) {
Override("width", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
Override("height", ty.i32(), Construct(ty.i32(), 3_i), {Id(8u)});
@ -179,7 +197,7 @@ OpDecorate %3 BuiltIn WorkgroupSize
)");
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndLet) {
Override("height", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
GlobalLet("depth", ty.i32(), Construct(ty.i32(), 3_i));
auto* func = Func("main", {}, ty.void_(), {},
@ -206,6 +224,33 @@ OpDecorate %3 BuiltIn WorkgroupSize
)");
}
TEST_F(BuilderTest, Decoration_ExecutionMode_WorkgroupSize_LiteralAndConst) {
Override("height", ty.i32(), Construct(ty.i32(), 2_i), {Id(7u)});
GlobalConst("depth", ty.i32(), Construct(ty.i32(), 3_i));
auto* func = Func("main", {}, ty.void_(), {},
{
WorkgroupSize(4_i, "height", "depth"),
Stage(ast::PipelineStage::kCompute),
});
spirv::Builder& b = Build();
ASSERT_TRUE(b.GenerateExecutionModes(func, 3)) << b.error();
EXPECT_EQ(DumpInstructions(b.execution_modes()), "");
EXPECT_EQ(DumpInstructions(b.types()),
R"(%2 = OpTypeInt 32 0
%1 = OpTypeVector %2 3
%4 = OpConstant %2 4
%5 = OpSpecConstant %2 2
%6 = OpConstant %2 3
%3 = OpSpecConstantComposite %1 %4 %5 %6
)");
EXPECT_EQ(DumpInstructions(b.annots()),
R"(OpDecorate %5 SpecId 7
OpDecorate %3 BuiltIn WorkgroupSize
)");
}
TEST_F(BuilderTest, Decoration_ExecutionMode_MultipleFragment) {
auto* func1 = Func("main1", {}, ty.void_(), {},
{

View File

@ -138,7 +138,7 @@ OpStore %7 %6
)");
}
TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
TEST_F(BuilderTest, FunctionVar_LetWithVarInitializer) {
// var v : f32 = 1.0;
// let v2 : f32 = v; // Should generate the load
@ -173,7 +173,38 @@ OpStore %7 %6
)");
}
TEST_F(BuilderTest, FunctionVar_Const) {
TEST_F(BuilderTest, FunctionVar_ConstWithVarInitializer) {
// const v : f32 = 1.0;
// let v2 : f32 = v;
auto* v = Const("v", ty.f32(), Expr(1_f));
auto* v2 = Var("v2", ty.f32(), ast::StorageClass::kNone, Expr("v"));
WrapInFunction(v, v2);
spirv::Builder& b = Build();
b.push_function(Function{});
EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
EXPECT_TRUE(b.GenerateFunctionVariable(v2)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.debug()), R"(OpName %3 "v2"
)");
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeFloat 32
%2 = OpConstant %1 1
%4 = OpTypePointer Function %1
%5 = OpConstantNull %1
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()),
R"(%3 = OpVariable %4 Function %5
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()),
R"(OpStore %3 %2
)");
}
TEST_F(BuilderTest, FunctionVar_Let) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
auto* v = Let("var", ty.vec3<f32>(), init);
@ -193,5 +224,20 @@ TEST_F(BuilderTest, FunctionVar_Const) {
)");
}
TEST_F(BuilderTest, FunctionVar_Const) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
auto* v = Const("var", ty.vec3<f32>(), init);
WrapInFunction(v);
spirv::Builder& b = Build();
EXPECT_TRUE(b.GenerateFunctionVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), ""); // Not a mistake - 'const' is inlined
}
} // namespace
} // namespace tint::writer::spirv

View File

@ -61,7 +61,7 @@ TEST_F(BuilderTest, GlobalVar_WithConstructor) {
)");
}
TEST_F(BuilderTest, GlobalVar_Const) {
TEST_F(BuilderTest, GlobalLet) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
auto* v = GlobalLet("l", ty.vec3<f32>(), init);
@ -81,7 +81,32 @@ TEST_F(BuilderTest, GlobalVar_Const) {
)");
}
TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
TEST_F(BuilderTest, GlobalConst) {
// const c = 42;
// var v = c;
auto* c = GlobalConst("c", nullptr, Expr(42_a));
GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1
%2 = OpConstant %1 42
%4 = OpTypePointer Private %1
%3 = OpVariable %4 Private %2
%6 = OpTypeVoid
%5 = OpTypeFunction %6
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, GlobalLet_Vec_Constructor) {
auto* init = vec3<f32>(1_f, 2_f, 3_f);
auto* v = GlobalLet("l", ty.vec3<f32>(), init);
@ -100,7 +125,94 @@ TEST_F(BuilderTest, GlobalVar_Complex_Constructor) {
)");
}
TEST_F(BuilderTest, GlobalVar_Complex_ConstructorNestedVector) {
TEST_F(BuilderTest, GlobalConst_Vec_Constructor) {
// const c = vec3<f32>(1f, 2f, 3f);
// var v = c;
auto* c = GlobalConst("c", nullptr, vec3<f32>(1_f, 2_f, 3_f));
GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
%8 = OpTypePointer Private %1
%7 = OpVariable %8 Private %6
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, GlobalConst_Vec_AInt_Constructor) {
// const c = vec3(1, 2, 3);
// var v = c;
auto* c = GlobalConst("c", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeInt 32 1
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
%8 = OpTypePointer Private %1
%7 = OpVariable %8 Private %6
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, GlobalConst_Vec_AFloat_Constructor) {
// const c = vec3(1.0, 2.0, 3.0);
// var v = c;
auto* c = GlobalConst("c", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
%8 = OpTypePointer Private %1
%7 = OpVariable %8 Private %6
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, GlobalLet_Nested_Vec_Constructor) {
auto* init = vec3<f32>(vec2<f32>(1_f, 2_f), 3_f);
auto* v = GlobalLet("l", ty.vec3<f32>(), init);
@ -119,6 +231,35 @@ TEST_F(BuilderTest, GlobalVar_Complex_ConstructorNestedVector) {
)");
}
TEST_F(BuilderTest, GlobalConst_Nested_Vec_Constructor) {
// const c = vec3<f32>(vec2<f32>(1f, 2f), 3f));
// var v = c;
auto* c = GlobalConst("c", nullptr, vec3<f32>(vec2<f32>(1_f, 2_f), 3_f));
GlobalVar("v", nullptr, ast::StorageClass::kPrivate, Expr(c));
spirv::Builder& b = SanitizeAndBuild();
ASSERT_TRUE(b.Build()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 2
%5 = OpConstant %2 3
%6 = OpConstantComposite %1 %3 %4 %5
%8 = OpTypePointer Private %1
%7 = OpVariable %8 Private %6
%10 = OpTypeVoid
%9 = OpTypeFunction %10
)");
EXPECT_EQ(DumpInstructions(b.functions()[0].variables()), R"()");
EXPECT_EQ(DumpInstructions(b.functions()[0].instructions()), R"(OpReturn
)");
Validate(b);
}
TEST_F(BuilderTest, GlobalVar_WithBindingAndGroup) {
auto* v =
GlobalVar("var", ty.sampler(ast::SamplerKind::kSampler), ast::StorageClass::kNone, nullptr,

View File

@ -25,9 +25,9 @@ using BuilderTest = TestHelper;
TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
auto* init = vec3<f32>(1_f, 1_f, 3_f);
auto* v = GlobalLet("var", ty.vec3<f32>(), init);
auto* v = GlobalConst("c", ty.vec3<f32>(), init);
auto* expr = Expr("var");
auto* expr = Expr("c");
WrapInFunction(expr);
spirv::Builder& b = Build();
@ -35,14 +35,9 @@ TEST_F(BuilderTest, IdentifierExpression_GlobalConst) {
EXPECT_TRUE(b.GenerateGlobalVariable(v)) << b.error();
ASSERT_FALSE(b.has_error()) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%2 = OpTypeFloat 32
%1 = OpTypeVector %2 3
%3 = OpConstant %2 1
%4 = OpConstant %2 3
%5 = OpConstantComposite %1 %3 %3 %4
)");
EXPECT_EQ(DumpInstructions(b.types()), R"()");
EXPECT_EQ(b.GenerateIdentifierExpression(expr), 5u);
EXPECT_EQ(b.GenerateIdentifierExpression(expr), 0u);
}
TEST_F(BuilderTest, IdentifierExpression_GlobalVar) {
@ -115,7 +110,6 @@ TEST_F(BuilderTest, IdentifierExpression_FunctionVar) {
TEST_F(BuilderTest, IdentifierExpression_Load) {
auto* var = GlobalVar("var", ty.i32(), ast::StorageClass::kPrivate);
auto* expr = Add("var", "var");
WrapInFunction(expr);
@ -138,15 +132,14 @@ TEST_F(BuilderTest, IdentifierExpression_Load) {
}
TEST_F(BuilderTest, IdentifierExpression_NoLoadConst) {
auto* var = GlobalLet("var", ty.i32(), Expr(2_i));
auto* expr = Add("var", "var");
WrapInFunction(expr);
auto* let = Let("let", ty.i32(), Expr(2_i));
auto* expr = Add("let", "let");
WrapInFunction(let, expr);
spirv::Builder& b = Build();
b.push_function(Function{});
ASSERT_TRUE(b.GenerateGlobalVariable(var)) << b.error();
ASSERT_TRUE(b.GenerateFunctionVariable(let)) << b.error();
EXPECT_EQ(b.GenerateBinaryExpression(expr->As<ast::BinaryExpression>()), 3u) << b.error();
EXPECT_EQ(DumpInstructions(b.types()), R"(%1 = OpTypeInt 32 1

View File

@ -50,5 +50,189 @@ TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_InferredType) {
EXPECT_EQ(gen.result(), " var a = 123i;\n");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_AInt) {
auto* C = Const("C", nullptr, Expr(1_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = 1;
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_AFloat) {
auto* C = Const("C", nullptr, Expr(1._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = 1.0;
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_i32) {
auto* C = Const("C", nullptr, Expr(1_i));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = 1i;
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_u32) {
auto* C = Const("C", nullptr, Expr(1_u));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = 1u;
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_f32) {
auto* C = Const("C", nullptr, Expr(1_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = 1.0f;
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AInt) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1_a, 2_a, 3_a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = vec3(1, 2, 3);
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_AFloat) {
auto* C = Const("C", nullptr, Construct(ty.vec3(nullptr), 1._a, 2._a, 3._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = vec3(1.0, 2.0, 3.0);
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_vec3_f32) {
auto* C = Const("C", nullptr, vec3<f32>(1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = vec3<f32>(1.0f, 2.0f, 3.0f);
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_AFloat) {
auto* C =
Const("C", nullptr, Construct(ty.mat(nullptr, 2, 3), 1._a, 2._a, 3._a, 4._a, 5._a, 6._a));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = mat2x3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_mat2x3_f32) {
auto* C = Const("C", nullptr, mat2x3<f32>(1_f, 2_f, 3_f, 4_f, 5_f, 6_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = mat2x3<f32>(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f);
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_f32) {
auto* C = Const("C", nullptr, Construct(ty.array<f32, 3>(), 1_f, 2_f, 3_f));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = array<f32, 3u>(1.0f, 2.0f, 3.0f);
let l = C;
}
)");
}
TEST_F(WgslGeneratorImplTest, Emit_VariableDeclStatement_Const_arr_vec2_bool) {
auto* C = Const("C", nullptr,
Construct(ty.array(ty.vec2<bool>(), 3_u), //
vec2<bool>(true, false), //
vec2<bool>(false, true), //
vec2<bool>(true, true)));
Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))});
GeneratorImpl& gen = Build();
ASSERT_TRUE(gen.Generate()) << gen.error();
EXPECT_EQ(gen.result(), R"(fn f() {
const C = array<vec2<bool>, 3u>(vec2<bool>(true, false), vec2<bool>(false, true), vec2<bool>(true, true));
let l = C;
}
)");
}
} // namespace
} // namespace tint::writer::wgsl

View File

@ -18,7 +18,7 @@ layout(binding = 1, std430) buffer S_2 {
ivec4 arr[4];
} src_storage;
ivec4[4] ret_arr() {
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
return tint_symbol_1;
}
@ -34,7 +34,7 @@ void foo(ivec4 src_param[4]) {
dst = tint_symbol_3;
dst = src_param;
dst = ret_arr();
ivec4 src_let[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 src_let[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
dst = src_let;
dst = src_function;
dst = src_private;

View File

@ -20,7 +20,7 @@ layout(binding = 1, std430) buffer S_2 {
ivec4 dst[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
int dst_nested[4][3][2] = int[4][3][2](int[3][2](int[2](0, 0), int[2](0, 0), int[2](0, 0)), int[3][2](int[2](0, 0), int[2](0, 0), int[2](0, 0)), int[3][2](int[2](0, 0), int[2](0, 0), int[2](0, 0)), int[3][2](int[2](0, 0), int[2](0, 0), int[2](0, 0)));
ivec4[4] ret_arr() {
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
return tint_symbol_1;
}
@ -35,7 +35,7 @@ void foo(ivec4 src_param[4]) {
dst = tint_symbol_3;
dst = src_param;
dst = ret_arr();
ivec4 src_let[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 src_let[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
dst = src_let;
dst = src_function;
dst = src_private;

View File

@ -28,7 +28,7 @@ layout(binding = 3, std430) buffer S_nested_1 {
int arr[4][3][2];
} dst_nested;
ivec4[4] ret_arr() {
ivec4 tint_symbol_2[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 tint_symbol_2[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
return tint_symbol_2;
}
@ -44,7 +44,7 @@ void foo(ivec4 src_param[4]) {
dst.arr = src_param;
ivec4 tint_symbol[4] = ret_arr();
dst.arr = tint_symbol;
ivec4 src_let[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 src_let[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
dst.arr = src_let;
dst.arr = src_function;
dst.arr = src_private;

View File

@ -20,7 +20,7 @@ layout(binding = 1, std430) buffer S_2 {
shared ivec4 dst[4];
shared int dst_nested[4][3][2];
ivec4[4] ret_arr() {
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
return tint_symbol_1;
}
@ -35,7 +35,7 @@ void foo(ivec4 src_param[4]) {
dst = tint_symbol_3;
dst = src_param;
dst = ret_arr();
ivec4 src_let[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 src_let[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
dst = src_let;
dst = src_function;
dst = src_private;

View File

@ -9,16 +9,16 @@ void tint_symbol() {
int tint_symbol_1[4] = int[4](1, 2, 3, 4);
int tint_symbol_2[4] = int[4](5, 6, 7, 8);
int tint_symbol_3[4] = int[4](9, 10, 11, 12);
int tint_symbol_4[3][4] = int[3][4](tint_symbol_1, tint_symbol_2, tint_symbol_3);
int tint_symbol_4[3][4] = int[3][4](int[4](1, 2, 3, 4), int[4](5, 6, 7, 8), int[4](9, 10, 11, 12));
int tint_symbol_5[4] = int[4](13, 14, 15, 16);
int tint_symbol_6[4] = int[4](17, 18, 19, 20);
int tint_symbol_7[4] = int[4](21, 22, 23, 24);
int tint_symbol_8[3][4] = int[3][4](tint_symbol_5, tint_symbol_6, tint_symbol_7);
int nested_nonempty[2][3][4] = int[2][3][4](tint_symbol_4, tint_symbol_8);
int tint_symbol_8[3][4] = int[3][4](int[4](13, 14, 15, 16), int[4](17, 18, 19, 20), int[4](21, 22, 23, 24));
int nested_nonempty[2][3][4] = int[2][3][4](int[3][4](int[4](1, 2, 3, 4), int[4](5, 6, 7, 8), int[4](9, 10, 11, 12)), int[3][4](int[4](13, 14, 15, 16), int[4](17, 18, 19, 20), int[4](21, 22, 23, 24)));
int tint_symbol_9[4] = int[4](1, 2, x, (x + 1));
int tint_symbol_10[4] = int[4](5, 6, 3, (4 + 1));
int tint_symbol_11[3][4] = int[3][4](tint_symbol_9, tint_symbol_10, nonempty);
int nested_nonempty_with_expr[2][3][4] = int[2][3][4](tint_symbol_11, nested_nonempty[1]);
int nested_nonempty_with_expr[2][3][4] = int[2][3][4](tint_symbol_11, int[3][4](int[4](13, 14, 15, 16), int[4](17, 18, 19, 20), int[4](21, 22, 23, 24)));
int tint_symbol_12[4] = int[4](0, 0, 0, 0);
int subexpr_empty = 0;
int tint_symbol_13[4] = int[4](1, 2, 3, 4);
@ -26,13 +26,13 @@ void tint_symbol() {
int tint_symbol_14[4] = int[4](1, x, (x + 1), 4);
int subexpr_nonempty_with_expr = tint_symbol_14[2];
int tint_symbol_15[2][4] = int[2][4](int[4](0, 0, 0, 0), int[4](0, 0, 0, 0));
int subexpr_nested_empty[4] = tint_symbol_15[1];
int subexpr_nested_empty[4] = int[4](0, 0, 0, 0);
int tint_symbol_16[4] = int[4](1, 2, 3, 4);
int tint_symbol_17[4] = int[4](5, 6, 7, 8);
int tint_symbol_18[2][4] = int[2][4](tint_symbol_16, tint_symbol_17);
int subexpr_nested_nonempty[4] = tint_symbol_18[1];
int tint_symbol_18[2][4] = int[2][4](int[4](1, 2, 3, 4), int[4](5, 6, 7, 8));
int subexpr_nested_nonempty[4] = int[4](5, 6, 7, 8);
int tint_symbol_19[4] = int[4](1, x, (x + 1), 4);
int tint_symbol_20[2][4] = int[2][4](tint_symbol_19, nested_nonempty[1][2]);
int tint_symbol_20[2][4] = int[2][4](tint_symbol_19, int[4](21, 22, 23, 24));
int subexpr_nested_nonempty_with_expr[4] = tint_symbol_20[1];
}

View File

@ -8,16 +8,16 @@ void main() {
const int tint_symbol[4] = {1, 2, 3, 4};
const int tint_symbol_1[4] = {5, 6, 7, 8};
const int tint_symbol_2[4] = {9, 10, 11, 12};
const int tint_symbol_3[3][4] = {tint_symbol, tint_symbol_1, tint_symbol_2};
const int tint_symbol_3[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
const int tint_symbol_4[4] = {13, 14, 15, 16};
const int tint_symbol_5[4] = {17, 18, 19, 20};
const int tint_symbol_6[4] = {21, 22, 23, 24};
const int tint_symbol_7[3][4] = {tint_symbol_4, tint_symbol_5, tint_symbol_6};
const int nested_nonempty[2][3][4] = {tint_symbol_3, tint_symbol_7};
const int tint_symbol_7[3][4] = {{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}};
const int nested_nonempty[2][3][4] = {{{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}}, {{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}}};
const int tint_symbol_8[4] = {1, 2, x, (x + 1)};
const int tint_symbol_9[4] = {5, 6, 3, (4 + 1)};
const int tint_symbol_10[3][4] = {tint_symbol_8, tint_symbol_9, nonempty};
const int nested_nonempty_with_expr[2][3][4] = {tint_symbol_10, nested_nonempty[1]};
const int nested_nonempty_with_expr[2][3][4] = {tint_symbol_10, {{13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24}}};
const int tint_symbol_11[4] = (int[4])0;
const int subexpr_empty = 0;
const int tint_symbol_12[4] = {1, 2, 3, 4};
@ -25,13 +25,13 @@ void main() {
const int tint_symbol_13[4] = {1, x, (x + 1), 4};
const int subexpr_nonempty_with_expr = tint_symbol_13[2];
const int tint_symbol_14[2][4] = (int[2][4])0;
const int subexpr_nested_empty[4] = tint_symbol_14[1];
const int subexpr_nested_empty[4] = (int[4])0;
const int tint_symbol_15[4] = {1, 2, 3, 4};
const int tint_symbol_16[4] = {5, 6, 7, 8};
const int tint_symbol_17[2][4] = {tint_symbol_15, tint_symbol_16};
const int subexpr_nested_nonempty[4] = tint_symbol_17[1];
const int tint_symbol_17[2][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};
const int subexpr_nested_nonempty[4] = {5, 6, 7, 8};
const int tint_symbol_18[4] = {1, x, (x + 1), 4};
const int tint_symbol_19[2][4] = {tint_symbol_18, nested_nonempty[1][2]};
const int tint_symbol_19[2][4] = {tint_symbol_18, {21, 22, 23, 24}};
const int subexpr_nested_nonempty_with_expr[4] = tint_symbol_19[1];
return;
}

View File

@ -23,16 +23,16 @@ kernel void tint_symbol() {
tint_array<int, 4> const tint_symbol_1 = tint_array<int, 4>{1, 2, 3, 4};
tint_array<int, 4> const tint_symbol_2 = tint_array<int, 4>{5, 6, 7, 8};
tint_array<int, 4> const tint_symbol_3 = tint_array<int, 4>{9, 10, 11, 12};
tint_array<tint_array<int, 4>, 3> const tint_symbol_4 = tint_array<tint_array<int, 4>, 3>{tint_symbol_1, tint_symbol_2, tint_symbol_3};
tint_array<tint_array<int, 4>, 3> const tint_symbol_4 = tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{1, 2, 3, 4}, tint_array<int, 4>{5, 6, 7, 8}, tint_array<int, 4>{9, 10, 11, 12}};
tint_array<int, 4> const tint_symbol_5 = tint_array<int, 4>{13, 14, 15, 16};
tint_array<int, 4> const tint_symbol_6 = tint_array<int, 4>{17, 18, 19, 20};
tint_array<int, 4> const tint_symbol_7 = tint_array<int, 4>{21, 22, 23, 24};
tint_array<tint_array<int, 4>, 3> const tint_symbol_8 = tint_array<tint_array<int, 4>, 3>{tint_symbol_5, tint_symbol_6, tint_symbol_7};
tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_symbol_4, tint_symbol_8};
tint_array<tint_array<int, 4>, 3> const tint_symbol_8 = tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{13, 14, 15, 16}, tint_array<int, 4>{17, 18, 19, 20}, tint_array<int, 4>{21, 22, 23, 24}};
tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{1, 2, 3, 4}, tint_array<int, 4>{5, 6, 7, 8}, tint_array<int, 4>{9, 10, 11, 12}}, tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{13, 14, 15, 16}, tint_array<int, 4>{17, 18, 19, 20}, tint_array<int, 4>{21, 22, 23, 24}}};
tint_array<int, 4> const tint_symbol_9 = tint_array<int, 4>{1, 2, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1)))};
tint_array<int, 4> const tint_symbol_10 = tint_array<int, 4>{5, 6, 3, as_type<int>((as_type<uint>(4) + as_type<uint>(1)))};
tint_array<tint_array<int, 4>, 3> const tint_symbol_11 = tint_array<tint_array<int, 4>, 3>{tint_symbol_9, tint_symbol_10, nonempty};
tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty_with_expr = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_symbol_11, nested_nonempty[1]};
tint_array<tint_array<tint_array<int, 4>, 3>, 2> const nested_nonempty_with_expr = tint_array<tint_array<tint_array<int, 4>, 3>, 2>{tint_symbol_11, tint_array<tint_array<int, 4>, 3>{tint_array<int, 4>{13, 14, 15, 16}, tint_array<int, 4>{17, 18, 19, 20}, tint_array<int, 4>{21, 22, 23, 24}}};
tint_array<int, 4> const tint_symbol_12 = tint_array<int, 4>{};
int const subexpr_empty = 0;
tint_array<int, 4> const tint_symbol_13 = tint_array<int, 4>{1, 2, 3, 4};
@ -40,13 +40,13 @@ kernel void tint_symbol() {
tint_array<int, 4> const tint_symbol_14 = tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), 4};
int const subexpr_nonempty_with_expr = tint_symbol_14[2];
tint_array<tint_array<int, 4>, 2> const tint_symbol_15 = tint_array<tint_array<int, 4>, 2>{};
tint_array<int, 4> const subexpr_nested_empty = tint_symbol_15[1];
tint_array<int, 4> const subexpr_nested_empty = tint_array<int, 4>{};
tint_array<int, 4> const tint_symbol_16 = tint_array<int, 4>{1, 2, 3, 4};
tint_array<int, 4> const tint_symbol_17 = tint_array<int, 4>{5, 6, 7, 8};
tint_array<tint_array<int, 4>, 2> const tint_symbol_18 = tint_array<tint_array<int, 4>, 2>{tint_symbol_16, tint_symbol_17};
tint_array<int, 4> const subexpr_nested_nonempty = tint_symbol_18[1];
tint_array<tint_array<int, 4>, 2> const tint_symbol_18 = tint_array<tint_array<int, 4>, 2>{tint_array<int, 4>{1, 2, 3, 4}, tint_array<int, 4>{5, 6, 7, 8}};
tint_array<int, 4> const subexpr_nested_nonempty = tint_array<int, 4>{5, 6, 7, 8};
tint_array<int, 4> const tint_symbol_19 = tint_array<int, 4>{1, x, as_type<int>((as_type<uint>(x) + as_type<uint>(1))), 4};
tint_array<tint_array<int, 4>, 2> const tint_symbol_20 = tint_array<tint_array<int, 4>, 2>{tint_symbol_19, nested_nonempty[1][2]};
tint_array<tint_array<int, 4>, 2> const tint_symbol_20 = tint_array<tint_array<int, 4>, 2>{tint_symbol_19, tint_array<int, 4>{21, 22, 23, 24}};
tint_array<int, 4> const subexpr_nested_nonempty_with_expr = tint_symbol_20[1];
return;
}

View File

@ -24,7 +24,7 @@ void tint_symbol(uint idx) {
s.arr[idx].f = 0.0f;
s.arr[idx].g = mat2x3(vec3(0.0f), vec3(0.0f));
s.arr[idx].h = mat3x2(vec2(0.0f), vec2(0.0f), vec2(0.0f));
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0), ivec4(0, 0, 0, 0));
ivec4 tint_symbol_1[4] = ivec4[4](ivec4(0), ivec4(0), ivec4(0), ivec4(0));
s.arr[idx].i = tint_symbol_1;
}

View File

@ -81,7 +81,7 @@ void swap_i1_i1_(inout int i, inout int j) {
const int x_34_save = x_33;
const int x_35 = obj.numbers[x_34_save];
const QuicksortObject x_943 = obj;
const int tint_symbol_52[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_52[10] = (int[10])0;
const QuicksortObject tint_symbol_53 = {tint_symbol_52};
obj = tint_symbol_53;
obj = x_943;
@ -94,7 +94,7 @@ void swap_i1_i1_(inout int i, inout int j) {
obj.numbers = tint_symbol_13;
}
const QuicksortObject x_944 = obj;
const int tint_symbol_54[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_54[10] = (int[10])0;
const QuicksortObject tint_symbol_55 = {tint_symbol_54};
obj = tint_symbol_55;
obj = x_944;
@ -135,7 +135,7 @@ void swap_i1_i1_(inout int i, inout int j) {
obj.numbers = tint_symbol_21;
}
const QuicksortObject x_950 = obj;
const int tint_symbol_56[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_56[10] = (int[10])0;
const QuicksortObject tint_symbol_57 = {tint_symbol_56};
obj = tint_symbol_57;
obj = x_950;
@ -213,7 +213,7 @@ int performPartition_i1_i1_(inout int l, inout int h) {
const float3 x_536 = float3(x_534.x, x_534.z, x_535.x);
j_1 = 10;
const QuicksortObject x_960 = obj;
const int tint_symbol_58[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_58[10] = (int[10])0;
const QuicksortObject tint_symbol_59 = {tint_symbol_58};
obj = tint_symbol_59;
obj = x_960;
@ -230,7 +230,7 @@ int performPartition_i1_i1_(inout int l, inout int h) {
pivot = x_963;
x_537 = float2(float3(1.0f, 2.0f, 3.0f).y, float3(1.0f, 2.0f, 3.0f).z);
const QuicksortObject x_964 = obj;
const int tint_symbol_60[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_60[10] = (int[10])0;
const QuicksortObject tint_symbol_61 = {tint_symbol_60};
obj = tint_symbol_61;
obj = x_964;
@ -274,7 +274,7 @@ int performPartition_i1_i1_(inout int l, inout int h) {
param_1 = x_971;
const int x_62 = obj.numbers[x_61_save];
const QuicksortObject x_972 = obj;
const int tint_symbol_62[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_62[10] = (int[10])0;
const QuicksortObject tint_symbol_63 = {tint_symbol_62};
obj = tint_symbol_63;
obj = x_972;
@ -334,7 +334,7 @@ int performPartition_i1_i1_(inout int l, inout int h) {
param_1 = x_985;
}
const QuicksortObject x_986 = obj;
const int tint_symbol_64[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_64[10] = (int[10])0;
const QuicksortObject tint_symbol_65 = {tint_symbol_64};
obj = tint_symbol_65;
obj = x_986;
@ -393,7 +393,7 @@ int performPartition_i1_i1_(inout int l, inout int h) {
}
const float2 x_549 = float2(x_534.x, x_534.y);
const QuicksortObject x_994 = obj;
const int tint_symbol_66[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_66[10] = (int[10])0;
const QuicksortObject tint_symbol_67 = {tint_symbol_66};
obj = tint_symbol_67;
obj = x_994;
@ -463,7 +463,7 @@ void quicksort_() {
param_5 = x_1007;
h_1 = 9;
const int x_1008[10] = stack;
const int tint_symbol_68[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_68[10] = (int[10])0;
stack = tint_symbol_68;
stack = x_1008;
const float2 x_556 = float2(float3(1.0f, 2.0f, 3.0f).y, float3(1.0f, 2.0f, 3.0f).y);
@ -497,14 +497,14 @@ void quicksort_() {
param_4 = x_1015;
const int x_95 = l_1;
const QuicksortObject x_1016 = obj;
const int tint_symbol_69[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_69[10] = (int[10])0;
const QuicksortObject tint_symbol_70 = {tint_symbol_69};
obj = tint_symbol_70;
obj = x_1016;
const float3 x_560 = float3(x_559.y, x_559.x, x_557.x);
const int x_96_save = x_94;
const int x_1017[10] = stack;
const int tint_symbol_71[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_71[10] = (int[10])0;
stack = tint_symbol_71;
stack = x_1017;
const float3 x_561 = float3(x_556.y, x_556.y, x_556.y);
@ -555,12 +555,12 @@ void quicksort_() {
h_1 = 0;
h_1 = x_1028;
const int x_1029[10] = stack;
const int tint_symbol_72[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_72[10] = (int[10])0;
stack = tint_symbol_72;
stack = x_1029;
const int x_106 = top;
const int x_1030[10] = stack;
const int tint_symbol_73[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_73[10] = (int[10])0;
stack = tint_symbol_73;
stack = x_1030;
const float2 x_567 = float2(x_558.x, x_564.z);
@ -572,7 +572,7 @@ void quicksort_() {
break;
}
const QuicksortObject x_1032 = obj;
const int tint_symbol_74[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_74[10] = (int[10])0;
const QuicksortObject tint_symbol_75 = {tint_symbol_74};
obj = tint_symbol_75;
obj = x_1032;
@ -599,7 +599,7 @@ void quicksort_() {
stack[x_96_save] = x_1037;
const int x_111 = stack[x_110_save];
const int x_1038[10] = stack;
const int tint_symbol_76[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_76[10] = (int[10])0;
stack = tint_symbol_76;
stack = x_1038;
const float3 x_571 = float3(x_559.y, x_559.x, x_564.y);
@ -608,7 +608,7 @@ void quicksort_() {
l_1 = x_1039;
h_1 = x_111;
const int x_1040[10] = stack;
const int tint_symbol_77[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_77[10] = (int[10])0;
stack = tint_symbol_77;
stack = x_1040;
const float2 x_572 = float2(x_562.y, x_561.y);
@ -700,7 +700,7 @@ void quicksort_() {
stack[x_100_save] = 0;
stack[x_100_save] = x_1061;
const int x_1062[10] = stack;
const int tint_symbol_78[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_78[10] = (int[10])0;
stack = tint_symbol_78;
stack = x_1062;
const float2 x_584 = float2(x_569.z, x_569.y);
@ -740,7 +740,7 @@ void quicksort_() {
h_1 = x_1070;
top = x_133;
const int x_1071[10] = stack;
const int tint_symbol_79[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_79[10] = (int[10])0;
stack = tint_symbol_79;
stack = x_1071;
const int x_134 = p;
@ -766,7 +766,7 @@ void quicksort_() {
stack[x_96_save] = x_1076;
const float2 x_592 = float2(float3(1.0f, 2.0f, 3.0f).x, float3(1.0f, 2.0f, 3.0f).y);
const QuicksortObject x_1077 = obj;
const int tint_symbol_80[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_80[10] = (int[10])0;
const QuicksortObject tint_symbol_81 = {tint_symbol_80};
obj = tint_symbol_81;
obj = x_1077;
@ -833,7 +833,7 @@ void quicksort_() {
const float2 x_601 = float2(x_563.x, x_563.y);
stack[x_147_save] = asint((1u + asuint(x_145)));
const int x_1093[10] = stack;
const int tint_symbol_82[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_82[10] = (int[10])0;
stack = tint_symbol_82;
stack = x_1093;
const int x_148 = top;
@ -842,7 +842,7 @@ void quicksort_() {
stack[x_114_save] = x_1094;
const float2 x_602 = float2(x_565.y, x_599.y);
const int x_1095[10] = stack;
const int tint_symbol_83[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_83[10] = (int[10])0;
stack = tint_symbol_83;
stack = x_1095;
const int x_149 = (x_148 + asint(1u));
@ -878,7 +878,7 @@ void quicksort_() {
l_1 = x_1103;
const float2 x_604 = float2(x_563.z, x_564.x);
const QuicksortObject x_1104 = obj;
const int tint_symbol_84[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_84[10] = (int[10])0;
const QuicksortObject tint_symbol_85 = {tint_symbol_84};
obj = tint_symbol_85;
obj = x_1104;
@ -899,13 +899,13 @@ void main_1() {
uv = x_717;
i_2 = 0;
const QuicksortObject x_721 = obj;
const int tint_symbol_86[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_86[10] = (int[10])0;
const QuicksortObject tint_symbol_87 = {tint_symbol_86};
obj = tint_symbol_87;
obj = x_721;
if (true) {
const QuicksortObject x_722 = obj;
const int tint_symbol_88[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_88[10] = (int[10])0;
const QuicksortObject tint_symbol_89 = {tint_symbol_88};
obj = tint_symbol_89;
obj = x_722;
@ -919,13 +919,13 @@ void main_1() {
color = x_725;
const float2 x_432 = float2(x_431.y, x_431.y);
const QuicksortObject x_726 = obj;
const int tint_symbol_90[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_90[10] = (int[10])0;
const QuicksortObject tint_symbol_91 = {tint_symbol_90};
obj = tint_symbol_91;
obj = x_726;
}
const QuicksortObject x_756 = obj;
const int tint_symbol_92[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_92[10] = (int[10])0;
const QuicksortObject tint_symbol_93 = {tint_symbol_92};
obj = tint_symbol_93;
obj = x_756;
@ -935,7 +935,7 @@ void main_1() {
i_2 = x_757;
quicksort_();
const QuicksortObject x_758 = obj;
const int tint_symbol_94[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_94[10] = (int[10])0;
const QuicksortObject tint_symbol_95 = {tint_symbol_94};
obj = tint_symbol_95;
obj = x_758;
@ -950,7 +950,7 @@ void main_1() {
const float2 x_185 = float2(x_184.x, x_184.y);
const float3 x_448 = float3(x_185.y, x_446.y, x_446.y);
const QuicksortObject x_761 = obj;
const int tint_symbol_96[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_96[10] = (int[10])0;
const QuicksortObject tint_symbol_97 = {tint_symbol_96};
obj = tint_symbol_97;
obj = x_761;
@ -959,7 +959,7 @@ void main_1() {
uv = x_762;
const float2 x_191 = asfloat(x_188[0].xy);
const QuicksortObject x_763 = obj;
const int tint_symbol_98[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_98[10] = (int[10])0;
const QuicksortObject tint_symbol_99 = {tint_symbol_98};
obj = tint_symbol_99;
obj = x_763;
@ -969,7 +969,7 @@ void main_1() {
color = x_764;
const float2 x_192 = (x_185 / x_191);
const QuicksortObject x_765 = obj;
const int tint_symbol_100[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_100[10] = (int[10])0;
const QuicksortObject tint_symbol_101 = {tint_symbol_100};
obj = tint_symbol_101;
obj = x_765;
@ -987,7 +987,7 @@ void main_1() {
color = x_768;
const float3 x_451 = float3(x_185.x, x_185.y, x_446.y);
const QuicksortObject x_769 = obj;
const int tint_symbol_102[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_102[10] = (int[10])0;
const QuicksortObject tint_symbol_103 = {tint_symbol_102};
obj = tint_symbol_103;
obj = x_769;
@ -996,7 +996,7 @@ void main_1() {
obj.numbers[0u] = x_770;
const int x_201 = obj.numbers[0u];
const QuicksortObject x_771 = obj;
const int tint_symbol_104[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_104[10] = (int[10])0;
const QuicksortObject tint_symbol_105 = {tint_symbol_104};
obj = tint_symbol_105;
obj = x_771;
@ -1012,7 +1012,7 @@ void main_1() {
i_2 = 0;
i_2 = x_774;
const QuicksortObject x_775 = obj;
const int tint_symbol_106[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_106[10] = (int[10])0;
const QuicksortObject tint_symbol_107 = {tint_symbol_106};
obj = tint_symbol_107;
obj = x_775;
@ -1031,7 +1031,7 @@ void main_1() {
uv.x = 0.0f;
uv.x = x_778;
const QuicksortObject x_779 = obj;
const int tint_symbol_108[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_108[10] = (int[10])0;
const QuicksortObject tint_symbol_109 = {tint_symbol_108};
obj = tint_symbol_109;
obj = x_779;
@ -1048,7 +1048,7 @@ void main_1() {
uv.x = x_782;
const int x_216 = obj.numbers[1];
const QuicksortObject x_783 = obj;
const int tint_symbol_110[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_110[10] = (int[10])0;
const QuicksortObject tint_symbol_111 = {tint_symbol_110};
obj = tint_symbol_111;
obj = x_783;
@ -1057,7 +1057,7 @@ void main_1() {
uv = (0.0f).xx;
uv = x_784;
const QuicksortObject x_785 = obj;
const int tint_symbol_112[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_112[10] = (int[10])0;
const QuicksortObject tint_symbol_113 = {tint_symbol_112};
obj = tint_symbol_113;
obj = x_785;
@ -1177,7 +1177,7 @@ void main_1() {
color.x = 0.0f;
color.x = x_816;
const QuicksortObject x_817 = obj;
const int tint_symbol_114[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_114[10] = (int[10])0;
const QuicksortObject tint_symbol_115 = {tint_symbol_114};
obj = tint_symbol_115;
obj = x_817;
@ -1288,7 +1288,7 @@ void main_1() {
uv[0] = x_844;
const float3 x_482 = float3(x_455.x, x_475.y, x_455.y);
const QuicksortObject x_845 = obj;
const int tint_symbol_116[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_116[10] = (int[10])0;
const QuicksortObject tint_symbol_117 = {tint_symbol_116};
obj = tint_symbol_117;
obj = x_845;
@ -1361,7 +1361,7 @@ void main_1() {
obj.numbers[6u] = x_863;
const float2 x_490 = float2(x_480.z, x_480.z);
const QuicksortObject x_864 = obj;
const int tint_symbol_118[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_118[10] = (int[10])0;
const QuicksortObject tint_symbol_119 = {tint_symbol_118};
obj = tint_symbol_119;
obj = x_864;
@ -1380,7 +1380,7 @@ void main_1() {
color.x = x_867;
const float x_287 = uv.y;
const QuicksortObject x_868 = obj;
const int tint_symbol_120[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_120[10] = (int[10])0;
const QuicksortObject tint_symbol_121 = {tint_symbol_120};
obj = tint_symbol_121;
obj = x_868;
@ -1542,7 +1542,7 @@ void main_1() {
uv.x = 0.0f;
uv.x = x_910;
const QuicksortObject x_911 = obj;
const int tint_symbol_122[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_122[10] = (int[10])0;
const QuicksortObject tint_symbol_123 = {tint_symbol_122};
obj = tint_symbol_123;
obj = x_911;
@ -1596,12 +1596,12 @@ void main_1() {
uv.x = 0.0f;
uv.x = x_923;
const QuicksortObject x_924 = obj;
const int tint_symbol_124[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_124[10] = (int[10])0;
const QuicksortObject tint_symbol_125 = {tint_symbol_124};
obj = tint_symbol_125;
obj = x_924;
const QuicksortObject x_925 = obj;
const int tint_symbol_126[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_126[10] = (int[10])0;
const QuicksortObject tint_symbol_127 = {tint_symbol_126};
obj = tint_symbol_127;
obj = x_925;
@ -1622,7 +1622,7 @@ void main_1() {
uv.x = x_929;
x_GLF_color = x_330;
const QuicksortObject x_930 = obj;
const int tint_symbol_128[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const int tint_symbol_128[10] = (int[10])0;
const QuicksortObject tint_symbol_129 = {tint_symbol_128};
obj = tint_symbol_129;
obj = x_930;

View File

@ -70,7 +70,7 @@ void swap_i1_i1_(thread int* const i, thread int* const j, thread QuicksortObjec
int const x_34_save = x_33;
int const x_35 = (*(tint_symbol_81)).numbers[x_34_save];
QuicksortObject const x_943 = *(tint_symbol_81);
tint_array<int, 10> const tint_symbol_2 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_2 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_3 = {.numbers=tint_symbol_2};
*(tint_symbol_81) = tint_symbol_3;
*(tint_symbol_81) = x_943;
@ -79,7 +79,7 @@ void swap_i1_i1_(thread int* const i, thread int* const j, thread QuicksortObjec
float3 const x_528 = float3(x_524[0], x_524[2], x_524[0]);
(*(tint_symbol_81)).numbers[x_36_save] = x_35;
QuicksortObject const x_944 = *(tint_symbol_81);
tint_array<int, 10> const tint_symbol_4 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_4 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_5 = {.numbers=tint_symbol_4};
*(tint_symbol_81) = tint_symbol_5;
*(tint_symbol_81) = x_944;
@ -104,7 +104,7 @@ void swap_i1_i1_(thread int* const i, thread int* const j, thread QuicksortObjec
(*(tint_symbol_81)).numbers[x_36_save] = 0;
(*(tint_symbol_81)).numbers[x_36_save] = x_949;
QuicksortObject const x_950 = *(tint_symbol_81);
tint_array<int, 10> const tint_symbol_6 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_6 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_7 = {.numbers=tint_symbol_6};
*(tint_symbol_81) = tint_symbol_7;
*(tint_symbol_81) = x_950;
@ -162,7 +162,7 @@ int performPartition_i1_i1_(thread int* const l, thread int* const h, thread Qui
float3 const x_536 = float3(x_534[0], x_534[2], x_535[0]);
j_1 = 10;
QuicksortObject const x_960 = *(tint_symbol_82);
tint_array<int, 10> const tint_symbol_8 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_8 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_9 = {.numbers=tint_symbol_8};
*(tint_symbol_82) = tint_symbol_9;
*(tint_symbol_82) = x_960;
@ -179,7 +179,7 @@ int performPartition_i1_i1_(thread int* const l, thread int* const h, thread Qui
pivot = x_963;
x_537 = float2(float3(1.0f, 2.0f, 3.0f)[1], float3(1.0f, 2.0f, 3.0f)[2]);
QuicksortObject const x_964 = *(tint_symbol_82);
tint_array<int, 10> const tint_symbol_10 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_10 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_11 = {.numbers=tint_symbol_10};
*(tint_symbol_82) = tint_symbol_11;
*(tint_symbol_82) = x_964;
@ -215,7 +215,7 @@ int performPartition_i1_i1_(thread int* const l, thread int* const h, thread Qui
param_1 = x_971;
int const x_62 = (*(tint_symbol_82)).numbers[x_61_save];
QuicksortObject const x_972 = *(tint_symbol_82);
tint_array<int, 10> const tint_symbol_12 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_12 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_13 = {.numbers=tint_symbol_12};
*(tint_symbol_82) = tint_symbol_13;
*(tint_symbol_82) = x_972;
@ -276,7 +276,7 @@ int performPartition_i1_i1_(thread int* const l, thread int* const h, thread Qui
param_1 = x_985;
}
QuicksortObject const x_986 = *(tint_symbol_82);
tint_array<int, 10> const tint_symbol_14 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_14 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_15 = {.numbers=tint_symbol_14};
*(tint_symbol_82) = tint_symbol_15;
*(tint_symbol_82) = x_986;
@ -311,7 +311,7 @@ int performPartition_i1_i1_(thread int* const l, thread int* const h, thread Qui
(*(tint_symbol_82)).numbers[x_42_save] = x_993;
float2 const x_549 = float2(x_534[0], x_534[1]);
QuicksortObject const x_994 = *(tint_symbol_82);
tint_array<int, 10> const tint_symbol_16 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_16 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_17 = {.numbers=tint_symbol_16};
*(tint_symbol_82) = tint_symbol_17;
*(tint_symbol_82) = x_994;
@ -381,7 +381,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
param_5 = x_1007;
h_1 = 9;
tint_array<int, 10> const x_1008 = stack;
tint_array<int, 10> const tint_symbol_18 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_18 = tint_array<int, 10>{};
stack = tint_symbol_18;
stack = x_1008;
float2 const x_556 = float2(float3(1.0f, 2.0f, 3.0f)[1], float3(1.0f, 2.0f, 3.0f)[1]);
@ -415,14 +415,14 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
param_4 = x_1015;
int const x_95 = l_1;
QuicksortObject const x_1016 = *(tint_symbol_83);
tint_array<int, 10> const tint_symbol_19 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_19 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_20 = {.numbers=tint_symbol_19};
*(tint_symbol_83) = tint_symbol_20;
*(tint_symbol_83) = x_1016;
float3 const x_560 = float3(x_559[1], x_559[0], x_557[0]);
int const x_96_save = x_94;
tint_array<int, 10> const x_1017 = stack;
tint_array<int, 10> const tint_symbol_21 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_21 = tint_array<int, 10>{};
stack = tint_symbol_21;
stack = x_1017;
float3 const x_561 = float3(x_556[1], x_556[1], x_556[1]);
@ -473,12 +473,12 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
h_1 = 0;
h_1 = x_1028;
tint_array<int, 10> const x_1029 = stack;
tint_array<int, 10> const tint_symbol_22 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_22 = tint_array<int, 10>{};
stack = tint_symbol_22;
stack = x_1029;
int const x_106 = top;
tint_array<int, 10> const x_1030 = stack;
tint_array<int, 10> const tint_symbol_23 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_23 = tint_array<int, 10>{};
stack = tint_symbol_23;
stack = x_1030;
float2 const x_567 = float2(x_558[0], x_564[2]);
@ -490,7 +490,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
break;
}
QuicksortObject const x_1032 = *(tint_symbol_83);
tint_array<int, 10> const tint_symbol_24 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_24 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_25 = {.numbers=tint_symbol_24};
*(tint_symbol_83) = tint_symbol_25;
*(tint_symbol_83) = x_1032;
@ -517,7 +517,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
stack[x_96_save] = x_1037;
int const x_111 = stack[x_110_save];
tint_array<int, 10> const x_1038 = stack;
tint_array<int, 10> const tint_symbol_26 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_26 = tint_array<int, 10>{};
stack = tint_symbol_26;
stack = x_1038;
float3 const x_571 = float3(x_559[1], x_559[0], x_564[1]);
@ -526,7 +526,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
l_1 = x_1039;
h_1 = x_111;
tint_array<int, 10> const x_1040 = stack;
tint_array<int, 10> const tint_symbol_27 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_27 = tint_array<int, 10>{};
stack = tint_symbol_27;
stack = x_1040;
float2 const x_572 = float2(x_562[1], x_561[1]);
@ -619,7 +619,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
stack[x_100_save] = 0;
stack[x_100_save] = x_1061;
tint_array<int, 10> const x_1062 = stack;
tint_array<int, 10> const tint_symbol_28 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_28 = tint_array<int, 10>{};
stack = tint_symbol_28;
stack = x_1062;
float2 const x_584 = float2(x_569[2], x_569[1]);
@ -659,7 +659,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
h_1 = x_1070;
top = x_133;
tint_array<int, 10> const x_1071 = stack;
tint_array<int, 10> const tint_symbol_29 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_29 = tint_array<int, 10>{};
stack = tint_symbol_29;
stack = x_1071;
int const x_134 = p;
@ -685,7 +685,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
stack[x_96_save] = x_1076;
float2 const x_592 = float2(float3(1.0f, 2.0f, 3.0f)[0], float3(1.0f, 2.0f, 3.0f)[1]);
QuicksortObject const x_1077 = *(tint_symbol_83);
tint_array<int, 10> const tint_symbol_30 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_30 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_31 = {.numbers=tint_symbol_30};
*(tint_symbol_83) = tint_symbol_31;
*(tint_symbol_83) = x_1077;
@ -752,7 +752,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
float2 const x_601 = float2(x_563[0], x_563[1]);
stack[x_147_save] = as_type<int>((1u + as_type<uint>(x_145)));
tint_array<int, 10> const x_1093 = stack;
tint_array<int, 10> const tint_symbol_32 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_32 = tint_array<int, 10>{};
stack = tint_symbol_32;
stack = x_1093;
int const x_148 = top;
@ -761,7 +761,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
stack[x_114_save] = x_1094;
float2 const x_602 = float2(x_565[1], x_599[1]);
tint_array<int, 10> const x_1095 = stack;
tint_array<int, 10> const tint_symbol_33 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_33 = tint_array<int, 10>{};
stack = tint_symbol_33;
stack = x_1095;
int const x_149 = as_type<int>((as_type<uint>(x_148) + as_type<uint>(as_type<int>(1u))));
@ -797,7 +797,7 @@ void quicksort_(thread QuicksortObject* const tint_symbol_83) {
l_1 = x_1103;
float2 const x_604 = float2(x_563[2], x_564[0]);
QuicksortObject const x_1104 = *(tint_symbol_83);
tint_array<int, 10> const tint_symbol_34 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_34 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_35 = {.numbers=tint_symbol_34};
*(tint_symbol_83) = tint_symbol_35;
*(tint_symbol_83) = x_1104;
@ -818,13 +818,13 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv = x_717;
i_2 = 0;
QuicksortObject const x_721 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_36 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_36 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_37 = {.numbers=tint_symbol_36};
*(tint_symbol_84) = tint_symbol_37;
*(tint_symbol_84) = x_721;
if (true) {
QuicksortObject const x_722 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_38 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_38 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_39 = {.numbers=tint_symbol_38};
*(tint_symbol_84) = tint_symbol_39;
*(tint_symbol_84) = x_722;
@ -838,13 +838,13 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
color = x_725;
float2 const x_432 = float2(x_431[1], x_431[1]);
QuicksortObject const x_726 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_40 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_40 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_41 = {.numbers=tint_symbol_40};
*(tint_symbol_84) = tint_symbol_41;
*(tint_symbol_84) = x_726;
}
QuicksortObject const x_756 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_42 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_42 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_43 = {.numbers=tint_symbol_42};
*(tint_symbol_84) = tint_symbol_43;
*(tint_symbol_84) = x_756;
@ -854,7 +854,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
i_2 = x_757;
quicksort_(tint_symbol_84);
QuicksortObject const x_758 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_44 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_44 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_45 = {.numbers=tint_symbol_44};
*(tint_symbol_84) = tint_symbol_45;
*(tint_symbol_84) = x_758;
@ -869,7 +869,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
float2 const x_185 = float2(x_184[0], x_184[1]);
float3 const x_448 = float3(x_185[1], x_446[1], x_446[1]);
QuicksortObject const x_761 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_46 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_46 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_47 = {.numbers=tint_symbol_46};
*(tint_symbol_84) = tint_symbol_47;
*(tint_symbol_84) = x_761;
@ -878,7 +878,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv = x_762;
float2 const x_191 = (*(tint_symbol_86)).resolution;
QuicksortObject const x_763 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_48 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_48 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_49 = {.numbers=tint_symbol_48};
*(tint_symbol_84) = tint_symbol_49;
*(tint_symbol_84) = x_763;
@ -888,7 +888,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
color = x_764;
float2 const x_192 = (x_185 / x_191);
QuicksortObject const x_765 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_50 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_50 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_51 = {.numbers=tint_symbol_50};
*(tint_symbol_84) = tint_symbol_51;
*(tint_symbol_84) = x_765;
@ -906,7 +906,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
color = x_768;
float3 const x_451 = float3(x_185[0], x_185[1], x_446[1]);
QuicksortObject const x_769 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_52 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_52 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_53 = {.numbers=tint_symbol_52};
*(tint_symbol_84) = tint_symbol_53;
*(tint_symbol_84) = x_769;
@ -915,7 +915,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
(*(tint_symbol_84)).numbers[0u] = x_770;
int const x_201 = (*(tint_symbol_84)).numbers[0u];
QuicksortObject const x_771 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_54 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_54 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_55 = {.numbers=tint_symbol_54};
*(tint_symbol_84) = tint_symbol_55;
*(tint_symbol_84) = x_771;
@ -931,7 +931,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
i_2 = 0;
i_2 = x_774;
QuicksortObject const x_775 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_56 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_56 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_57 = {.numbers=tint_symbol_56};
*(tint_symbol_84) = tint_symbol_57;
*(tint_symbol_84) = x_775;
@ -950,7 +950,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv[0] = 0.0f;
uv[0] = x_778;
QuicksortObject const x_779 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_58 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_58 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_59 = {.numbers=tint_symbol_58};
*(tint_symbol_84) = tint_symbol_59;
*(tint_symbol_84) = x_779;
@ -967,7 +967,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv[0] = x_782;
int const x_216 = (*(tint_symbol_84)).numbers[1];
QuicksortObject const x_783 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_60 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_60 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_61 = {.numbers=tint_symbol_60};
*(tint_symbol_84) = tint_symbol_61;
*(tint_symbol_84) = x_783;
@ -976,7 +976,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv = float2(0.0f);
uv = x_784;
QuicksortObject const x_785 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_62 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_62 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_63 = {.numbers=tint_symbol_62};
*(tint_symbol_84) = tint_symbol_63;
*(tint_symbol_84) = x_785;
@ -1096,7 +1096,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
color[0] = 0.0f;
color[0] = x_816;
QuicksortObject const x_817 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_64 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_64 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_65 = {.numbers=tint_symbol_64};
*(tint_symbol_84) = tint_symbol_65;
*(tint_symbol_84) = x_817;
@ -1207,7 +1207,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv[0] = x_844;
float3 const x_482 = float3(x_455[0], x_475[1], x_455[1]);
QuicksortObject const x_845 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_66 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_66 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_67 = {.numbers=tint_symbol_66};
*(tint_symbol_84) = tint_symbol_67;
*(tint_symbol_84) = x_845;
@ -1280,7 +1280,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
(*(tint_symbol_84)).numbers[6u] = x_863;
float2 const x_490 = float2(x_480[2], x_480[2]);
QuicksortObject const x_864 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_68 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_68 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_69 = {.numbers=tint_symbol_68};
*(tint_symbol_84) = tint_symbol_69;
*(tint_symbol_84) = x_864;
@ -1299,7 +1299,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
color[0] = x_867;
float const x_287 = uv[1];
QuicksortObject const x_868 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_70 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_70 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_71 = {.numbers=tint_symbol_70};
*(tint_symbol_84) = tint_symbol_71;
*(tint_symbol_84) = x_868;
@ -1461,7 +1461,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv[0] = 0.0f;
uv[0] = x_910;
QuicksortObject const x_911 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_72 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_72 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_73 = {.numbers=tint_symbol_72};
*(tint_symbol_84) = tint_symbol_73;
*(tint_symbol_84) = x_911;
@ -1515,12 +1515,12 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv[0] = 0.0f;
uv[0] = x_923;
QuicksortObject const x_924 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_74 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_74 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_75 = {.numbers=tint_symbol_74};
*(tint_symbol_84) = tint_symbol_75;
*(tint_symbol_84) = x_924;
QuicksortObject const x_925 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_76 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_76 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_77 = {.numbers=tint_symbol_76};
*(tint_symbol_84) = tint_symbol_77;
*(tint_symbol_84) = x_925;
@ -1541,7 +1541,7 @@ void main_1(thread QuicksortObject* const tint_symbol_84, thread float4* const t
uv[0] = x_929;
*(tint_symbol_87) = x_330;
QuicksortObject const x_930 = *(tint_symbol_84);
tint_array<int, 10> const tint_symbol_78 = tint_array<int, 10>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
tint_array<int, 10> const tint_symbol_78 = tint_array<int, 10>{};
QuicksortObject const tint_symbol_79 = {.numbers=tint_symbol_78};
*(tint_symbol_84) = tint_symbol_79;
*(tint_symbol_84) = x_930;

View File

@ -4,7 +4,7 @@ void tint_symbol() {
int zero[2][3] = int[2][3](int[3](0, 0, 0), int[3](0, 0, 0));
int tint_symbol_1[3] = int[3](1, 2, 3);
int tint_symbol_2[3] = int[3](4, 5, 6);
int init[2][3] = int[2][3](tint_symbol_1, tint_symbol_2);
int init[2][3] = int[2][3](int[3](1, 2, 3), int[3](4, 5, 6));
}
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

View File

@ -3,6 +3,6 @@ void main() {
int zero[2][3] = (int[2][3])0;
const int tint_symbol[3] = {1, 2, 3};
const int tint_symbol_1[3] = {4, 5, 6};
int init[2][3] = {tint_symbol, tint_symbol_1};
int init[2][3] = {{1, 2, 3}, {4, 5, 6}};
return;
}

View File

@ -18,7 +18,7 @@ kernel void tint_symbol() {
tint_array<tint_array<int, 3>, 2> zero = {};
tint_array<int, 3> const tint_symbol_1 = tint_array<int, 3>{1, 2, 3};
tint_array<int, 3> const tint_symbol_2 = tint_array<int, 3>{4, 5, 6};
tint_array<tint_array<int, 3>, 2> init = tint_array<tint_array<int, 3>, 2>{tint_symbol_1, tint_symbol_2};
tint_array<tint_array<int, 3>, 2> init = tint_array<tint_array<int, 3>, 2>{tint_array<int, 3>{1, 2, 3}, tint_array<int, 3>{4, 5, 6}};
return;
}