Add support for GLSL length.

This CL adds support for the GLSL length command.

Bug: tint:5
Change-Id: I2704bc04e493fb3aef8e5cd58039b6b863cc80f8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/20001
Reviewed-by: David Neto <dneto@google.com>
This commit is contained in:
dan sinclair 2020-04-20 21:09:14 +00:00 committed by dan sinclair
parent 89af8a23cc
commit 652a4b9871
2 changed files with 104 additions and 0 deletions

View File

@ -668,6 +668,24 @@ ast::type::Type* TypeDeterminer::GetImportData(
}
return params[0]->result_type();
} else if (name == "length") {
if (params.size() != 1) {
error_ = "incorrect number of parameters for " + name +
". Expected 1 got " + std::to_string(params.size());
return nullptr;
}
if (!params[0]->result_type()->is_float_scalar_or_vector()) {
error_ = "incorrect type for " + name +
". Requires a float scalar or a float vector";
return nullptr;
}
*id = GLSLstd450Length;
auto* result_type = params[0]->result_type();
// Length returns a scalar of the same type as the parameter.
return result_type->is_float_scalar() ? result_type
: result_type->AsVector()->type();
}
return nullptr;

View File

@ -1618,5 +1618,91 @@ INSTANTIATE_TEST_SUITE_P(
GLSLData{"inversesqrt", GLSLstd450InverseSqrt},
GLSLData{"normalize", GLSLstd450Normalize}));
TEST_F(TypeDeterminerTest, ImportData_Length_Scalar) {
ast::type::F32Type f32;
ast::ExpressionList params;
params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&f32, 1.f)));
ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
uint32_t id = 0;
auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->is_float_scalar());
EXPECT_EQ(id, GLSLstd450Length);
}
TEST_F(TypeDeterminerTest, ImportData_Length_FloatVector) {
ast::type::F32Type f32;
ast::type::VectorType vec(&f32, 3);
ast::ExpressionList vals;
vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(&f32, 1.0f)));
vals.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(&f32, 3.0f)));
ast::ExpressionList params;
params.push_back(
std::make_unique<ast::TypeConstructorExpression>(&vec, std::move(vals)));
ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
uint32_t id = 0;
auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
ASSERT_NE(type, nullptr);
EXPECT_TRUE(type->is_float_scalar());
EXPECT_EQ(id, GLSLstd450Length);
}
TEST_F(TypeDeterminerTest, ImportData_Length_Error_Integer) {
ast::type::I32Type i32;
ast::ExpressionList params;
params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::IntLiteral>(&i32, 1)));
ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
uint32_t id = 0;
auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
ASSERT_EQ(type, nullptr);
EXPECT_EQ(
td()->error(),
"incorrect type for length. Requires a float scalar or a float vector");
}
TEST_F(TypeDeterminerTest, ImportData_Length_Error_NoParams) {
ast::ExpressionList params;
uint32_t id = 0;
auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
ASSERT_EQ(type, nullptr);
EXPECT_EQ(td()->error(),
"incorrect number of parameters for length. Expected 1 got 0");
}
TEST_F(TypeDeterminerTest, ImportData_Length_Error_MultipleParams) {
ast::type::F32Type f32;
ast::ExpressionList params;
params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
params.push_back(std::make_unique<ast::ScalarConstructorExpression>(
std::make_unique<ast::FloatLiteral>(&f32, 1.f)));
ASSERT_TRUE(td()->DetermineResultType(params)) << td()->error();
uint32_t id = 0;
auto* type = td()->GetImportData("GLSL.std.450", "length", params, &id);
ASSERT_EQ(type, nullptr);
EXPECT_EQ(td()->error(),
"incorrect number of parameters for length. Expected 1 got 3");
}
} // namespace
} // namespace tint