[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) {