diff --git a/include/tint/.clang-format b/include/tint/.clang-format new file mode 100644 index 0000000000..2fb833a5df --- /dev/null +++ b/include/tint/.clang-format @@ -0,0 +1,2 @@ +# http://clang.llvm.org/docs/ClangFormatStyleOptions.html +BasedOnStyle: Chromium diff --git a/include/tint/tint.h b/include/tint/tint.h index 1a04196bfe..2b8430e01d 100644 --- a/include/tint/tint.h +++ b/include/tint/tint.h @@ -61,7 +61,6 @@ #endif // TINT_BUILD_HLSL_WRITER #if TINT_BUILD_GLSL_WRITER -#include "src/tint/transform/glsl.h" #include "src/tint/writer/glsl/generator.h" #endif // TINT_BUILD_GLSL_WRITER diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index 956705503e..5594bf87da 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -751,8 +751,6 @@ libtint_source_set("libtint_hlsl_writer_src") { libtint_source_set("libtint_glsl_writer_src") { sources = [ - "transform/glsl.cc", - "transform/glsl.h", "writer/glsl/generator.cc", "writer/glsl/generator.h", "writer/glsl/generator_impl.cc", diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index a6ad6f6224..527eeafa42 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -339,8 +339,6 @@ set(TINT_LIB_SRCS transform/for_loop_to_loop.h transform/expand_compound_assignment.cc transform/expand_compound_assignment.h - transform/glsl.cc - transform/glsl.h transform/loop_to_for_loop.cc transform/loop_to_for_loop.h transform/manager.cc diff --git a/src/tint/transform/glsl.cc b/src/tint/transform/glsl.cc deleted file mode 100644 index f0120e8fb8..0000000000 --- a/src/tint/transform/glsl.cc +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2021 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/tint/transform/glsl.h" - -#include - -#include "src/tint/program_builder.h" -#include "src/tint/transform/add_empty_entry_point.h" -#include "src/tint/transform/add_spirv_block_attribute.h" -#include "src/tint/transform/binding_remapper.h" -#include "src/tint/transform/builtin_polyfill.h" -#include "src/tint/transform/canonicalize_entry_point_io.h" -#include "src/tint/transform/combine_samplers.h" -#include "src/tint/transform/decompose_memory_access.h" -#include "src/tint/transform/expand_compound_assignment.h" -#include "src/tint/transform/fold_trivial_single_use_lets.h" -#include "src/tint/transform/loop_to_for_loop.h" -#include "src/tint/transform/manager.h" -#include "src/tint/transform/promote_initializers_to_const_var.h" -#include "src/tint/transform/promote_side_effects_to_decl.h" -#include "src/tint/transform/remove_phonies.h" -#include "src/tint/transform/renamer.h" -#include "src/tint/transform/simplify_pointers.h" -#include "src/tint/transform/single_entry_point.h" -#include "src/tint/transform/unshadow.h" -#include "src/tint/transform/unwind_discard_functions.h" -#include "src/tint/transform/zero_init_workgroup_memory.h" -#include "src/tint/writer/generate_external_texture_bindings.h" - -TINT_INSTANTIATE_TYPEINFO(tint::transform::Glsl); -TINT_INSTANTIATE_TYPEINFO(tint::transform::Glsl::Config); - -namespace tint::transform { - -Glsl::Glsl() = default; -Glsl::~Glsl() = default; - -Output Glsl::Run(const Program* in, const DataMap& inputs) const { - Manager manager; - DataMap data; - - auto* cfg = inputs.Get(); - - { // Builtin polyfills - BuiltinPolyfill::Builtins polyfills; - polyfills.count_leading_zeros = true; - polyfills.count_trailing_zeros = true; - polyfills.extract_bits = BuiltinPolyfill::Level::kClampParameters; - polyfills.first_leading_bit = true; - polyfills.first_trailing_bit = true; - polyfills.insert_bits = BuiltinPolyfill::Level::kClampParameters; - data.Add(polyfills); - manager.Add(); - } - - if (cfg && !cfg->entry_point.empty()) { - manager.Add(); - data.Add(cfg->entry_point); - } - manager.Add(); - data.Add(Renamer::Target::kGlslKeywords, - /* preserve_unicode */ false); - manager.Add(); - - // Attempt to convert `loop`s into for-loops. This is to try and massage the - // output into something that will not cause FXC to choke or misbehave. - manager.Add(); - manager.Add(); - - if (!cfg || !cfg->disable_workgroup_init) { - // ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as - // ZeroInitWorkgroupMemory may inject new builtin parameters. - manager.Add(); - } - manager.Add(); - manager.Add(); - manager.Add(); - manager.Add(); - manager.Add(); - - manager.Add(); - - if (cfg && cfg->generate_external_texture_bindings) { - auto new_bindings_map = writer::GenerateExternalTextureBindings(in); - data.Add(new_bindings_map); - } - manager.Add(); - - manager.Add(); - if (auto* binding_info = inputs.Get()) { - data.Add(*binding_info); - } else { - data.Add(CombineSamplers::BindingMap(), - sem::BindingPoint()); - } - manager.Add(); - if (auto* remappings = inputs.Get()) { - data.Add(*remappings); - } else { - BindingRemapper::BindingPoints bp; - BindingRemapper::AccessControls ac; - data.Add(bp, ac, /* mayCollide */ true); - } - - manager.Add(); - - manager.Add(); - manager.Add(); - - data.Add( - CanonicalizeEntryPointIO::ShaderStyle::kGlsl); - auto out = manager.Run(in, data); - if (!out.program.IsValid()) { - return out; - } - - ProgramBuilder builder; - CloneContext ctx(&builder, &out.program); - ctx.Clone(); - return Output{Program(std::move(builder))}; -} - -Glsl::Config::Config(const std::string& entry_point_in, - bool disable_workgroup_init_in, - bool generate_external_texture_bindings_in) - : entry_point(entry_point_in), - disable_workgroup_init(disable_workgroup_init_in), - generate_external_texture_bindings( - generate_external_texture_bindings_in) {} -Glsl::Config::Config(const Config&) = default; -Glsl::Config::~Config() = default; - -} // namespace tint::transform diff --git a/src/tint/transform/glsl.h b/src/tint/transform/glsl.h deleted file mode 100644 index c84ff2958d..0000000000 --- a/src/tint/transform/glsl.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2021 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_TINT_TRANSFORM_GLSL_H_ -#define SRC_TINT_TRANSFORM_GLSL_H_ - -#include - -#include "src/tint/transform/transform.h" - -// Forward declarations -namespace tint { -class CloneContext; -} // namespace tint - -namespace tint::transform { - -/// Glsl is a transform used to sanitize a Program for use with the Glsl writer. -/// Passing a non-sanitized Program to the Glsl writer will result in undefined -/// behavior. -class Glsl final : public Castable { - public: - /// Configuration options for the Glsl sanitizer transform. - struct Config final : public Castable { - /// Constructor - /// @param entry_point the root entry point function to generate - /// @param disable_workgroup_init `true` to disable workgroup memory zero - /// initialization - /// @param generate_external_texture_bindings 'true' to generates binding - /// mappings for external textures - explicit Config(const std::string& entry_point, - bool disable_workgroup_init, - bool generate_external_texture_bindings); - - /// Copy constructor - Config(const Config&); - - /// Destructor - ~Config() override; - - /// GLSL generator wraps a single entry point in a main() function. - std::string entry_point; - - /// Set to `true` to disable workgroup memory zero initialization - bool disable_workgroup_init = false; - - /// Set to 'true' to generates binding mappings for external textures - bool generate_external_texture_bindings = false; - }; - - /// Constructor - Glsl(); - ~Glsl() override; - - /// Runs the transform on `program`, returning the transformation result. - /// @param program the source program to transform - /// @param data optional extra transform-specific data - /// @returns the transformation result - Output Run(const Program* program, const DataMap& data = {}) const override; -}; - -} // namespace tint::transform - -#endif // SRC_TINT_TRANSFORM_GLSL_H_ diff --git a/src/tint/transform/glsl_test.cc b/src/tint/transform/glsl_test.cc deleted file mode 100644 index 555701b59a..0000000000 --- a/src/tint/transform/glsl_test.cc +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2021 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/tint/transform/glsl.h" - -#include "src/tint/transform/test_helper.h" - -namespace tint::transform { -namespace { - -using GlslTest = TransformTest; - -TEST_F(GlslTest, AddEmptyEntryPoint) { - auto* src = R"()"; - - auto* expect = R"( -@stage(compute) @workgroup_size(1) -fn unused_entry_point() { -} -)"; - - auto got = Run(src); - - EXPECT_EQ(expect, str(got)); -} - -} // namespace -} // namespace tint::transform diff --git a/src/tint/writer/glsl/generator.cc b/src/tint/writer/glsl/generator.cc index ad06ac4e90..83ae8c4bc6 100644 --- a/src/tint/writer/glsl/generator.cc +++ b/src/tint/writer/glsl/generator.cc @@ -16,7 +16,6 @@ #include "src/tint/transform/binding_remapper.h" #include "src/tint/transform/combine_samplers.h" -#include "src/tint/transform/glsl.h" #include "src/tint/writer/glsl/generator_impl.h" namespace tint::writer::glsl { @@ -34,34 +33,25 @@ Result Generate(const Program* program, const std::string& entry_point) { Result result; - // Run the GLSL sanitizer. - transform::DataMap data; - data.Add(options.binding_points, - options.access_controls, - options.allow_collisions); - data.Add( - options.binding_map, options.placeholder_binding_point); - data.Add(entry_point, - /* disable_workgroup_init */ false, - options.generate_external_texture_bindings); - transform::Glsl sanitizer; - auto output = sanitizer.Run(program, data); - if (!output.program.IsValid()) { + // Sanitize the program. + auto sanitized_result = Sanitize(program, options, entry_point); + if (!sanitized_result.program.IsValid()) { result.success = false; - result.error = output.program.Diagnostics().str(); + result.error = sanitized_result.program.Diagnostics().str(); return result; } // Generate the GLSL code. - auto impl = std::make_unique(&output.program, options.version); + auto impl = std::make_unique(&sanitized_result.program, + options.version); result.success = impl->Generate(); result.error = impl->error(); result.glsl = impl->result(); // Collect the list of entry points in the sanitized program. - for (auto* func : output.program.AST().Functions()) { + for (auto* func : sanitized_result.program.AST().Functions()) { if (func->IsEntryPoint()) { - auto name = output.program.Symbols().NameFor(func->symbol); + auto name = sanitized_result.program.Symbols().NameFor(func->symbol); result.entry_points.push_back({name, func->PipelineStage()}); } } diff --git a/src/tint/writer/glsl/generator.h b/src/tint/writer/glsl/generator.h index ab5c9bb8d7..11206cf1a1 100644 --- a/src/tint/writer/glsl/generator.h +++ b/src/tint/writer/glsl/generator.h @@ -70,6 +70,9 @@ struct Options { /// generated by the BindingRemapper transform bool allow_collisions = false; + /// Set to `true` to disable workgroup memory zero initialization + bool disable_workgroup_init = false; + /// Set to 'true' to generates binding mappings for external textures bool generate_external_texture_bindings = false; @@ -106,6 +109,7 @@ struct Result { /// information. /// @param program the program to translate to GLSL /// @param options the configuration options to use when generating GLSL +/// @param entry_point the entry point to generate GLSL for /// @returns the resulting GLSL and supplementary information Result Generate(const Program* program, const Options& options, diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc index 729a8c07b4..ef7467db5c 100644 --- a/src/tint/writer/glsl/generator_impl.cc +++ b/src/tint/writer/glsl/generator_impl.cc @@ -45,12 +45,32 @@ #include "src/tint/sem/type_constructor.h" #include "src/tint/sem/type_conversion.h" #include "src/tint/sem/variable.h" -#include "src/tint/transform/glsl.h" +#include "src/tint/transform/add_empty_entry_point.h" +#include "src/tint/transform/add_spirv_block_attribute.h" +#include "src/tint/transform/binding_remapper.h" +#include "src/tint/transform/builtin_polyfill.h" +#include "src/tint/transform/canonicalize_entry_point_io.h" +#include "src/tint/transform/combine_samplers.h" +#include "src/tint/transform/decompose_memory_access.h" +#include "src/tint/transform/expand_compound_assignment.h" +#include "src/tint/transform/fold_trivial_single_use_lets.h" +#include "src/tint/transform/loop_to_for_loop.h" +#include "src/tint/transform/manager.h" +#include "src/tint/transform/promote_initializers_to_const_var.h" +#include "src/tint/transform/promote_side_effects_to_decl.h" +#include "src/tint/transform/remove_phonies.h" +#include "src/tint/transform/renamer.h" +#include "src/tint/transform/simplify_pointers.h" +#include "src/tint/transform/single_entry_point.h" +#include "src/tint/transform/unshadow.h" +#include "src/tint/transform/unwind_discard_functions.h" +#include "src/tint/transform/zero_init_workgroup_memory.h" #include "src/tint/utils/defer.h" #include "src/tint/utils/map.h" #include "src/tint/utils/scoped_assignment.h" #include "src/tint/writer/append_vector.h" #include "src/tint/writer/float_to_string.h" +#include "src/tint/writer/generate_external_texture_bindings.h" namespace { @@ -127,6 +147,86 @@ const char* convert_texel_format_to_glsl(const ast::TexelFormat format) { } // namespace +SanitizedResult::SanitizedResult() = default; +SanitizedResult::~SanitizedResult() = default; +SanitizedResult::SanitizedResult(SanitizedResult&&) = default; + +SanitizedResult Sanitize(const Program* in, + const Options& options, + const std::string& entry_point) { + transform::Manager manager; + transform::DataMap data; + + { // Builtin polyfills + transform::BuiltinPolyfill::Builtins polyfills; + polyfills.count_leading_zeros = true; + polyfills.count_trailing_zeros = true; + polyfills.extract_bits = + transform::BuiltinPolyfill::Level::kClampParameters; + polyfills.first_leading_bit = true; + polyfills.first_trailing_bit = true; + polyfills.insert_bits = transform::BuiltinPolyfill::Level::kClampParameters; + data.Add(polyfills); + manager.Add(); + } + + if (!entry_point.empty()) { + manager.Add(); + data.Add(entry_point); + } + manager.Add(); + data.Add( + transform::Renamer::Target::kGlslKeywords, + /* preserve_unicode */ false); + manager.Add(); + + // Attempt to convert `loop`s into for-loops. This is to try and massage the + // output into something that will not cause FXC to choke or misbehave. + manager.Add(); + manager.Add(); + + if (!options.disable_workgroup_init) { + // ZeroInitWorkgroupMemory must come before CanonicalizeEntryPointIO as + // ZeroInitWorkgroupMemory may inject new builtin parameters. + manager.Add(); + } + manager.Add(); + manager.Add(); + manager.Add(); + manager.Add(); + manager.Add(); + + manager.Add(); + + if (options.generate_external_texture_bindings) { + auto new_bindings_map = writer::GenerateExternalTextureBindings(in); + data.Add( + new_bindings_map); + } + manager.Add(); + + data.Add( + options.binding_map, options.placeholder_binding_point); + manager.Add(); + + data.Add(options.binding_points, + options.access_controls, + options.allow_collisions); + manager.Add(); + + manager.Add(); + manager.Add(); + manager.Add(); + data.Add( + transform::CanonicalizeEntryPointIO::ShaderStyle::kGlsl); + + auto out = manager.Run(in, data); + + SanitizedResult result; + result.program = std::move(out.program); + return result; +} + GeneratorImpl::GeneratorImpl(const Program* program, const Version& version) : TextGenerator(program), version_(version) {} diff --git a/src/tint/writer/glsl/generator_impl.h b/src/tint/writer/glsl/generator_impl.h index 37be658229..9104182acf 100644 --- a/src/tint/writer/glsl/generator_impl.h +++ b/src/tint/writer/glsl/generator_impl.h @@ -35,6 +35,7 @@ #include "src/tint/scope_stack.h" #include "src/tint/transform/decompose_memory_access.h" #include "src/tint/utils/hash.h" +#include "src/tint/writer/glsl/generator.h" #include "src/tint/writer/glsl/version.h" #include "src/tint/writer/text_generator.h" @@ -48,6 +49,28 @@ class TypeConversion; namespace tint::writer::glsl { +/// The result of sanitizing a program for generation. +struct SanitizedResult { + /// Constructor + SanitizedResult(); + /// Destructor + ~SanitizedResult(); + /// Move constructor + SanitizedResult(SanitizedResult&&); + + /// The sanitized program. + Program program; +}; + +/// Sanitize a program in preparation for generating GLSL. +/// @program The program to sanitize +/// @param options The HLSL generator options. +/// @param entry_point the entry point to generate GLSL for +/// @returns the sanitized program and any supplementary information +SanitizedResult Sanitize(const Program* program, + const Options& options, + const std::string& entry_point); + /// Implementation class for GLSL generator class GeneratorImpl : public TextGenerator { public: diff --git a/src/tint/writer/glsl/test_helper.h b/src/tint/writer/glsl/test_helper.h index 969490aa38..d4790175ec 100644 --- a/src/tint/writer/glsl/test_helper.h +++ b/src/tint/writer/glsl/test_helper.h @@ -20,7 +20,6 @@ #include #include "gtest/gtest.h" -#include "src/tint/transform/glsl.h" #include "src/tint/transform/manager.h" #include "src/tint/writer/glsl/generator_impl.h" @@ -61,7 +60,8 @@ class TestHelperBase : public BODY, public ProgramBuilder { /// return the same GeneratorImpl without rebuilding. /// @param version the GLSL version /// @return the built generator - GeneratorImpl& SanitizeAndBuild(Version version = Version()) { + GeneratorImpl& SanitizeAndBuild(Version version = Version(), + const Options& options = {}) { if (gen_) { return *gen_; } @@ -76,15 +76,14 @@ class TestHelperBase : public BODY, public ProgramBuilder { << formatter.format(program->Diagnostics()); }(); - transform::Manager transform_manager; - transform::DataMap transform_data; - transform_manager.Add(); - auto result = transform_manager.Run(program.get(), transform_data); + auto sanitized_result = + Sanitize(program.get(), options, /* entry_point */ ""); [&]() { - ASSERT_TRUE(result.program.IsValid()) - << formatter.format(result.program.Diagnostics()); + ASSERT_TRUE(sanitized_result.program.IsValid()) + << formatter.format(sanitized_result.program.Diagnostics()); }(); - *program = std::move(result.program); + + *program = std::move(sanitized_result.program); gen_ = std::make_unique(program.get(), version); return *gen_; } diff --git a/test/tint/BUILD.gn b/test/tint/BUILD.gn index fcf85d1c7e..bb217df485 100644 --- a/test/tint/BUILD.gn +++ b/test/tint/BUILD.gn @@ -667,7 +667,6 @@ tint_unittests_source_set("tint_unittests_hlsl_writer_src") { tint_unittests_source_set("tint_unittests_glsl_writer_src") { sources = [ - "../../src/tint/transform/glsl_test.cc", "../../src/tint/writer/glsl/generator_impl_array_accessor_test.cc", "../../src/tint/writer/glsl/generator_impl_assign_test.cc", "../../src/tint/writer/glsl/generator_impl_binary_test.cc",