Setup infrastructure for single entry point `tint`.
Creates all the needed code paths for single entry point `tint`, but keep
all the backends using the original code path for now. They will be moved
over one-by-one.
Bug: 380043961
Change-Id: I02cc2cc350d42099063ef95a8208e88499c63454
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/218334
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index 5eeb7e5..8ecf145 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -672,7 +672,9 @@
transform_manager.Add<tint::ast::transform::SubstituteOverride>();
}
-[[maybe_unused]] tint::Result<tint::Program> ProcessASTTransforms(
+// This will be removed once all the generators are moved over to the always run single entry point
+// version.
+[[maybe_unused]] tint::Result<tint::Program> ProcessASTTransformsOld(
Options& options,
tint::inspector::Inspector& inspector,
tint::Program& program) {
@@ -696,6 +698,28 @@
return transform_manager.Run(program, std::move(transform_inputs), outputs);
}
+[[maybe_unused]] tint::Result<tint::Program> ProcessASTTransforms(
+ Options& options,
+ tint::inspector::Inspector& inspector,
+ tint::Program& program) {
+ tint::ast::transform::Manager transform_manager;
+ tint::ast::transform::DataMap transform_inputs;
+
+ transform_manager.append(std::make_unique<tint::ast::transform::SingleEntryPoint>());
+ transform_inputs.Add<tint::ast::transform::SingleEntryPoint::Config>(options.ep_name);
+
+ AddRenamer(options, transform_manager, transform_inputs);
+
+ auto res = CreateOverrideMap(options, inspector);
+ if (res != tint::Success) {
+ return res.Failure();
+ }
+ AddSubstituteOverrides(res.Get(), transform_manager, transform_inputs);
+
+ tint::ast::transform::DataMap outputs;
+ return transform_manager.Run(program, std::move(transform_inputs), outputs);
+}
+
#if TINT_BUILD_SPV_WRITER
std::string Disassemble(const std::vector<uint32_t>& data) {
std::string spv_errors;
@@ -745,7 +769,7 @@
[[maybe_unused]] tint::inspector::Inspector& inspector,
[[maybe_unused]] tint::Program& src_program) {
#if TINT_BUILD_SPV_WRITER
- auto res = ProcessASTTransforms(options, inspector, src_program);
+ auto res = ProcessASTTransformsOld(options, inspector, src_program);
if (res != tint::Success || !res->IsValid()) {
tint::cmd::PrintWGSL(std::cerr, res.Get());
std::cerr << res->Diagnostics() << "\n";
@@ -865,7 +889,7 @@
[[maybe_unused]] tint::inspector::Inspector& inspector,
[[maybe_unused]] tint::Program& src_program) {
#if TINT_BUILD_MSL_WRITER
- auto transform_res = ProcessASTTransforms(options, inspector, src_program);
+ auto transform_res = ProcessASTTransformsOld(options, inspector, src_program);
if (transform_res != tint::Success || !transform_res->IsValid()) {
tint::cmd::PrintWGSL(std::cerr, transform_res.Get());
std::cerr << transform_res->Diagnostics() << "\n";
@@ -986,7 +1010,7 @@
[[maybe_unused]] tint::inspector::Inspector& inspector,
[[maybe_unused]] tint::Program& src_program) {
#if TINT_BUILD_HLSL_WRITER
- auto res = ProcessASTTransforms(options, inspector, src_program);
+ auto res = ProcessASTTransformsOld(options, inspector, src_program);
if (res != tint::Success || !res->IsValid()) {
tint::cmd::PrintWGSL(std::cerr, res.Get());
std::cerr << res->Diagnostics() << "\n";
@@ -1120,7 +1144,7 @@
[[maybe_unused]] tint::inspector::Inspector& src_inspector,
[[maybe_unused]] tint::Program& src_program) {
#if TINT_BUILD_GLSL_WRITER
- auto res = ProcessASTTransforms(options, src_inspector, src_program);
+ auto res = ProcessASTTransformsOld(options, src_inspector, src_program);
if (res != tint::Success || !res->IsValid()) {
tint::cmd::PrintWGSL(std::cerr, res.Get());
std::cerr << res->Diagnostics() << "\n";
@@ -1128,8 +1152,7 @@
}
tint::inspector::Inspector inspector(res.Get());
- auto generate = [&](const tint::Program& prg, const std::string entry_point_name,
- [[maybe_unused]] tint::ast::PipelineStage stage) -> bool {
+ auto generate = [&](const tint::Program& prg, const std::string entry_point_name) -> bool {
tint::glsl::writer::Options gen_options;
if (options.glsl_desktop) {
@@ -1192,6 +1215,18 @@
}
if (options.validate && options.skip_hash.count(hash) == 0) {
+ tint::ast::PipelineStage stage = tint::ast::PipelineStage::kCompute;
+ switch (entry_point.stage) {
+ case tint::inspector::PipelineStage::kCompute:
+ stage = tint::ast::PipelineStage::kCompute;
+ break;
+ case tint::inspector::PipelineStage::kVertex:
+ stage = tint::ast::PipelineStage::kVertex;
+ break;
+ case tint::inspector::PipelineStage::kFragment:
+ stage = tint::ast::PipelineStage::kFragment;
+ break;
+ }
#if !TINT_BUILD_GLSL_VALIDATOR
std::cerr << "GLSL validator not enabled in tint build\n";
return false;
@@ -1212,24 +1247,12 @@
if (inspector.GetEntryPoints().empty()) {
// Pass empty string here so that the GLSL generator will generate
// code for all functions, reachable or not.
- return generate(res.Get(), "", tint::ast::PipelineStage::kCompute);
+ return generate(res.Get(), "");
}
bool success = true;
for (auto& entry_point : inspector.GetEntryPoints()) {
- tint::ast::PipelineStage stage = tint::ast::PipelineStage::kCompute;
- switch (entry_point.stage) {
- case tint::inspector::PipelineStage::kCompute:
- stage = tint::ast::PipelineStage::kCompute;
- break;
- case tint::inspector::PipelineStage::kVertex:
- stage = tint::ast::PipelineStage::kVertex;
- break;
- case tint::inspector::PipelineStage::kFragment:
- stage = tint::ast::PipelineStage::kFragment;
- break;
- }
- success &= generate(res.Get(), entry_point.name, stage);
+ success &= generate(res.Get(), entry_point.name);
}
return success;
#else
@@ -1337,32 +1360,113 @@
return GenerateWgsl(options, inspector, info.program) ? 0 : 1;
}
- bool success = false;
- switch (options.format) {
- case Format::kSpirv:
- case Format::kSpvAsm:
- success = GenerateSpirv(options, inspector, info.program);
- break;
- case Format::kMsl:
- success = GenerateMsl(options, inspector, info.program);
- break;
- case Format::kHlsl:
- case Format::kHlslFxc:
- success = GenerateHlsl(options, inspector, info.program);
- break;
- case Format::kGlsl:
- success = GenerateGlsl(options, inspector, info.program);
- break;
- case Format::kWgsl:
- TINT_UNREACHABLE();
- case Format::kNone:
- break;
- default:
- std::cerr << "Unknown output format specified\n";
+ if (options.format == Format::kNone) {
+ auto generate = [&]() {
+ bool success = false;
+ switch (options.format) {
+ case Format::kSpirv:
+ case Format::kSpvAsm:
+ success = GenerateSpirv(options, inspector, info.program);
+ break;
+ case Format::kMsl:
+ success = GenerateMsl(options, inspector, info.program);
+ break;
+ case Format::kHlsl:
+ case Format::kHlslFxc:
+ success = GenerateHlsl(options, inspector, info.program);
+ break;
+ case Format::kGlsl:
+ success = GenerateGlsl(options, inspector, info.program);
+ break;
+ case Format::kNone:
+ break;
+ case Format::kWgsl:
+ TINT_UNREACHABLE();
+ default:
+ std::cerr << "Unknown output format specified\n";
+ return false;
+ }
+ if (!success) {
+ return false;
+ }
+ return true;
+ };
+
+ if (inspector.GetEntryPoints().empty()) {
+ return generate() ? 0 : 1;
+ }
+
+ bool success = true;
+ std::string outfile_name = options.output_file;
+ auto entry_points = inspector.GetEntryPoints();
+ for (auto& entry_point : entry_points) {
+ if (options.emit_single_entry_point && entry_point.name != options.ep_name) {
+ continue;
+ }
+
+ // If we're emitting to stdout, add a separator between the entry points. If we're going
+ // to a file, and we aren't emitting a single entry point, add the entry point name into
+ // the output file name.
+ if (tint::cmd::IsStdout(options.output_file)) {
+ if (entry_points.size() > 1) {
+ if (options.format == Format::kSpvAsm) {
+ std::cout << ";\n; ";
+ } else {
+ std::cout << "//\n// ";
+ }
+ std::cout << entry_point.name << "\n";
+ if (options.format == Format::kSpvAsm) {
+ std::cout << ";\n";
+ } else {
+ std::cout << "//\n";
+ }
+ }
+ } else if (!options.emit_single_entry_point) {
+ auto pos = outfile_name.rfind(".");
+ if (pos == std::string_view::npos) {
+ options.output_file = outfile_name + "." + entry_point.name;
+ } else {
+ options.output_file = outfile_name.substr(0, pos) + "." + entry_point.name +
+ "." + outfile_name.substr(pos + 1);
+ }
+ }
+
+ options.ep_name = entry_point.name;
+ success &= generate();
+
+ if (options.emit_single_entry_point) {
+ break;
+ }
+ }
+ return success ? 0 : 1;
+
+ } else {
+ bool success = false;
+ switch (options.format) {
+ case Format::kSpirv:
+ case Format::kSpvAsm:
+ success = GenerateSpirv(options, inspector, info.program);
+ break;
+ case Format::kMsl:
+ success = GenerateMsl(options, inspector, info.program);
+ break;
+ case Format::kHlsl:
+ case Format::kHlslFxc:
+ success = GenerateHlsl(options, inspector, info.program);
+ break;
+ case Format::kGlsl:
+ success = GenerateGlsl(options, inspector, info.program);
+ break;
+ case Format::kWgsl:
+ case Format::kNone:
+ TINT_UNREACHABLE();
+ default:
+ std::cerr << "Unknown output format specified\n";
+ return 1;
+ }
+ if (!success) {
return 1;
- }
- if (!success) {
- return 1;
+ }
}
return 0;