[hlsl-writer] Scaffold the HLSL backend. This CL adds the scaffolding for the HLSL backend. Bug: tint:7 Change-Id: Iaf9f5159bc409f3ac71fcec281229258bdfa021b Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/25000 Reviewed-by: David Neto <dneto@google.com>
diff --git a/BUILD.gn b/BUILD.gn index 9bd4307..67d7557 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -62,6 +62,12 @@ defines += [ "TINT_BUILD_MSL_WRITER=0" ] } + if (tint_build_hlsl_writer) { + defines += [ "TINT_BUILD_HLSL_WRITER=1" ] + } else { + defines += [ "TINT_BUILD_HLSL_WRITER=0" ] + } + include_dirs = [ "${tint_root_dir}/", "${tint_root_dir}/include/", @@ -513,6 +519,23 @@ public_deps = [ ":libtint_core_src" ] } +source_set("libtint_hlsl_writer_src") { + sources = [ + "src/writer/hlsl/generator.cc", + "src/writer/hlsl/generator.h", + "src/writer/hlsl/generator_impl.cc", + "src/writer/hlsl/generator_impl.h", + ] + + configs += [ ":tint_common_config" ] + public_configs = [ ":tint_public_config" ] + + if (build_with_chromium) { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + } +} + source_set("libtint") { deps = [ ":libtint_core_src" ] @@ -536,6 +559,10 @@ deps += [ ":libtint_msl_writer_src" ] } + if (tint_build_hlsl_writer) { + deps += [ ":libtint_hlsl_writer_src" ] + } + configs += [ ":tint_common_config" ] public_configs = [ ":tint_public_config" ] @@ -982,6 +1009,21 @@ ] } +source_set("tint_unittests_hlsl_writer_src") { + sources = [ "src/writer/hlsl/generator_impl_test.cc" ] + + configs += [ + ":tint_common_config", + ":tint_unittests_config", + ] + public_configs = [ ":tint_public_config" ] + + if (build_with_chromium) { + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ "//build/config/compiler:no_chromium_code" ] + } +} + source_set("tint_unittests_src") { testonly = true
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4586ee4..a3cb4f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -29,6 +29,7 @@ option(TINT_BUILD_DOCS "Build documentation" ON) option(TINT_BUILD_SPV_READER "Build the SPIR-V input reader" ON) option(TINT_BUILD_WGSL_READER "Builde the WGSL input reader" ON) +option(TINT_BUILD_HLSL_WRITER "Build the HLSL output writer" ON) option(TINT_BUILD_MSL_WRITER "Build the MSL output writer" ON) option(TINT_BUILD_SPV_WRITER "Build the SPIR-V output writer" ON) option(TINT_BUILD_WGSL_WRITER "Build the WGSL output writer" ON) @@ -51,6 +52,7 @@ message(STATUS "Tint build docs: ${TINT_BUILD_DOCS}") message(STATUS "Tint build SPIR-V reader: ${TINT_BUILD_SPV_READER}") message(STATUS "Tint build WGSL reader: ${TINT_BUILD_WGSL_READER}") +message(STATUS "Tint build HLSL writer: ${TINT_BUILD_HLSL_WRITER}") message(STATUS "Tint build MSL writer: ${TINT_BUILD_MSL_WRITER}") message(STATUS "Tint build SPIR-V writer: ${TINT_BUILD_SPV_WRITER}") message(STATUS "Tint build WGSL writer: ${TINT_BUILD_WGSL_WRITER}") @@ -121,6 +123,8 @@ target_compile_definitions(${TARGET} PRIVATE -DTINT_BUILD_WGSL_READER=$<BOOL:${TINT_BUILD_WGSL_READER}>) target_compile_definitions(${TARGET} PRIVATE + -DTINT_BUILD_HLSL_WRITER=$<BOOL:${TINT_BUILD_HLSL_WRITER}>) + target_compile_definitions(${TARGET} PRIVATE -DTINT_BUILD_MSL_WRITER=$<BOOL:${TINT_BUILD_MSL_WRITER}>) target_compile_definitions(${TARGET} PRIVATE -DTINT_BUILD_SPV_WRITER=$<BOOL:${TINT_BUILD_SPV_WRITER}>)
diff --git a/include/tint/tint.h b/include/tint/tint.h index 6ff5947..8873612 100644 --- a/include/tint/tint.h +++ b/include/tint/tint.h
@@ -46,4 +46,8 @@ #include "src/writer/msl/generator.h" #endif // TINT_BUILD_MSL_WRITER +#if TINT_BUILD_HLSL_WRITER +#include "src/writer/hlsl/generator.h" +#endif // TINT_BUILD_HLSL_WRITER + #endif // INCLUDE_TINT_TINT_H_
diff --git a/samples/main.cc b/samples/main.cc index 674f3c4..d472b8e 100644 --- a/samples/main.cc +++ b/samples/main.cc
@@ -33,6 +33,7 @@ kSpvAsm, kWgsl, kMsl, + kHlsl, }; struct Options { @@ -50,13 +51,14 @@ const char kUsage[] = R"(Usage: tint [options] <input-file> options: - --format <spirv|spvasm|wgsl|msl> -- Output format. + --format <spirv|spvasm|wgsl|msl|hlsl> -- Output format. If not provided, will be inferred from output filename extension: .spvasm -> spvasm - .spv -> spirv - .wgsl -> wgsl - .metal -> msl + .spv -> spirv + .wgsl -> wgsl + .metal -> msl + .hlsl -> hlsl If none matches, then default to SPIR-V assembly. --output-file <name> -- Output file name. Use "-" for standard output -o <name> -- Output file name. Use "-" for standard output @@ -86,6 +88,11 @@ return Format::kMsl; #endif // TINT_BUILD_MSL_WRITER +#if TINT_BUILD_HLSL_WRITER + if (fmt == "hlsl") + return Format::kHlsl; +#endif // TINT_BUILD_HLSL_WRITER + return Format::kNone; } @@ -453,7 +460,13 @@ if (options.format == Format::kMsl) { writer = std::make_unique<tint::writer::msl::Generator>(std::move(mod)); } -#endif // TINT_BUILDER_MSL_WRITER +#endif // TINT_BUILD_MSL_WRITER + +#if TINT_BUILD_HLSL_WRITER + if (options.format == Format::kHlsl) { + writer = std::make_unique<tint::writer::hlsl::Generator>(std::move(mod)); + } +#endif // TINT_BUILD_HLSL_WRITER if (!writer) { std::cerr << "Unknown output format specified" << std::endl;
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fe9486d..23f3988 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt
@@ -260,6 +260,15 @@ ) endif() +if(${TINT_BUILD_HLSL_WRITER}) + list(APPEND TINT_LIB_SRCS + writer/hlsl/generator.cc + writer/hlsl/generator.h + writer/hlsl/generator_impl.cc + writer/hlsl/generator_impl.h + ) +endif() + set(TINT_TEST_SRCS ast/array_accessor_expression_test.cc ast/as_expression_test.cc @@ -524,6 +533,12 @@ ) endif() +if (${TINT_BUILD_HLSL_WRITER}) + list(APPEND TINT_TEST_SRCS + writer/hlsl/generator_impl_test.cc + ) +endif() + add_executable(tint_unittests ${TINT_TEST_SRCS}) if(NOT MSVC)
diff --git a/src/writer/hlsl/generator.cc b/src/writer/hlsl/generator.cc new file mode 100644 index 0000000..b0f1566 --- /dev/null +++ b/src/writer/hlsl/generator.cc
@@ -0,0 +1,45 @@ +// 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/writer/hlsl/generator.h" + +#include <utility> + +namespace tint { +namespace writer { +namespace hlsl { + +Generator::Generator(ast::Module module) : Text(std::move(module)) {} + +Generator::~Generator() = default; + +bool Generator::Generate() { + auto ret = impl_.Generate(module_); + if (!ret) { + error_ = impl_.error(); + } + return ret; +} + +std::string Generator::result() const { + return impl_.result(); +} + +std::string Generator::error() const { + return impl_.error(); +} + +} // namespace hlsl +} // namespace writer +} // namespace tint
diff --git a/src/writer/hlsl/generator.h b/src/writer/hlsl/generator.h new file mode 100644 index 0000000..c3cf473 --- /dev/null +++ b/src/writer/hlsl/generator.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_WRITER_HLSL_GENERATOR_H_ +#define SRC_WRITER_HLSL_GENERATOR_H_ + +#include <string> + +#include "src/writer/hlsl/generator_impl.h" +#include "src/writer/text.h" + +namespace tint { +namespace writer { +namespace hlsl { + +/// Class to generate HLSL source +class Generator : public Text { + public: + /// Constructor + /// @param module the module to convert + explicit Generator(ast::Module module); + ~Generator() override; + + /// Generates the result data + /// @returns true on successful generation; false otherwise + bool Generate() override; + + /// @returns the result data + std::string result() const override; + + /// @returns the error + std::string error() const; + + private: + GeneratorImpl impl_; +}; + +} // namespace hlsl +} // namespace writer +} // namespace tint + +#endif // SRC_WRITER_HLSL_GENERATOR_H_
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc new file mode 100644 index 0000000..7bcabcd --- /dev/null +++ b/src/writer/hlsl/generator_impl.cc
@@ -0,0 +1,31 @@ +// 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/writer/hlsl/generator_impl.h" + +namespace tint { +namespace writer { +namespace hlsl { + +GeneratorImpl::GeneratorImpl() = default; + +GeneratorImpl::~GeneratorImpl() = default; + +bool GeneratorImpl::Generate(const ast::Module&) { + return true; +} + +} // namespace hlsl +} // namespace writer +} // namespace tint
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h new file mode 100644 index 0000000..2c78a01 --- /dev/null +++ b/src/writer/hlsl/generator_impl.h
@@ -0,0 +1,42 @@ +// 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_WRITER_HLSL_GENERATOR_IMPL_H_ +#define SRC_WRITER_HLSL_GENERATOR_IMPL_H_ + +#include "src/ast/module.h" +#include "src/writer/text_generator.h" + +namespace tint { +namespace writer { +namespace hlsl { + +/// Implementation class for HLSL generator +class GeneratorImpl : public TextGenerator { + public: + /// Constructor + GeneratorImpl(); + ~GeneratorImpl(); + + /// Generates the result data + /// @param module the module to generate + /// @returns true on successful generation; false otherwise + bool Generate(const ast::Module& module); +}; + +} // namespace hlsl +} // namespace writer +} // namespace tint + +#endif // SRC_WRITER_HLSL_GENERATOR_IMPL_H_
diff --git a/src/writer/hlsl/generator_impl_test.cc b/src/writer/hlsl/generator_impl_test.cc new file mode 100644 index 0000000..0b68755 --- /dev/null +++ b/src/writer/hlsl/generator_impl_test.cc
@@ -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. + +#include "src/writer/hlsl/generator_impl.h" + +#include <memory> + +#include "gtest/gtest.h" +#include "src/ast/entry_point.h" +#include "src/ast/function.h" +#include "src/ast/module.h" +#include "src/ast/type/void_type.h" + +namespace tint { +namespace writer { +namespace hlsl { +namespace { + +using HlslGeneratorImplTest = testing::Test; + +TEST_F(HlslGeneratorImplTest, DISABLED_Generate) { + ast::type::VoidType void_type; + ast::Module m; + m.AddFunction(std::make_unique<ast::Function>("my_func", ast::VariableList{}, + &void_type)); + m.AddEntryPoint(std::make_unique<ast::EntryPoint>( + ast::PipelineStage::kFragment, "my_func", "")); + + GeneratorImpl g; + + ASSERT_TRUE(g.Generate(m)) << g.error(); + EXPECT_EQ(g.result(), R"(#import <metal_lib> + +void my_func() { +} +)"); +} + +} // namespace +} // namespace hlsl +} // namespace writer +} // namespace tint
diff --git a/src/writer/msl/generator.h b/src/writer/msl/generator.h index c062b3d..fcee316 100644 --- a/src/writer/msl/generator.h +++ b/src/writer/msl/generator.h
@@ -24,7 +24,7 @@ namespace writer { namespace msl { -/// Class to generate WGSL source from a WGSL module +/// Class to generate MSL source class Generator : public Text { public: /// Constructor
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h index cc7d33a..3176394 100644 --- a/src/writer/msl/generator_impl.h +++ b/src/writer/msl/generator_impl.h
@@ -32,7 +32,7 @@ namespace writer { namespace msl { -/// Implementation class for WGSL generator +/// Implementation class for MSL generator class GeneratorImpl : public TextGenerator { public: /// Constructor
diff --git a/src/writer/wgsl/generator.h b/src/writer/wgsl/generator.h index a9d170a..400d855 100644 --- a/src/writer/wgsl/generator.h +++ b/src/writer/wgsl/generator.h
@@ -24,7 +24,7 @@ namespace writer { namespace wgsl { -/// Class to generate WGSL source from a WGSL module +/// Class to generate WGSL source class Generator : public Text { public: /// Constructor