[tint][msl] Check module + options before generating Move the `CanRun()` function from the writer fuzzer into the writer as a helper function. This can then be used by both the fuzzer and the Tint executable to check whether the backend can actually handle the module+options. This yields much more user friendly error messages from the Tint executable when trying to generate backend code for a module that contains features that are not supported by that backend. Bug: 376572262 Change-Id: Ib451250b4898c3f46edaa4ba2e36d6d39e625d91 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/222095 Reviewed-by: dan sinclair <dsinclair@chromium.org> Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc index 846c90b..adcefd4 100644 --- a/src/tint/cmd/tint/main.cc +++ b/src/tint/cmd/tint/main.cc
@@ -951,6 +951,14 @@ std::cerr << "Failed to generate IR: " << ir << "\n"; return false; } + + // Check that the module and options are supported by the backend. + auto check = tint::msl::writer::CanGenerate(ir.Get(), gen_options); + if (check != tint::Success) { + std::cerr << check.Failure() << "\n"; + return false; + } + result = tint::msl::writer::Generate(ir.Get(), gen_options); } else { result = tint::msl::writer::Generate(input_program, gen_options);
diff --git a/src/tint/lang/msl/writer/BUILD.bazel b/src/tint/lang/msl/writer/BUILD.bazel index 489aadd..c36364d 100644 --- a/src/tint/lang/msl/writer/BUILD.bazel +++ b/src/tint/lang/msl/writer/BUILD.bazel
@@ -49,6 +49,7 @@ "//src/tint/lang/core", "//src/tint/lang/core/common", "//src/tint/lang/core/constant", + "//src/tint/lang/core/ir", "//src/tint/lang/core/type", "//src/tint/lang/wgsl", "//src/tint/lang/wgsl/ast",
diff --git a/src/tint/lang/msl/writer/BUILD.cmake b/src/tint/lang/msl/writer/BUILD.cmake index 536378a..71f367ea 100644 --- a/src/tint/lang/msl/writer/BUILD.cmake +++ b/src/tint/lang/msl/writer/BUILD.cmake
@@ -57,6 +57,7 @@ tint_lang_core tint_lang_core_common tint_lang_core_constant + tint_lang_core_ir tint_lang_core_type tint_lang_wgsl tint_lang_wgsl_ast
diff --git a/src/tint/lang/msl/writer/BUILD.gn b/src/tint/lang/msl/writer/BUILD.gn index 9a2501bd..f003138 100644 --- a/src/tint/lang/msl/writer/BUILD.gn +++ b/src/tint/lang/msl/writer/BUILD.gn
@@ -54,6 +54,7 @@ "${tint_src_dir}/lang/core", "${tint_src_dir}/lang/core/common", "${tint_src_dir}/lang/core/constant", + "${tint_src_dir}/lang/core/ir", "${tint_src_dir}/lang/core/type", "${tint_src_dir}/lang/wgsl", "${tint_src_dir}/lang/wgsl/ast",
diff --git a/src/tint/lang/msl/writer/writer.cc b/src/tint/lang/msl/writer/writer.cc index ad36b55..c623e4b 100644 --- a/src/tint/lang/msl/writer/writer.cc +++ b/src/tint/lang/msl/writer/writer.cc
@@ -30,6 +30,9 @@ #include <memory> #include <utility> +#include "src/tint/lang/core/ir/module.h" +#include "src/tint/lang/core/ir/var.h" +#include "src/tint/lang/core/type/input_attachment.h" #include "src/tint/lang/msl/writer/ast_printer/ast_printer.h" #include "src/tint/lang/msl/writer/common/option_helpers.h" #include "src/tint/lang/msl/writer/printer/printer.h" @@ -37,6 +40,24 @@ namespace tint::msl::writer { +Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options&) { + // Check for unsupported module-scope variable address spaces and types. + for (auto* inst : *ir.root_block) { + auto* var = inst->As<core::ir::Var>(); + auto* ptr = var->Result(0)->Type()->As<core::type::Pointer>(); + if (ptr->AddressSpace() == core::AddressSpace::kPushConstant) { + return Failure("push constants are not supported by the MSL backend"); + } + if (ptr->AddressSpace() == core::AddressSpace::kPixelLocal) { + return Failure("pixel_local address space is not supported by the MSL backend"); + } + if (ptr->StoreType()->Is<core::type::InputAttachment>()) { + return Failure("input attachments are not supported by the MSL backend"); + } + } + return Success; +} + Result<Output> Generate(core::ir::Module& ir, const Options& options) { { auto res = ValidateBindingOptions(options);
diff --git a/src/tint/lang/msl/writer/writer.h b/src/tint/lang/msl/writer/writer.h index cdfdb2c..93f6505 100644 --- a/src/tint/lang/msl/writer/writer.h +++ b/src/tint/lang/msl/writer/writer.h
@@ -45,6 +45,12 @@ namespace tint::msl::writer { +/// Check if the module @p ir is supported by the MSL backend with @p options. +/// @param ir the module +/// @param options the writer options +/// @returns Success or a failure message indicating why MSL generation would fail +Result<SuccessType> CanGenerate(const core::ir::Module& ir, const Options& options); + /// Generate MSL for a program, according to a set of configuration options. /// The result will contain the MSL and supplementary information, or failure. /// @param ir the IR module to translate to MSL
diff --git a/src/tint/lang/msl/writer/writer_fuzz.cc b/src/tint/lang/msl/writer/writer_fuzz.cc index ba4dced..1be3150 100644 --- a/src/tint/lang/msl/writer/writer_fuzz.cc +++ b/src/tint/lang/msl/writer/writer_fuzz.cc
@@ -30,7 +30,6 @@ #include "src/tint/cmd/fuzz/ir/fuzz.h" #include "src/tint/lang/core/ir/module.h" #include "src/tint/lang/core/ir/var.h" -#include "src/tint/lang/core/type/input_attachment.h" #include "src/tint/lang/core/type/pointer.h" #include "src/tint/lang/msl/writer/helpers/generate_bindings.h" #include "src/tint/lang/msl/writer/writer.h" @@ -38,31 +37,9 @@ namespace tint::msl::writer { namespace { -bool CanRun(const core::ir::Module& module, const Options&) { - // Check for unsupported module-scope variable address spaces and types. - for (auto* inst : *module.root_block) { - auto* var = inst->As<core::ir::Var>(); - auto* ptr = var->Result(0)->Type()->As<core::type::Pointer>(); - if (ptr->AddressSpace() == core::AddressSpace::kPushConstant) { - return false; - } - if (ptr->AddressSpace() == core::AddressSpace::kPixelLocal) { - return false; - } - if (ptr->StoreType()->Is<core::type::InputAttachment>()) { - return false; - } - } - return true; -} - Result<SuccessType> IRFuzzer(core::ir::Module& module, const fuzz::ir::Context& context, Options options) { - if (!CanRun(module, options)) { - return Failure{"Cannot run module"}; - } - options.bindings = GenerateBindings(module); options.array_length_from_uniform.ubo_binding = 30; @@ -80,6 +57,11 @@ } } + auto check = CanGenerate(module, options); + if (check != Success) { + return check.Failure(); + } + auto output = Generate(module, options); if (output == Success && context.options.dump) {