[spirv-reader] Support null vector, matrix, arr, struct
Bug: tint:3 Change-Id: I2fa25e5d28b965de4a419719e37bc999be8489ea Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/21581 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
b275fd2f0e
commit
1bbc1cb2c1
|
@ -914,11 +914,87 @@ TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
|
||||||
return {ast_type, std::make_unique<ast::TypeConstructorExpression>(
|
return {ast_type, std::make_unique<ast::TypeConstructorExpression>(
|
||||||
ast_type, std::move(ast_components))};
|
ast_type, std::move(ast_components))};
|
||||||
}
|
}
|
||||||
|
auto* spirv_null_const = spirv_const->AsNullConstant();
|
||||||
|
if (spirv_null_const != nullptr) {
|
||||||
|
return {ast_type, MakeNullValue(ast_type)};
|
||||||
|
}
|
||||||
Fail() << "Unhandled constant type " << inst->type_id() << " for value ID "
|
Fail() << "Unhandled constant type " << inst->type_id() << " for value ID "
|
||||||
<< id;
|
<< id;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ast::Expression> ParserImpl::MakeNullValue(
|
||||||
|
ast::type::Type* type) {
|
||||||
|
// TODO(dneto): Use the no-operands constructor syntax when it becomes
|
||||||
|
// available in Tint.
|
||||||
|
// https://github.com/gpuweb/gpuweb/issues/685
|
||||||
|
// https://bugs.chromium.org/p/tint/issues/detail?id=34
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
Fail() << "trying to create null value for a null type";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->IsBool()) {
|
||||||
|
return std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
|
std::make_unique<ast::BoolLiteral>(type, false));
|
||||||
|
}
|
||||||
|
if (type->IsU32()) {
|
||||||
|
return std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
|
std::make_unique<ast::UintLiteral>(type, 0u));
|
||||||
|
}
|
||||||
|
if (type->IsI32()) {
|
||||||
|
return std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
|
std::make_unique<ast::IntLiteral>(type, 0));
|
||||||
|
}
|
||||||
|
if (type->IsF32()) {
|
||||||
|
return std::make_unique<ast::ScalarConstructorExpression>(
|
||||||
|
std::make_unique<ast::FloatLiteral>(type, 0.0f));
|
||||||
|
}
|
||||||
|
if (type->IsVector()) {
|
||||||
|
const auto* vec_ty = type->AsVector();
|
||||||
|
ast::ExpressionList ast_components;
|
||||||
|
for (size_t i = 0; i < vec_ty->size(); ++i) {
|
||||||
|
ast_components.emplace_back(MakeNullValue(vec_ty->type()));
|
||||||
|
}
|
||||||
|
return std::make_unique<ast::TypeConstructorExpression>(
|
||||||
|
type, std::move(ast_components));
|
||||||
|
}
|
||||||
|
if (type->IsMatrix()) {
|
||||||
|
const auto* mat_ty = type->AsMatrix();
|
||||||
|
// Matrix components are columns
|
||||||
|
auto* column_ty =
|
||||||
|
ctx_.type_mgr().Get(std::make_unique<ast::type::VectorType>(
|
||||||
|
mat_ty->type(), mat_ty->rows()));
|
||||||
|
ast::ExpressionList ast_components;
|
||||||
|
for (size_t i = 0; i < mat_ty->columns(); ++i) {
|
||||||
|
ast_components.emplace_back(MakeNullValue(column_ty));
|
||||||
|
}
|
||||||
|
return std::make_unique<ast::TypeConstructorExpression>(
|
||||||
|
type, std::move(ast_components));
|
||||||
|
}
|
||||||
|
if (type->IsArray()) {
|
||||||
|
auto* arr_ty = type->AsArray();
|
||||||
|
ast::ExpressionList ast_components;
|
||||||
|
for (size_t i = 0; i < arr_ty->size(); ++i) {
|
||||||
|
ast_components.emplace_back(MakeNullValue(arr_ty->type()));
|
||||||
|
}
|
||||||
|
return std::make_unique<ast::TypeConstructorExpression>(
|
||||||
|
type, std::move(ast_components));
|
||||||
|
}
|
||||||
|
if (type->IsStruct()) {
|
||||||
|
auto* struct_ty = type->AsStruct();
|
||||||
|
ast::ExpressionList ast_components;
|
||||||
|
for (auto& member : struct_ty->impl()->members()) {
|
||||||
|
ast_components.emplace_back(MakeNullValue(member->type()));
|
||||||
|
}
|
||||||
|
return std::make_unique<ast::TypeConstructorExpression>(
|
||||||
|
type, std::move(ast_components));
|
||||||
|
}
|
||||||
|
Fail() << "can't make null value for type: " << type->type_name();
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
TypedExpression ParserImpl::RectifyOperandSignedness(SpvOp op,
|
TypedExpression ParserImpl::RectifyOperandSignedness(SpvOp op,
|
||||||
TypedExpression&& expr) {
|
TypedExpression&& expr) {
|
||||||
const bool requires_signed = AssumesSignedOperands(op);
|
const bool requires_signed = AssumesSignedOperands(op);
|
||||||
|
|
|
@ -244,9 +244,14 @@ class ParserImpl : Reader {
|
||||||
|
|
||||||
/// Creates an AST expression node for a SPIR-V constant.
|
/// Creates an AST expression node for a SPIR-V constant.
|
||||||
/// @param id the SPIR-V ID of the constant
|
/// @param id the SPIR-V ID of the constant
|
||||||
/// @returns a new Literal node
|
/// @returns a new expression
|
||||||
TypedExpression MakeConstantExpression(uint32_t id);
|
TypedExpression MakeConstantExpression(uint32_t id);
|
||||||
|
|
||||||
|
/// Creates an AST expression node for the null value for the given type.
|
||||||
|
/// @param type the AST type
|
||||||
|
/// @returns a new expression
|
||||||
|
std::unique_ptr<ast::Expression> MakeNullValue(ast::type::Type* type);
|
||||||
|
|
||||||
/// Converts a given expression to the signedness demanded for an operand
|
/// Converts a given expression to the signedness demanded for an operand
|
||||||
/// of the given SPIR-V opcode, if required. If the operation assumes
|
/// of the given SPIR-V opcode, if required. If the operation assumes
|
||||||
/// signed integer operands, and |expr| is unsigned, then return an
|
/// signed integer operands, and |expr| is unsigned, then return an
|
||||||
|
|
|
@ -50,6 +50,9 @@ std::string CommonTypes() {
|
||||||
%int_m1 = OpConstant %int -1
|
%int_m1 = OpConstant %int -1
|
||||||
%uint_2 = OpConstant %uint 2
|
%uint_2 = OpConstant %uint 2
|
||||||
|
|
||||||
|
%v2bool = OpTypeVector %bool 2
|
||||||
|
%v2uint = OpTypeVector %uint 2
|
||||||
|
%v2int = OpTypeVector %int 2
|
||||||
%v2float = OpTypeVector %float 2
|
%v2float = OpTypeVector %float 2
|
||||||
%m3v2float = OpTypeMatrix %v2float 3
|
%m3v2float = OpTypeMatrix %v2float 3
|
||||||
|
|
||||||
|
@ -300,6 +303,98 @@ TEST_F(SpvParserTest, ModuleScopeVar_VectorInitializer) {
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_VectorBoolNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %v2bool
|
||||||
|
%const = OpConstantNull %v2bool
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__vec_2__bool
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__bool
|
||||||
|
ScalarConstructor{false}
|
||||||
|
ScalarConstructor{false}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_VectorUintNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %v2uint
|
||||||
|
%const = OpConstantNull %v2uint
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__vec_2__u32
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__u32
|
||||||
|
ScalarConstructor{0}
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_VectorIntNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %v2int
|
||||||
|
%const = OpConstantNull %v2int
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__vec_2__i32
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__i32
|
||||||
|
ScalarConstructor{0}
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_VectorFloatNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %v2float
|
||||||
|
%const = OpConstantNull %v2float
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__vec_2__f32
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvParserTest, ModuleScopeVar_MatrixInitializer) {
|
TEST_F(SpvParserTest, ModuleScopeVar_MatrixInitializer) {
|
||||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
%ptr = OpTypePointer Private %m3v2float
|
%ptr = OpTypePointer Private %m3v2float
|
||||||
|
@ -342,6 +437,42 @@ TEST_F(SpvParserTest, ModuleScopeVar_MatrixInitializer) {
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_MatrixNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %m3v2float
|
||||||
|
%const = OpConstantNull %m3v2float
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__mat_2_3__f32
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__mat_2_3__f32
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
}
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
}
|
||||||
|
TypeConstructor{
|
||||||
|
__vec_2__f32
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvParserTest, ModuleScopeVar_ArrayInitializer) {
|
TEST_F(SpvParserTest, ModuleScopeVar_ArrayInitializer) {
|
||||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
%ptr = OpTypePointer Private %arr2uint
|
%ptr = OpTypePointer Private %arr2uint
|
||||||
|
@ -366,6 +497,29 @@ TEST_F(SpvParserTest, ModuleScopeVar_ArrayInitializer) {
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_ArrayNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %arr2uint
|
||||||
|
%const = OpConstantNull %arr2uint
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__array__u32_2
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__array__u32_2
|
||||||
|
ScalarConstructor{0}
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(SpvParserTest, ModuleScopeVar_StructInitializer) {
|
TEST_F(SpvParserTest, ModuleScopeVar_StructInitializer) {
|
||||||
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
%ptr = OpTypePointer Private %strct
|
%ptr = OpTypePointer Private %strct
|
||||||
|
@ -396,6 +550,34 @@ TEST_F(SpvParserTest, ModuleScopeVar_StructInitializer) {
|
||||||
})"));
|
})"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ModuleScopeVar_StructNullInitializer) {
|
||||||
|
auto* p = parser(test::Assemble(CommonTypes() + R"(
|
||||||
|
%ptr = OpTypePointer Private %strct
|
||||||
|
%const = OpConstantNull %strct
|
||||||
|
%200 = OpVariable %ptr Private %const
|
||||||
|
)"));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
const auto module_str = p->module().to_str();
|
||||||
|
EXPECT_THAT(module_str, HasSubstr(R"(Variable{
|
||||||
|
x_200
|
||||||
|
private
|
||||||
|
__struct_S
|
||||||
|
{
|
||||||
|
TypeConstructor{
|
||||||
|
__struct_S
|
||||||
|
ScalarConstructor{0}
|
||||||
|
ScalarConstructor{0.000000}
|
||||||
|
TypeConstructor{
|
||||||
|
__array__u32_2
|
||||||
|
ScalarConstructor{0}
|
||||||
|
ScalarConstructor{0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})"));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
|
Loading…
Reference in New Issue