[spirv-reader] Convert pointer type
Bug: tint:3 Change-Id: Ibba1472a1aa3f1399e9596ee6662a29121d88eca Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/18420 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
73e1ef825e
commit
269a2c6a91
|
@ -38,6 +38,7 @@
|
||||||
#include "src/ast/type/f32_type.h"
|
#include "src/ast/type/f32_type.h"
|
||||||
#include "src/ast/type/i32_type.h"
|
#include "src/ast/type/i32_type.h"
|
||||||
#include "src/ast/type/matrix_type.h"
|
#include "src/ast/type/matrix_type.h"
|
||||||
|
#include "src/ast/type/pointer_type.h"
|
||||||
#include "src/ast/type/struct_type.h"
|
#include "src/ast/type/struct_type.h"
|
||||||
#include "src/ast/type/type.h"
|
#include "src/ast/type/type.h"
|
||||||
#include "src/ast/type/u32_type.h"
|
#include "src/ast/type/u32_type.h"
|
||||||
|
@ -164,10 +165,10 @@ ast::type::Type* ParserImpl::ConvertType(uint32_t type_id) {
|
||||||
return save(ConvertType(spirv_type->AsArray()));
|
return save(ConvertType(spirv_type->AsArray()));
|
||||||
case spvtools::opt::analysis::Type::kStruct:
|
case spvtools::opt::analysis::Type::kStruct:
|
||||||
return save(ConvertType(spirv_type->AsStruct()));
|
return save(ConvertType(spirv_type->AsStruct()));
|
||||||
case spvtools::opt::analysis::Type::kFunction:
|
|
||||||
case spvtools::opt::analysis::Type::kPointer:
|
case spvtools::opt::analysis::Type::kPointer:
|
||||||
// For now, just return null without erroring out.
|
return save(ConvertType(spirv_type->AsPointer()));
|
||||||
// TODO(dneto)
|
case spvtools::opt::analysis::Type::kFunction:
|
||||||
|
// TODO(dneto). For now return null without erroring out.
|
||||||
return nullptr;
|
return nullptr;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -520,6 +521,27 @@ ast::type::Type* ParserImpl::ConvertType(
|
||||||
return ctx_.type_mgr().Get(std::move(ast_struct_type));
|
return ctx_.type_mgr().Get(std::move(ast_struct_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ast::type::Type* ParserImpl::ConvertType(
|
||||||
|
const spvtools::opt::analysis::Pointer* ptr_ty) {
|
||||||
|
auto* ast_elem_ty = ConvertType(type_mgr_->GetId(ptr_ty->pointee_type()));
|
||||||
|
if (ast_elem_ty == nullptr) {
|
||||||
|
Fail() << "SPIR-V pointer type with ID " << type_mgr_->GetId(ptr_ty)
|
||||||
|
<< " has invalid pointee type "
|
||||||
|
<< type_mgr_->GetId(ptr_ty->pointee_type());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto ast_storage_class =
|
||||||
|
enum_converter_.ToStorageClass(ptr_ty->storage_class());
|
||||||
|
if (ast_storage_class == ast::StorageClass::kNone) {
|
||||||
|
Fail() << "SPIR-V pointer type with ID " << type_mgr_->GetId(ptr_ty)
|
||||||
|
<< " has invalid storage class "
|
||||||
|
<< static_cast<uint32_t>(ptr_ty->storage_class());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return ctx_.type_mgr().Get(
|
||||||
|
std::make_unique<ast::type::PointerType>(ast_elem_ty, ast_storage_class));
|
||||||
|
}
|
||||||
|
|
||||||
bool ParserImpl::RegisterTypes() {
|
bool ParserImpl::RegisterTypes() {
|
||||||
if (!success_) {
|
if (!success_) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -190,6 +190,8 @@ class ParserImpl : Reader {
|
||||||
/// Converts a specific SPIR-V type to a Tint type. Struct case
|
/// Converts a specific SPIR-V type to a Tint type. Struct case
|
||||||
ast::type::Type* ConvertType(
|
ast::type::Type* ConvertType(
|
||||||
const spvtools::opt::analysis::Struct* struct_ty);
|
const spvtools::opt::analysis::Struct* struct_ty);
|
||||||
|
/// Converts a specific SPIR-V type to a Tint type. Pointer case
|
||||||
|
ast::type::Type* ConvertType(const spvtools::opt::analysis::Pointer* ptr_ty);
|
||||||
|
|
||||||
// The SPIR-V binary we're parsing
|
// The SPIR-V binary we're parsing
|
||||||
std::vector<uint32_t> spv_binary_;
|
std::vector<uint32_t> spv_binary_;
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#include "src/ast/struct.h"
|
#include "src/ast/struct.h"
|
||||||
#include "src/ast/type/array_type.h"
|
#include "src/ast/type/array_type.h"
|
||||||
#include "src/ast/type/matrix_type.h"
|
#include "src/ast/type/matrix_type.h"
|
||||||
|
#include "src/ast/type/pointer_type.h"
|
||||||
#include "src/ast/type/struct_type.h"
|
#include "src/ast/type/struct_type.h"
|
||||||
|
#include "src/ast/type/type.h"
|
||||||
#include "src/ast/type/vector_type.h"
|
#include "src/ast/type/vector_type.h"
|
||||||
#include "src/reader/spirv/parser_impl.h"
|
#include "src/reader/spirv/parser_impl.h"
|
||||||
#include "src/reader/spirv/parser_impl_test_helper.h"
|
#include "src/reader/spirv/parser_impl_test_helper.h"
|
||||||
|
@ -484,11 +486,222 @@ TEST_F(SpvParserTest, ConvertType_StructWithMemberDecorations) {
|
||||||
)"));
|
)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(dneto): Demonstrate other member deocrations. Blocked on
|
// TODO(dneto): Demonstrate other member decorations. Blocked on
|
||||||
// crbug.com/tint/30
|
// crbug.com/tint/30
|
||||||
// TODO(dneto): Demonstrate multiple member deocrations. Blocked on
|
// TODO(dneto): Demonstrate multiple member deocrations. Blocked on
|
||||||
// crbug.com/tint/30
|
// crbug.com/tint/30
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_InvalidPointeetype) {
|
||||||
|
// Disallow pointer-to-function
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%void = OpTypeVoid
|
||||||
|
%42 = OpTypeFunction %void
|
||||||
|
%3 = OpTypePointer Input %42
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule()) << p->error();
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_EQ(type, nullptr);
|
||||||
|
EXPECT_THAT(p->error(),
|
||||||
|
Eq("SPIR-V pointer type with ID 3 has invalid pointee type 42"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, DISABLED_ConvertType_InvalidStorageClass) {
|
||||||
|
// Disallow invalid storage class
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%1 = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer !999 %1 ; Special syntax to inject 999 as the storage class
|
||||||
|
)"));
|
||||||
|
// TODO(dneto): I can't get it past module building.
|
||||||
|
EXPECT_FALSE(p->BuildInternalModule()) << p->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerInput) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Input %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kInput);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerOutput) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Output %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kOutput);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerUniform) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Uniform %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kUniform);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerWorkgroup) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Workgroup %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kWorkgroup);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerUniformConstant) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer UniformConstant %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kUniformConstant);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerStorageBuffer) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer StorageBuffer %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kStorageBuffer);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerImage) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Image %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kImage);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerPushConstant) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer PushConstant %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kPushConstant);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerPrivate) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Private %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kPrivate);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerFunction) {
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%3 = OpTypePointer Function %float
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsF32());
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kFunction);
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, ConvertType_PointerToPointer) {
|
||||||
|
// FYI: The reader suports pointer-to-pointer even while WebGPU does not.
|
||||||
|
auto p = parser(test::Assemble(R"(
|
||||||
|
%float = OpTypeFloat 32
|
||||||
|
%42 = OpTypePointer Output %float
|
||||||
|
%3 = OpTypePointer Input %42
|
||||||
|
)"));
|
||||||
|
EXPECT_TRUE(p->BuildInternalModule());
|
||||||
|
|
||||||
|
auto* type = p->ConvertType(3);
|
||||||
|
EXPECT_NE(type, nullptr);
|
||||||
|
EXPECT_TRUE(type->IsPointer());
|
||||||
|
|
||||||
|
auto* ptr_ty = type->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ty, nullptr);
|
||||||
|
EXPECT_EQ(ptr_ty->storage_class(), ast::StorageClass::kInput);
|
||||||
|
EXPECT_TRUE(ptr_ty->type()->IsPointer());
|
||||||
|
|
||||||
|
auto* ptr_ptr_ty = ptr_ty->type()->AsPointer();
|
||||||
|
EXPECT_NE(ptr_ptr_ty, nullptr);
|
||||||
|
EXPECT_EQ(ptr_ptr_ty->storage_class(), ast::StorageClass::kOutput);
|
||||||
|
EXPECT_TRUE(ptr_ptr_ty->type()->IsF32());
|
||||||
|
|
||||||
|
EXPECT_TRUE(p->error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
|
Loading…
Reference in New Issue