From 14cfcd707df16681b1dffefba360d90640298192 Mon Sep 17 00:00:00 2001 From: David Neto Date: Mon, 23 Mar 2020 22:53:42 +0000 Subject: [PATCH] Add conversion of SpvExecutionModel Bug: tint:3 Change-Id: I2b1a12beea9343ab3a8db50308e2f6fd790c654b Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/17581 Reviewed-by: dan sinclair --- src/CMakeLists.txt | 3 + src/reader/spirv/enum_converter.cc | 43 ++++++++++++ src/reader/spirv/enum_converter.h | 53 ++++++++++++++ src/reader/spirv/enum_converter_test.cc | 93 +++++++++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 src/reader/spirv/enum_converter.cc create mode 100644 src/reader/spirv/enum_converter.h create mode 100644 src/reader/spirv/enum_converter_test.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a64b78beba..0fcbb43599 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -198,6 +198,8 @@ set(TINT_LIB_SRCS if(${TINT_BUILD_SPV_READER}) list(APPEND TINT_LIB_SRCS + reader/spirv/enum_converter.h + reader/spirv/enum_converter.cc reader/spirv/fail_stream.h reader/spirv/namer.cc reader/spirv/namer.h @@ -314,6 +316,7 @@ endif() if(${TINT_BUILD_SPV_READER}) list(APPEND TINT_TEST_SRCS + reader/spirv/enum_converter_test.cc reader/spirv/fail_stream_test.cc reader/spirv/namer_test.cc reader/spirv/parser_impl_import_test.cc diff --git a/src/reader/spirv/enum_converter.cc b/src/reader/spirv/enum_converter.cc new file mode 100644 index 0000000000..ebbde754a1 --- /dev/null +++ b/src/reader/spirv/enum_converter.cc @@ -0,0 +1,43 @@ +// 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/enum_converter.h" + +namespace tint { +namespace reader { +namespace spirv { + +EnumConverter::EnumConverter(const FailStream& fs) : fail_stream_(fs) {} + +EnumConverter::~EnumConverter() = default; + +ast::PipelineStage EnumConverter::ToPipelineStage(SpvExecutionModel model) { + switch (model) { + case SpvExecutionModelVertex: + return ast::PipelineStage::kVertex; + case SpvExecutionModelFragment: + return ast::PipelineStage::kFragment; + case SpvExecutionModelGLCompute: + return ast::PipelineStage::kCompute; + default: + break; + } + + Fail() << "unknown SPIR-V execution model: " << uint32_t(model); + return ast::PipelineStage::kNone; +} + +} // namespace spirv +} // namespace reader +} // namespace tint diff --git a/src/reader/spirv/enum_converter.h b/src/reader/spirv/enum_converter.h new file mode 100644 index 0000000000..0af83127ce --- /dev/null +++ b/src/reader/spirv/enum_converter.h @@ -0,0 +1,53 @@ +// 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. + +#ifndef SRC_READER_SPIRV_ENUM_CONVERTER_H_ +#define SRC_READER_SPIRV_ENUM_CONVERTER_H_ + +#include "spirv/unified1/spirv.h" +#include "src/ast/pipeline_stage.h" +#include "src/reader/spirv/fail_stream.h" + +namespace tint { +namespace reader { +namespace spirv { + +/// A converter from SPIR-V enums to Tint AST enums. +class EnumConverter { + public: + /// Creates a new enum converter. + /// @param fail_stream the error reporting stream. + explicit EnumConverter(const FailStream& fail_stream); + /// Destructor + ~EnumConverter(); + + /// Converts a SPIR-V execution model to a Tint pipeline stage. + /// On failure, logs an error and returns kNone + /// @param model the SPIR-V entry point execution model + /// @returns a Tint AST pipeline stage + ast::PipelineStage ToPipelineStage(SpvExecutionModel model); + + private: + /// Registers a failure and returns a stream for logg diagnostics. + /// @returns a failure stream + FailStream Fail() { return fail_stream_.Fail(); } + + FailStream fail_stream_; +}; + +} // namespace spirv +} // namespace reader +} // namespace tint + +#endif // SRC_READER_SPIRV_ENUM_CONVERTER_H_ diff --git a/src/reader/spirv/enum_converter_test.cc b/src/reader/spirv/enum_converter_test.cc new file mode 100644 index 0000000000..b4450d651f --- /dev/null +++ b/src/reader/spirv/enum_converter_test.cc @@ -0,0 +1,93 @@ +// 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/enum_converter.h" + +#include +#include + +#include "gmock/gmock.h" +#include "spirv/unified1/spirv.h" +#include "src/ast/pipeline_stage.h" + +namespace tint { +namespace reader { +namespace spirv { +namespace { + +struct PipelineStageCase { + SpvExecutionModel model; + bool expect_success; + ast::PipelineStage expected; +}; +inline std::ostream& operator<<(std::ostream& out, PipelineStageCase psc) { + out << "PipelineStageCase{ SpvExecutionModel:" << int(psc.model) + << " expect_success?:" << int(psc.expect_success) + << " expected:" << int(psc.expected) << "}"; + return out; +} + +class SpvPipelineStageTest : public testing::TestWithParam { + public: + SpvPipelineStageTest() + : 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(SpvPipelineStageTest, Samples) { + const auto params = GetParam(); + + const auto result = converter_.ToPipelineStage(params.model); + 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 execution model:")); + } +} + +INSTANTIATE_TEST_SUITE_P( + EnumConverterGood, + SpvPipelineStageTest, + testing::Values(PipelineStageCase{SpvExecutionModelVertex, true, + ast::PipelineStage::kVertex}, + PipelineStageCase{SpvExecutionModelFragment, true, + ast::PipelineStage::kFragment}, + PipelineStageCase{SpvExecutionModelGLCompute, true, + ast::PipelineStage::kCompute})); + +INSTANTIATE_TEST_SUITE_P( + EnumConverterBad, + SpvPipelineStageTest, + testing::Values(PipelineStageCase{SpvExecutionModel(9999), false, + ast::PipelineStage::kNone}, + PipelineStageCase{SpvExecutionModelTessellationControl, + false, ast::PipelineStage::kNone})); + +} // namespace +} // namespace spirv +} // namespace reader +} // namespace tint