[msl-writer] Emit zero values for private, function and output vars. This CL updates the MSL writer to emit the needed zero initializers for Private, Function and Output variables. Bug: tint:172 Change-Id: I73b1c3bb4c87a8ec7b1fb9d17a35e907c9a42095 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28943 Commit-Queue: Ryan Harrison <rharrison@chromium.org> Reviewed-by: Ryan Harrison <rharrison@chromium.org>
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc index b3efd73..45773b9 100644 --- a/src/writer/msl/generator_impl.cc +++ b/src/writer/msl/generator_impl.cc
@@ -819,6 +819,16 @@ out_ << "0u"; } else if (type->IsVector()) { return EmitZeroValue(type->AsVector()->type()); + } else if (type->IsMatrix()) { + return EmitZeroValue(type->AsMatrix()->type()); + } else if (type->IsArray()) { + out_ << "{"; + if (!EmitZeroValue(type->AsArray()->type())) { + return false; + } + out_ << "}"; + } else if (type->IsStruct()) { + out_ << "{}"; } else { error_ = "Invalid type for zero emission: " + type->type_name(); return false; @@ -1805,10 +1815,19 @@ out_ << " " << var->name(); } - if (!skip_constructor && var->constructor() != nullptr) { + if (!skip_constructor) { out_ << " = "; - if (!EmitExpression(var->constructor())) { - return false; + if (var->constructor() != nullptr) { + if (!EmitExpression(var->constructor())) { + return false; + } + } else if (var->storage_class() == ast::StorageClass::kPrivate || + var->storage_class() == ast::StorageClass::kFunction || + var->storage_class() == ast::StorageClass::kNone || + var->storage_class() == ast::StorageClass::kOutput) { + if (!EmitZeroValue(var->type())) { + return false; + } } } out_ << ";" << std::endl;
diff --git a/src/writer/msl/generator_impl_variable_decl_statement_test.cc b/src/writer/msl/generator_impl_variable_decl_statement_test.cc index 8e14e4d..cda99ae 100644 --- a/src/writer/msl/generator_impl_variable_decl_statement_test.cc +++ b/src/writer/msl/generator_impl_variable_decl_statement_test.cc
@@ -18,8 +18,15 @@ #include "gtest/gtest.h" #include "src/ast/identifier_expression.h" #include "src/ast/module.h" +#include "src/ast/struct.h" +#include "src/ast/struct_decoration.h" +#include "src/ast/struct_member.h" +#include "src/ast/struct_member_decoration.h" +#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/type/array_type.h" #include "src/ast/type/f32_type.h" +#include "src/ast/type/matrix_type.h" +#include "src/ast/type/struct_type.h" #include "src/ast/type/vector_type.h" #include "src/ast/variable.h" #include "src/ast/variable_decl_statement.h" @@ -44,7 +51,7 @@ g.increment_indent(); ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); - EXPECT_EQ(g.result(), " float a;\n"); + EXPECT_EQ(g.result(), " float a = 0.0f;\n"); } TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Const) { @@ -60,7 +67,7 @@ g.increment_indent(); ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); - EXPECT_EQ(g.result(), " const float a;\n"); + EXPECT_EQ(g.result(), " const float a = 0.0f;\n"); } TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Array) { @@ -77,13 +84,27 @@ g.increment_indent(); ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); - EXPECT_EQ(g.result(), " float a[5];\n"); + EXPECT_EQ(g.result(), " float a[5] = {0.0f};\n"); } -TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Function) { +TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Struct) { ast::type::F32Type f32; - auto var = - std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &f32); + + ast::StructMemberList members; + members.push_back(std::make_unique<ast::StructMember>( + "a", &f32, ast::StructMemberDecorationList{})); + + ast::StructMemberDecorationList b_deco; + b_deco.push_back(std::make_unique<ast::StructMemberOffsetDecoration>(4)); + members.push_back( + std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco))); + + auto str = std::make_unique<ast::Struct>(); + str->set_members(std::move(members)); + + ast::type::StructType s(std::move(str)); + + auto var = std::make_unique<ast::Variable>("a", ast::StorageClass::kNone, &s); ast::VariableDeclStatement stmt(std::move(var)); @@ -92,7 +113,44 @@ g.increment_indent(); ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); - EXPECT_EQ(g.result(), " float a;\n"); + EXPECT_EQ(g.result(), R"( struct { + float a; + float b; + } a = {}; +)"); +} + +TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Vector) { + ast::type::F32Type f32; + ast::type::VectorType vec(&f32, 2); + + auto var = + std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &vec); + + ast::VariableDeclStatement stmt(std::move(var)); + + ast::Module m; + GeneratorImpl g(&m); + g.increment_indent(); + + ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); + EXPECT_EQ(g.result(), " float2 a = 0.0f;\n"); +} + +TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Matrix) { + ast::type::F32Type f32; + ast::type::MatrixType mat(&f32, 2, 3); + auto var = + std::make_unique<ast::Variable>("a", ast::StorageClass::kFunction, &mat); + + ast::VariableDeclStatement stmt(std::move(var)); + + ast::Module m; + GeneratorImpl g(&m); + g.increment_indent(); + + ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); + EXPECT_EQ(g.result(), " float3x2 a = 0.0f;\n"); } TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Private) { @@ -107,7 +165,7 @@ g.increment_indent(); ASSERT_TRUE(g.EmitStatement(&stmt)) << g.error(); - EXPECT_EQ(g.result(), " float a;\n"); + EXPECT_EQ(g.result(), " float a = 0.0f;\n"); } TEST_F(MslGeneratorImplTest, Emit_VariableDeclStatement_Initializer_Private) {