From 3819c260debf2720b56af8794ccc05414783936f Mon Sep 17 00:00:00 2001 From: dan sinclair Date: Wed, 17 Jun 2020 18:39:17 +0000 Subject: [PATCH] Add type determination for GLSL determinant. This CL adds the type determination code for the GLSL determinant call. Change-Id: I46bc57f4fd5f4f43021b20ee511b0b8fc809f4f8 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23360 Reviewed-by: David Neto --- src/type_determiner.cc | 15 ++++++- src/type_determiner_test.cc | 83 +++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/src/type_determiner.cc b/src/type_determiner.cc index d4ecc3aa62..bf8c00ffe1 100644 --- a/src/type_determiner.cc +++ b/src/type_determiner.cc @@ -64,7 +64,8 @@ namespace { enum class GlslDataType { kFloatScalarOrVector, kIntScalarOrVector, - kFloatVector + kFloatVector, + kMatrix }; struct GlslData { const char* name; @@ -87,6 +88,7 @@ constexpr const GlslData kGlslData[] = { {"cosh", 1, GLSLstd450Cosh, GlslDataType::kFloatScalarOrVector, 0}, {"cross", 2, GLSLstd450Cross, GlslDataType::kFloatVector, 3}, {"degrees", 1, GLSLstd450Degrees, GlslDataType::kFloatScalarOrVector, 0}, + {"determinant", 1, GLSLstd450Determinant, GlslDataType::kMatrix, 0}, {"distance", 2, GLSLstd450Distance, GlslDataType::kFloatScalarOrVector, 0}, {"exp", 1, GLSLstd450Exp, GlslDataType::kFloatScalarOrVector, 0}, {"exp2", 1, GLSLstd450Exp2, GlslDataType::kFloatScalarOrVector, 0}, @@ -780,6 +782,13 @@ ast::type::Type* TypeDeterminer::GetImportData( return nullptr; } break; + case GlslDataType::kMatrix: + if (!result_types.back()->IsMatrix()) { + set_error(source, + "incorrect type for " + name + ". Requires matrix value"); + return nullptr; + } + break; } } @@ -799,6 +808,10 @@ ast::type::Type* TypeDeterminer::GetImportData( ? result_types[0] : result_types[0]->AsVector()->type(); } + // The determinant returns the component type of the columns + if (name == "determinant") { + return result_types[0]->AsMatrix()->type(); + } return result_types[0]; } diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc index 1587e9998b..8ec424fc31 100644 --- a/src/type_determiner_test.cc +++ b/src/type_determiner_test.cc @@ -3185,5 +3185,88 @@ INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest, GLSLData{"umax", GLSLstd450UMax}, GLSLData{"smax", GLSLstd450SMax})); +TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant_Matrix) { + ast::type::F32Type f32; + ast::type::MatrixType mat(&f32, 3, 3); + + auto var = std::make_unique( + "var", ast::StorageClass::kFunction, &mat); + mod()->AddGlobalVariable(std::move(var)); + + // Register the global + ASSERT_TRUE(td()->Determine()) << td()->error(); + + ast::ExpressionList params; + params.push_back(std::make_unique("var")); + + ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error(); + + uint32_t id = 0; + auto* type = + td()->GetImportData({0, 0}, "GLSL.std.450", "determinant", params, &id); + ASSERT_NE(type, nullptr); + EXPECT_TRUE(type->IsF32()); + EXPECT_EQ(id, GLSLstd450Determinant); +} + +TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant_Error_Float) { + ast::type::F32Type f32; + + auto var = std::make_unique( + "var", ast::StorageClass::kFunction, &f32); + mod()->AddGlobalVariable(std::move(var)); + + // Register the global + ASSERT_TRUE(td()->Determine()) << td()->error(); + + ast::ExpressionList params; + params.push_back(std::make_unique("var")); + + ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error(); + + uint32_t id = 0; + auto* type = + td()->GetImportData({0, 0}, "GLSL.std.450", "determinant", params, &id); + ASSERT_EQ(type, nullptr); + EXPECT_EQ(td()->error(), + "incorrect type for determinant. Requires matrix value"); +} + +TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant_Error_NoParams) { + ast::ExpressionList params; + + uint32_t id = 0; + auto* type = + td()->GetImportData({0, 0}, "GLSL.std.450", "determinant", params, &id); + ASSERT_EQ(type, nullptr); + EXPECT_EQ(td()->error(), + "incorrect number of parameters for determinant. Expected 1 got 0"); +} + +TEST_F(TypeDeterminerTest, ImportData_GLSL_Determinant_Error_TooManyParams) { + ast::type::F32Type f32; + ast::type::MatrixType mat(&f32, 3, 3); + + auto var = std::make_unique( + "var", ast::StorageClass::kFunction, &mat); + mod()->AddGlobalVariable(std::move(var)); + + // Register the global + ASSERT_TRUE(td()->Determine()) << td()->error(); + + ast::ExpressionList params; + params.push_back(std::make_unique("var")); + params.push_back(std::make_unique("var")); + + ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error(); + + uint32_t id = 0; + auto* type = + td()->GetImportData({0, 0}, "GLSL.std.450", "determinant", params, &id); + ASSERT_EQ(type, nullptr); + EXPECT_EQ(td()->error(), + "incorrect number of parameters for determinant. Expected 1 got 2"); +} + } // namespace } // namespace tint