mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-06 21:25:58 +00:00
Add reader::spirv::ParserImpl::ConvertType
For now, it only handles scalar types Bug: tint:3 Change-Id: Ic20e18a4f80790e6cd10d4c06dd2abfd8f67a304 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/17700 Reviewed-by: dan sinclair <dsinclair@google.com>
This commit is contained in:
parent
69b9c1b8e0
commit
71e1d81654
@ -319,6 +319,7 @@ if(${TINT_BUILD_SPV_READER})
|
|||||||
reader/spirv/enum_converter_test.cc
|
reader/spirv/enum_converter_test.cc
|
||||||
reader/spirv/fail_stream_test.cc
|
reader/spirv/fail_stream_test.cc
|
||||||
reader/spirv/namer_test.cc
|
reader/spirv/namer_test.cc
|
||||||
|
reader/spirv/parser_impl_convert_type_test.cc
|
||||||
reader/spirv/parser_impl_entry_point_test.cc
|
reader/spirv/parser_impl_entry_point_test.cc
|
||||||
reader/spirv/parser_impl_import_test.cc
|
reader/spirv/parser_impl_import_test.cc
|
||||||
reader/spirv/parser_impl_user_name_test.cc
|
reader/spirv/parser_impl_user_name_test.cc
|
||||||
|
@ -15,13 +15,22 @@
|
|||||||
#include "src/reader/spirv/parser_impl.h"
|
#include "src/reader/spirv/parser_impl.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "source/opt/build_module.h"
|
#include "source/opt/build_module.h"
|
||||||
#include "source/opt/instruction.h"
|
#include "source/opt/instruction.h"
|
||||||
#include "source/opt/module.h"
|
#include "source/opt/module.h"
|
||||||
|
#include "source/opt/type_manager.h"
|
||||||
#include "spirv-tools/libspirv.hpp"
|
#include "spirv-tools/libspirv.hpp"
|
||||||
|
#include "src/ast/type/bool_type.h"
|
||||||
|
#include "src/ast/type/f32_type.h"
|
||||||
|
#include "src/ast/type/i32_type.h"
|
||||||
|
#include "src/ast/type/type.h"
|
||||||
|
#include "src/ast/type/u32_type.h"
|
||||||
|
#include "src/ast/type/void_type.h"
|
||||||
|
#include "src/type_manager.h"
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace reader {
|
namespace reader {
|
||||||
@ -92,6 +101,77 @@ ast::Module ParserImpl::module() {
|
|||||||
return std::move(ast_module_);
|
return std::move(ast_module_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ast::type::Type* ParserImpl::ConvertType(uint32_t type_id) {
|
||||||
|
if (!success_) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_mgr_ == nullptr) {
|
||||||
|
Fail() << "ConvertType called when the internal module has not been built.";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto where = id_to_type_.find(type_id);
|
||||||
|
if (where != id_to_type_.end()) {
|
||||||
|
return where->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* spirv_type = type_mgr_->GetType(type_id);
|
||||||
|
if (spirv_type == nullptr) {
|
||||||
|
Fail() << "ID is not a SPIR-V type: " << type_id;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ast::type::Type* result = nullptr;
|
||||||
|
TypeManager* tint_tm = TypeManager::Instance();
|
||||||
|
|
||||||
|
switch (spirv_type->kind()) {
|
||||||
|
case spvtools::opt::analysis::Type::kVoid:
|
||||||
|
result = tint_tm->Get(std::make_unique<ast::type::VoidType>());
|
||||||
|
break;
|
||||||
|
case spvtools::opt::analysis::Type::kBool:
|
||||||
|
result = tint_tm->Get(std::make_unique<ast::type::BoolType>());
|
||||||
|
break;
|
||||||
|
case spvtools::opt::analysis::Type::kInteger: {
|
||||||
|
const auto* int_ty = spirv_type->AsInteger();
|
||||||
|
if (int_ty->width() == 32) {
|
||||||
|
if (int_ty->IsSigned()) {
|
||||||
|
result = tint_tm->Get(std::make_unique<ast::type::I32Type>());
|
||||||
|
} else {
|
||||||
|
result = tint_tm->Get(std::make_unique<ast::type::U32Type>());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Fail() << "unhandled integer width: " << int_ty->width();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case spvtools::opt::analysis::Type::kFloat: {
|
||||||
|
const auto* float_ty = spirv_type->AsFloat();
|
||||||
|
if (float_ty->width() == 32) {
|
||||||
|
result = tint_tm->Get(std::make_unique<ast::type::F32Type>());
|
||||||
|
} else {
|
||||||
|
Fail() << "unhandled float width: " << float_ty->width();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// The error diagnostic will be generated below because result is still
|
||||||
|
// nullptr.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == nullptr) {
|
||||||
|
if (success_) {
|
||||||
|
// Only emit a new diagnostic if we haven't already emitted a more
|
||||||
|
// specific one.
|
||||||
|
Fail() << "unknown SPIR-V type: " << type_id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
id_to_type_[type_id] = result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool ParserImpl::BuildInternalModule() {
|
bool ParserImpl::BuildInternalModule() {
|
||||||
tools_.SetMessageConsumer(message_consumer_);
|
tools_.SetMessageConsumer(message_consumer_);
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#include "spirv-tools/libspirv.hpp"
|
#include "spirv-tools/libspirv.hpp"
|
||||||
#include "src/ast/import.h"
|
#include "src/ast/import.h"
|
||||||
#include "src/ast/module.h"
|
#include "src/ast/module.h"
|
||||||
|
#include "src/ast/type/type.h"
|
||||||
#include "src/reader/reader.h"
|
#include "src/reader/reader.h"
|
||||||
#include "src/reader/spirv/enum_converter.h"
|
#include "src/reader/spirv/enum_converter.h"
|
||||||
#include "src/reader/spirv/fail_stream.h"
|
#include "src/reader/spirv/fail_stream.h"
|
||||||
@ -82,6 +83,14 @@ class ParserImpl : Reader {
|
|||||||
return glsl_std_450_imports_;
|
return glsl_std_450_imports_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Converts a SPIR-V type to a Tint type.
|
||||||
|
/// On failure, logs an error and returns null.
|
||||||
|
/// This should only be called after the internal
|
||||||
|
/// representation of the module has been built.
|
||||||
|
/// @param type_id the SPIR-V ID of a type.
|
||||||
|
/// @returns a Tint type, or nullptr
|
||||||
|
const ast::type::Type* ConvertType(uint32_t type_id);
|
||||||
|
|
||||||
/// @returns the namer object
|
/// @returns the namer object
|
||||||
Namer& namer() { return namer_; }
|
Namer& namer() { return namer_; }
|
||||||
|
|
||||||
@ -147,6 +156,9 @@ class ParserImpl : Reader {
|
|||||||
// The set of IDs that are imports of the GLSL.std.450 extended instruction
|
// The set of IDs that are imports of the GLSL.std.450 extended instruction
|
||||||
// sets.
|
// sets.
|
||||||
std::unordered_set<uint32_t> glsl_std_450_imports_;
|
std::unordered_set<uint32_t> glsl_std_450_imports_;
|
||||||
|
|
||||||
|
// Maps a SPIR-V type ID to a Tint type.
|
||||||
|
std::unordered_map<uint32_t, const ast::type::Type*> id_to_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
|
136
src/reader/spirv/parser_impl_convert_type_test.cc
Normal file
136
src/reader/spirv/parser_impl_convert_type_test.cc
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
// Copyright 2020 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/reader/spirv/parser_impl.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
#include "src/reader/spirv/spirv_tools_helpers_test.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace reader {
|
||||||
|
namespace spirv {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using ::testing::Eq;
|
||||||
|
|
||||||
|
using SpvParserTest_ConvertType = ::testing::Test;
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, PreservesExistingFailure) {
|
||||||
|
ParserImpl p(std::vector<uint32_t>{});
|
||||||
|
p.Fail() << "boing";
|
||||||
|
const auto* type = p.ConvertType(10);
|
||||||
|
EXPECT_EQ(type, nullptr);
|
||||||
|
EXPECT_THAT(p.error(), Eq("boing"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, NotAnId) {
|
||||||
|
ParserImpl p(test::Assemble("%1 = OpExtInstImport \"GLSL.std.450\""));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule()) << p.error();
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(10);
|
||||||
|
EXPECT_EQ(type, nullptr);
|
||||||
|
EXPECT_EQ(nullptr, type);
|
||||||
|
EXPECT_THAT(p.error(), Eq("ID is not a SPIR-V type: 10"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, IdExistsButIsNotAType) {
|
||||||
|
ParserImpl p(test::Assemble("%1 = OpExtInstImport \"GLSL.std.450\""));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(1);
|
||||||
|
EXPECT_EQ(nullptr, type);
|
||||||
|
EXPECT_THAT(p.error(), Eq("ID is not a SPIR-V type: 1"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, UnhandledType) {
|
||||||
|
// Pipes are an OpenCL type. Tint doesn't support them.
|
||||||
|
ParserImpl p(test::Assemble("%70 = OpTypePipe WriteOnly"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(70);
|
||||||
|
EXPECT_EQ(nullptr, type);
|
||||||
|
EXPECT_THAT(p.error(), Eq("unknown SPIR-V type: 70"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, Void) {
|
||||||
|
ParserImpl p(test::Assemble("%1 = OpTypeVoid"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(1);
|
||||||
|
EXPECT_TRUE(type->IsVoid());
|
||||||
|
EXPECT_TRUE(p.error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, Bool) {
|
||||||
|
ParserImpl p(test::Assemble("%100 = OpTypeBool"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(100);
|
||||||
|
EXPECT_TRUE(type->IsBool());
|
||||||
|
EXPECT_TRUE(p.error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, I32) {
|
||||||
|
ParserImpl p(test::Assemble("%2 = OpTypeInt 32 1"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(2);
|
||||||
|
EXPECT_TRUE(type->IsI32());
|
||||||
|
EXPECT_TRUE(p.error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, U32) {
|
||||||
|
ParserImpl p(test::Assemble("%3 = OpTypeInt 32 0"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(3);
|
||||||
|
EXPECT_TRUE(type->IsU32());
|
||||||
|
EXPECT_TRUE(p.error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, F32) {
|
||||||
|
ParserImpl p(test::Assemble("%4 = OpTypeFloat 32"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(4);
|
||||||
|
EXPECT_TRUE(type->IsF32());
|
||||||
|
EXPECT_TRUE(p.error().empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, BadIntWidth) {
|
||||||
|
ParserImpl p(test::Assemble("%5 = OpTypeInt 17 1"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(5);
|
||||||
|
EXPECT_EQ(type, nullptr);
|
||||||
|
EXPECT_THAT(p.error(), Eq("unhandled integer width: 17"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest_ConvertType, BadFloatWidth) {
|
||||||
|
ParserImpl p(test::Assemble("%6 = OpTypeFloat 19"));
|
||||||
|
EXPECT_TRUE(p.BuildAndParseInternalModule());
|
||||||
|
|
||||||
|
const auto* type = p.ConvertType(6);
|
||||||
|
EXPECT_EQ(type, nullptr);
|
||||||
|
EXPECT_THAT(p.error(), Eq("unhandled float width: 19"));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace spirv
|
||||||
|
} // namespace reader
|
||||||
|
} // namespace tint
|
Loading…
x
Reference in New Issue
Block a user