diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index b307c8d887..c9861a14f5 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc @@ -122,6 +122,16 @@ void PrintF32(std::ostream& out, float value) { } } +bool PrintF16(std::ostream& out, float value) { + // Note: Currently inf and nan should not be constructable, don't emit them. + if (std::isinf(value) || std::isnan(value)) { + return false; + } else { + out << FloatToString(value) << "h"; + return true; + } +} + // Helper for writing " : register(RX, spaceY)", where R is the register, X is // the binding point binding value, and Y is the binding point group value. struct RegisterAndSpace { @@ -3122,6 +3132,13 @@ bool GeneratorImpl::EmitConstant(std::ostream& out, const sem::Constant* constan PrintF32(out, constant->As()); return true; }, + [&](const sem::F16*) { + // emit a f16 scalar with explicit float16_t type declaration. + out << "float16_t("; + bool valid = PrintF16(out, constant->As()); + out << ")"; + return valid; + }, [&](const sem::I32*) { out << constant->As(); return true; @@ -3218,6 +3235,13 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, const ast::LiteralExpression* return true; }, [&](const ast::FloatLiteralExpression* l) { + if (l->suffix == ast::FloatLiteralExpression::Suffix::kH) { + // Emit f16 literal with explicit float16_t type declaration. + out << "float16_t("; + bool valid = PrintF16(out, static_cast(l->value)); + out << ")"; + return valid; + } PrintF32(out, static_cast(l->value)); return true; }, @@ -3251,6 +3275,10 @@ bool GeneratorImpl::EmitValue(std::ostream& out, const sem::Type* type, int valu out << value << ".0f"; return true; }, + [&](const sem::F16*) { + out << "float16_t(" << value << ".0h)"; + return true; + }, [&](const sem::I32*) { out << value; return true; @@ -3723,15 +3751,23 @@ bool GeneratorImpl::EmitType(std::ostream& out, return true; }, [&](const sem::F16*) { - diagnostics_.add_error(diag::System::Writer, - "Type f16 is not completely implemented yet."); - return false; + out << "float16_t"; + return true; }, [&](const sem::I32*) { out << "int"; return true; }, [&](const sem::Matrix* mat) { + if (mat->type()->Is()) { + // Use matrix for f16 matrix + out << "matrix<"; + if (!EmitType(out, mat->type(), storage_class, access, "")) { + return false; + } + out << ", " << mat->columns() << ", " << mat->rows() << ">"; + return true; + } if (!EmitType(out, mat->type(), storage_class, access, "")) { return false; } @@ -3847,6 +3883,7 @@ bool GeneratorImpl::EmitType(std::ostream& out, } else if (vec->type()->Is() && width >= 1 && width <= 4) { out << "bool" << width; } else { + // For example, use "vector" for f16 vector. out << "vector<"; if (!EmitType(out, vec->type(), storage_class, access, "")) { return false; diff --git a/src/tint/writer/hlsl/generator_impl_constructor_test.cc b/src/tint/writer/hlsl/generator_impl_constructor_test.cc index 6a1d696fc9..f8b9357dd4 100644 --- a/src/tint/writer/hlsl/generator_impl_constructor_test.cc +++ b/src/tint/writer/hlsl/generator_impl_constructor_test.cc @@ -61,6 +61,18 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Float) { EXPECT_THAT(gen.result(), HasSubstr("1073741824.0f")); } +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_F16) { + Enable(ast::Extension::kF16); + + // Use a number close to 1<<16 but whose decimal representation ends in 0. + WrapInFunction(Expr(f16((1 << 15) - 8))); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr("float16_t(32752.0h)")); +} + TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Float) { WrapInFunction(Construct(-1.2e-5_f)); @@ -70,6 +82,17 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Float) { EXPECT_THAT(gen.result(), HasSubstr("-0.000012f")); } +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_F16) { + Enable(ast::Extension::kF16); + + WrapInFunction(Construct(-1.2e-3_h)); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr("float16_t(-0.00119972229h)")); +} + TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Bool) { WrapInFunction(Construct(true)); @@ -97,7 +120,7 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Uint) { EXPECT_THAT(gen.result(), HasSubstr("12345u")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_F32) { WrapInFunction(vec3(1_f, 2_f, 3_f)); GeneratorImpl& gen = Build(); @@ -106,7 +129,20 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec) { EXPECT_THAT(gen.result(), HasSubstr("float3(1.0f, 2.0f, 3.0f)")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_Empty) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_F16) { + Enable(ast::Extension::kF16); + + WrapInFunction(vec3(1_h, 2_h, 3_h)); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT( + gen.result(), + HasSubstr("vector(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h))")); +} + +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_Empty_F32) { WrapInFunction(vec3()); GeneratorImpl& gen = Build(); @@ -115,7 +151,18 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_Empty) { EXPECT_THAT(gen.result(), HasSubstr("0.0f).xxx")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_Float_Literal) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_Empty_F16) { + Enable(ast::Extension::kF16); + + WrapInFunction(vec3()); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr("(float16_t(0.0h)).xxx")); +} + +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_F32_Literal) { WrapInFunction(vec3(2_f)); GeneratorImpl& gen = Build(); @@ -124,7 +171,18 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_ EXPECT_THAT(gen.result(), HasSubstr("2.0f).xxx")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_Float_Var) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_F16_Literal) { + Enable(ast::Extension::kF16); + + WrapInFunction(vec3(2_h)); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr("(float16_t(2.0h)).xxx")); +} + +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_F32_Var) { auto* var = Var("v", nullptr, Expr(2_f)); auto* cast = vec3(var); WrapInFunction(var, cast); @@ -136,6 +194,20 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_ const float3 tint_symbol = float3((v).xxx);)")); } +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_F16_Var) { + Enable(ast::Extension::kF16); + + auto* var = Var("v", nullptr, Expr(2_h)); + auto* cast = vec3(var); + WrapInFunction(var, cast); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + EXPECT_THAT(gen.result(), HasSubstr(R"(float16_t v = float16_t(2.0h); + const vector tint_symbol = vector((v).xxx);)")); +} + TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_Bool_Literal) { WrapInFunction(vec3(true)); @@ -175,7 +247,7 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Vec_SingleScalar_ EXPECT_THAT(gen.result(), HasSubstr("2u).xxx")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_F32) { WrapInFunction(mat2x3(vec3(1_f, 2_f, 3_f), vec3(3_f, 4_f, 5_f))); GeneratorImpl& gen = Build(); @@ -186,7 +258,22 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat) { HasSubstr("float2x3(float3(1.0f, 2.0f, 3.0f), float3(3.0f, 4.0f, 5.0f))")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Complex) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_F16) { + Enable(ast::Extension::kF16); + + WrapInFunction(mat2x3(vec3(1_h, 2_h, 3_h), vec3(3_h, 4_h, 5_h))); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + + EXPECT_THAT(gen.result(), + HasSubstr("matrix(vector(float16_t(1.0h), " + "float16_t(2.0h), float16_t(3.0h)), vector(float16_t(3.0h), float16_t(4.0h), float16_t(5.0h)))")); +} + +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Complex_F32) { // mat4x4( // vec4(2.0f, 3.0f, 4.0f, 8.0f), // vec4(), @@ -213,7 +300,40 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Complex) { "(7.0f).xxxx, float4(42.0f, 21.0f, 6.0f, -5.0f))")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Empty) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Complex_F16) { + // mat4x4( + // vec4(2.0h, 3.0h, 4.0h, 8.0h), + // vec4(), + // vec4(7.0h), + // vec4(vec4(42.0h, 21.0h, 6.0h, -5.0h)), + // ); + Enable(ast::Extension::kF16); + + auto* vector_literal = + vec4(Expr(f16(2.0)), Expr(f16(3.0)), Expr(f16(4.0)), Expr(f16(8.0))); + auto* vector_zero_ctor = vec4(); + auto* vector_single_scalar_ctor = vec4(Expr(f16(7.0))); + auto* vector_identical_ctor = + vec4(vec4(Expr(f16(42.0)), Expr(f16(21.0)), Expr(f16(6.0)), Expr(f16(-5.0)))); + + auto* constructor = mat4x4(vector_literal, vector_zero_ctor, vector_single_scalar_ctor, + vector_identical_ctor); + + WrapInFunction(constructor); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + + EXPECT_THAT(gen.result(), HasSubstr("matrix(" + "vector(float16_t(2.0h), float16_t(3.0h), " + "float16_t(4.0h), float16_t(8.0h)), " + "(float16_t(0.0h)).xxxx, (float16_t(7.0h)).xxxx, " + "vector(float16_t(42.0h), float16_t(21.0h), " + "float16_t(6.0h), float16_t(-5.0h)))")); +} + +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Empty_F32) { WrapInFunction(mat2x3()); GeneratorImpl& gen = Build(); @@ -223,7 +343,20 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Empty) { EXPECT_THAT(gen.result(), HasSubstr("float2x3 tint_symbol = float2x3((0.0f).xxx, (0.0f).xxx)")); } -TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Identity) { +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Empty_F16) { + Enable(ast::Extension::kF16); + + WrapInFunction(mat2x3()); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + + EXPECT_THAT(gen.result(), + HasSubstr("matrix((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx)")); +} + +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Identity_F32) { // fn f() { // var m_1: mat4x4 = mat4x4(); // var m_2: mat4x4 = mat4x4(m_1); @@ -241,6 +374,27 @@ TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Identity) { EXPECT_THAT(gen.result(), HasSubstr("float4x4 m_2 = float4x4(m_1);")); } +TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Mat_Identity_F16) { + // fn f() { + // var m_1: mat4x4 = mat4x4(); + // var m_2: mat4x4 = mat4x4(m_1); + // } + + Enable(ast::Extension::kF16); + + auto* m_1 = Var("m_1", ty.mat4x4(ty.f16()), mat4x4()); + auto* m_2 = Var("m_2", ty.mat4x4(ty.f16()), mat4x4(m_1)); + + WrapInFunction(m_1, m_2); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.Generate()) << gen.error(); + + EXPECT_THAT(gen.result(), + HasSubstr("matrix m_2 = matrix(m_1);")); +} + TEST_F(HlslGeneratorImplTest_Constructor, EmitConstructor_Type_Array) { WrapInFunction(Construct(ty.array(ty.vec3(), 3_u), vec3(1_f, 2_f, 3_f), vec3(4_f, 5_f, 6_f), vec3(7_f, 8_f, 9_f))); diff --git a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc index 3a988a0325..d5dee6faf4 100644 --- a/src/tint/writer/hlsl/generator_impl_module_constant_test.cc +++ b/src/tint/writer/hlsl/generator_impl_module_constant_test.cc @@ -92,6 +92,22 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f32) { )"); } +TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_f16) { + Enable(ast::Extension::kF16); + + auto* var = GlobalConst("G", nullptr, Expr(1_h)); + 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 float16_t l = float16_t(1.0h); +} +)"); +} + 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)))}); @@ -134,6 +150,22 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f32) { )"); } +TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_vec3_f16) { + Enable(ast::Extension::kF16); + + auto* var = GlobalConst("G", nullptr, vec3(1_h, 2_h, 3_h)); + 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 vector l = vector(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h)); +} +)"); +} + 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)); @@ -163,6 +195,22 @@ TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f32) { )"); } +TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_mat2x3_f16) { + Enable(ast::Extension::kF16); + + auto* var = GlobalConst("G", nullptr, mat2x3(1_h, 2_h, 3_h, 4_h, 5_h, 6_h)); + 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 matrix l = matrix(vector(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h)), vector(float16_t(4.0h), float16_t(5.0h), float16_t(6.0h))); +} +)"); +} + TEST_F(HlslGeneratorImplTest_ModuleConstant, Emit_GlobalConst_arr_f32) { auto* var = GlobalConst("G", nullptr, Construct(ty.array(), 1_f, 2_f, 3_f)); Func("f", {}, ty.void_(), {Decl(Let("l", nullptr, Expr(var)))}); diff --git a/src/tint/writer/hlsl/generator_impl_type_test.cc b/src/tint/writer/hlsl/generator_impl_type_test.cc index 614d8f1cbc..991c5c0088 100644 --- a/src/tint/writer/hlsl/generator_impl_type_test.cc +++ b/src/tint/writer/hlsl/generator_impl_type_test.cc @@ -94,6 +94,17 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_Bool) { EXPECT_EQ(out.str(), "bool"); } +TEST_F(HlslGeneratorImplTest_Type, EmitType_F16) { + auto* f16 = create(); + + GeneratorImpl& gen = Build(); + + std::stringstream out; + ASSERT_TRUE(gen.EmitType(out, f16, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) + << gen.error(); + EXPECT_EQ(out.str(), "float16_t"); +} + TEST_F(HlslGeneratorImplTest_Type, EmitType_F32) { auto* f32 = create(); @@ -116,7 +127,20 @@ TEST_F(HlslGeneratorImplTest_Type, EmitType_I32) { EXPECT_EQ(out.str(), "int"); } -TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix) { +TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix_F16) { + auto* f16 = create(); + auto* vec3 = create(f16, 3u); + auto* mat2x3 = create(vec3, 2u); + + GeneratorImpl& gen = Build(); + + std::stringstream out; + ASSERT_TRUE(gen.EmitType(out, mat2x3, ast::StorageClass::kNone, ast::Access::kReadWrite, "")) + << gen.error(); + EXPECT_EQ(out.str(), "matrix"); +} + +TEST_F(HlslGeneratorImplTest_Type, EmitType_Matrix_F32) { auto* f32 = create(); auto* vec3 = create(f32, 3u); auto* mat2x3 = create(vec3, 2u); diff --git a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc index 1e111cd8fc..9a741bc49e 100644 --- a/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc +++ b/src/tint/writer/hlsl/generator_impl_variable_decl_statement_test.cc @@ -134,6 +134,22 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f32) )"); } +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_f16) { + Enable(ast::Extension::kF16); + + auto* C = Const("C", nullptr, Expr(1_h)); + 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 float16_t l = float16_t(1.0h); +} +)"); +} + 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)))}); @@ -176,6 +192,22 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3 )"); } +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_vec3_f16) { + Enable(ast::Extension::kF16); + + auto* C = Const("C", nullptr, vec3(1_h, 2_h, 3_h)); + 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 vector l = vector(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h)); +} +)"); +} + 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)); @@ -205,6 +237,22 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2 )"); } +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_mat2x3_f16) { + Enable(ast::Extension::kF16); + + auto* C = Const("C", nullptr, mat2x3(1_h, 2_h, 3_h, 4_h, 5_h, 6_h)); + 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 matrix l = matrix(vector(float16_t(1.0h), float16_t(2.0h), float16_t(3.0h)), vector(float16_t(4.0h), float16_t(5.0h), float16_t(6.0h))); +} +)"); +} + TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Const_arr_f32) { auto* C = Const("C", nullptr, Construct(ty.array(), 1_f, 2_f, 3_f)); Func("f", {}, ty.void_(), {Decl(C), Decl(Let("l", nullptr, Expr(C)))}); @@ -263,7 +311,7 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Private) { EXPECT_THAT(gen.result(), HasSubstr(" static float a = 0.0f;\n")); } -TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroVec) { +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroVec_F32) { auto* var = Var("a", ty.vec3(), ast::StorageClass::kNone, vec3()); auto* stmt = Decl(var); @@ -276,7 +324,22 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initialize )"); } -TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroMat) { +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroVec_F16) { + Enable(ast::Extension::kF16); + + auto* var = Var("a", ty.vec3(), ast::StorageClass::kNone, vec3()); + + auto* stmt = Decl(var); + WrapInFunction(stmt); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error(); + EXPECT_EQ(gen.result(), R"(vector a = (float16_t(0.0h)).xxx; +)"); +} + +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroMat_F32) { auto* var = Var("a", ty.mat2x3(), ast::StorageClass::kNone, mat2x3()); auto* stmt = Decl(var); @@ -290,5 +353,22 @@ TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initialize )"); } +TEST_F(HlslGeneratorImplTest_VariableDecl, Emit_VariableDeclStatement_Initializer_ZeroMat_F16) { + Enable(ast::Extension::kF16); + + auto* var = Var("a", ty.mat2x3(), ast::StorageClass::kNone, mat2x3()); + + auto* stmt = Decl(var); + WrapInFunction(stmt); + + GeneratorImpl& gen = Build(); + + ASSERT_TRUE(gen.EmitStatement(stmt)) << gen.error(); + EXPECT_EQ( + gen.result(), + R"(matrix a = matrix((float16_t(0.0h)).xxx, (float16_t(0.0h)).xxx); +)"); +} + } // namespace } // namespace tint::writer::hlsl