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>
This commit is contained in:
dan sinclair 2020-06-17 18:39:17 +00:00 committed by dan sinclair
parent 1650af2c86
commit 3819c260de
2 changed files with 97 additions and 1 deletions

View File

@ -64,7 +64,8 @@ namespace {
enum class GlslDataType { enum class GlslDataType {
kFloatScalarOrVector, kFloatScalarOrVector,
kIntScalarOrVector, kIntScalarOrVector,
kFloatVector kFloatVector,
kMatrix
}; };
struct GlslData { struct GlslData {
const char* name; const char* name;
@ -87,6 +88,7 @@ constexpr const GlslData kGlslData[] = {
{"cosh", 1, GLSLstd450Cosh, GlslDataType::kFloatScalarOrVector, 0}, {"cosh", 1, GLSLstd450Cosh, GlslDataType::kFloatScalarOrVector, 0},
{"cross", 2, GLSLstd450Cross, GlslDataType::kFloatVector, 3}, {"cross", 2, GLSLstd450Cross, GlslDataType::kFloatVector, 3},
{"degrees", 1, GLSLstd450Degrees, GlslDataType::kFloatScalarOrVector, 0}, {"degrees", 1, GLSLstd450Degrees, GlslDataType::kFloatScalarOrVector, 0},
{"determinant", 1, GLSLstd450Determinant, GlslDataType::kMatrix, 0},
{"distance", 2, GLSLstd450Distance, GlslDataType::kFloatScalarOrVector, 0}, {"distance", 2, GLSLstd450Distance, GlslDataType::kFloatScalarOrVector, 0},
{"exp", 1, GLSLstd450Exp, GlslDataType::kFloatScalarOrVector, 0}, {"exp", 1, GLSLstd450Exp, GlslDataType::kFloatScalarOrVector, 0},
{"exp2", 1, GLSLstd450Exp2, GlslDataType::kFloatScalarOrVector, 0}, {"exp2", 1, GLSLstd450Exp2, GlslDataType::kFloatScalarOrVector, 0},
@ -780,6 +782,13 @@ ast::type::Type* TypeDeterminer::GetImportData(
return nullptr; return nullptr;
} }
break; 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]
: result_types[0]->AsVector()->type(); : 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]; return result_types[0];
} }

View File

@ -3185,5 +3185,88 @@ INSTANTIATE_TEST_SUITE_P(TypeDeterminerTest,
GLSLData{"umax", GLSLstd450UMax}, GLSLData{"umax", GLSLstd450UMax},
GLSLData{"smax", GLSLstd450SMax})); 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
} // namespace tint } // namespace tint