diff --git a/src/reader/spirv/enum_converter.cc b/src/reader/spirv/enum_converter.cc index ebbde754a1..40606cf78f 100644 --- a/src/reader/spirv/enum_converter.cc +++ b/src/reader/spirv/enum_converter.cc @@ -38,6 +38,36 @@ ast::PipelineStage EnumConverter::ToPipelineStage(SpvExecutionModel model) { return ast::PipelineStage::kNone; } +ast::StorageClass EnumConverter::ToStorageClass(SpvStorageClass sc) { + switch (sc) { + case SpvStorageClassInput: + return ast::StorageClass::kInput; + case SpvStorageClassOutput: + return ast::StorageClass::kOutput; + case SpvStorageClassUniform: + return ast::StorageClass::kUniform; + case SpvStorageClassWorkgroup: + return ast::StorageClass::kWorkgroup; + case SpvStorageClassUniformConstant: + return ast::StorageClass::kUniformConstant; + case SpvStorageClassStorageBuffer: + return ast::StorageClass::kStorageBuffer; + case SpvStorageClassImage: + return ast::StorageClass::kImage; + case SpvStorageClassPushConstant: + return ast::StorageClass::kPushConstant; + case SpvStorageClassPrivate: + return ast::StorageClass::kPrivate; + case SpvStorageClassFunction: + return ast::StorageClass::kFunction; + default: + break; + } + + Fail() << "unknown SPIR-V storage class: " << uint32_t(sc); + return ast::StorageClass::kNone; +} + } // namespace spirv } // namespace reader } // namespace tint diff --git a/src/reader/spirv/enum_converter.h b/src/reader/spirv/enum_converter.h index 7014e03bb3..c910307ffe 100644 --- a/src/reader/spirv/enum_converter.h +++ b/src/reader/spirv/enum_converter.h @@ -17,6 +17,7 @@ #include "spirv/unified1/spirv.h" #include "src/ast/pipeline_stage.h" +#include "src/ast/storage_class.h" #include "src/reader/spirv/fail_stream.h" namespace tint { @@ -38,6 +39,12 @@ class EnumConverter { /// @returns a Tint AST pipeline stage ast::PipelineStage ToPipelineStage(SpvExecutionModel model); + /// Converts a SPIR-V storage class to a Tint storage class. + /// On failure, logs an error and returns kNone + /// @param sc the SPIR-V storage class + /// @returns a Tint AST pipeline stage + ast::StorageClass ToStorageClass(SpvStorageClass sc); + private: /// Registers a failure and returns a stream for log diagnostics. /// @returns a failure stream diff --git a/src/reader/spirv/enum_converter_test.cc b/src/reader/spirv/enum_converter_test.cc index b4450d651f..ee3aaa3745 100644 --- a/src/reader/spirv/enum_converter_test.cc +++ b/src/reader/spirv/enum_converter_test.cc @@ -26,6 +26,8 @@ namespace reader { namespace spirv { namespace { +// Pipeline stage + struct PipelineStageCase { SpvExecutionModel model; bool expect_success; @@ -87,6 +89,80 @@ INSTANTIATE_TEST_SUITE_P( PipelineStageCase{SpvExecutionModelTessellationControl, false, ast::PipelineStage::kNone})); +// Storage class + +struct StorageClassCase { + SpvStorageClass sc; + bool expect_success; + ast::StorageClass expected; +}; +inline std::ostream& operator<<(std::ostream& out, StorageClassCase scc) { + out << "StorageClassCase{ SpvStorageClass:" << int(scc.sc) + << " expect_success?:" << int(scc.expect_success) + << " expected:" << int(scc.expected) << "}"; + return out; +} + +class SpvStorageClassTest : public testing::TestWithParam { + public: + SpvStorageClassTest() + : success_(true), + fail_stream_(&success_, &errors_), + converter_(fail_stream_) {} + + std::string error() const { return errors_.str(); } + + protected: + bool success_ = true; + std::stringstream errors_; + FailStream fail_stream_; + EnumConverter converter_; +}; + +TEST_P(SpvStorageClassTest, Samples) { + const auto params = GetParam(); + + const auto result = converter_.ToStorageClass(params.sc); + EXPECT_EQ(success_, params.expect_success); + if (params.expect_success) { + EXPECT_EQ(result, params.expected); + EXPECT_TRUE(error().empty()); + } else { + EXPECT_EQ(result, params.expected); + EXPECT_THAT(error(), + ::testing::StartsWith("unknown SPIR-V storage class: ")); + } +} + +INSTANTIATE_TEST_SUITE_P( + EnumConverterGood, + SpvStorageClassTest, + testing::Values( + StorageClassCase{SpvStorageClassInput, true, ast::StorageClass::kInput}, + StorageClassCase{SpvStorageClassOutput, true, + ast::StorageClass::kOutput}, + StorageClassCase{SpvStorageClassUniform, true, + ast::StorageClass::kUniform}, + StorageClassCase{SpvStorageClassWorkgroup, true, + ast::StorageClass::kWorkgroup}, + StorageClassCase{SpvStorageClassUniformConstant, true, + ast::StorageClass::kUniformConstant}, + StorageClassCase{SpvStorageClassStorageBuffer, true, + ast::StorageClass::kStorageBuffer}, + StorageClassCase{SpvStorageClassImage, true, ast::StorageClass::kImage}, + StorageClassCase{SpvStorageClassPushConstant, true, + ast::StorageClass::kPushConstant}, + StorageClassCase{SpvStorageClassPrivate, true, + ast::StorageClass::kPrivate}, + StorageClassCase{SpvStorageClassFunction, true, + ast::StorageClass::kFunction})); + +INSTANTIATE_TEST_SUITE_P(EnumConverterBad, + SpvStorageClassTest, + testing::Values(StorageClassCase{ + SpvStorageClass(9999), false, + ast::StorageClass::kNone})); + } // namespace } // namespace spirv } // namespace reader