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 <dneto@google.com>
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index d4ecc3a..bf8c00f 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -64,7 +64,8 @@
enum class GlslDataType {
kFloatScalarOrVector,
kIntScalarOrVector,
- kFloatVector
+ kFloatVector,
+ kMatrix
};
struct GlslData {
const char* name;
@@ -87,6 +88,7 @@
{"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 @@
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 @@
? 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 1587e99..8ec424f 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -3185,5 +3185,88 @@
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<ast::Variable>(
+ "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<ast::IdentifierExpression>("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<ast::Variable>(
+ "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<ast::IdentifierExpression>("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<ast::Variable>(
+ "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<ast::IdentifierExpression>("var"));
+ params.push_back(std::make_unique<ast::IdentifierExpression>("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