[glsl] Emit let's
Add emitting of let statements to the GLSL IR backend.
Bug: 42251044
Change-Id: I9a38f9d84383b7789f70d0348f8935b11696c559
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200457
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/glsl/writer/BUILD.bazel b/src/tint/lang/glsl/writer/BUILD.bazel
index 9ea3151..8294a43 100644
--- a/src/tint/lang/glsl/writer/BUILD.bazel
+++ b/src/tint/lang/glsl/writer/BUILD.bazel
@@ -90,6 +90,7 @@
"call_test.cc",
"constant_test.cc",
"function_test.cc",
+ "var_and_let_test.cc",
] + select({
":tint_build_glsl_validator": [
"helper_test.h",
diff --git a/src/tint/lang/glsl/writer/BUILD.cmake b/src/tint/lang/glsl/writer/BUILD.cmake
index f105f30..e5a40a3 100644
--- a/src/tint/lang/glsl/writer/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/BUILD.cmake
@@ -101,6 +101,7 @@
lang/glsl/writer/call_test.cc
lang/glsl/writer/constant_test.cc
lang/glsl/writer/function_test.cc
+ lang/glsl/writer/var_and_let_test.cc
)
tint_target_add_dependencies(tint_lang_glsl_writer_test test
diff --git a/src/tint/lang/glsl/writer/BUILD.gn b/src/tint/lang/glsl/writer/BUILD.gn
index 1d2047c..8b3b547 100644
--- a/src/tint/lang/glsl/writer/BUILD.gn
+++ b/src/tint/lang/glsl/writer/BUILD.gn
@@ -93,6 +93,7 @@
"call_test.cc",
"constant_test.cc",
"function_test.cc",
+ "var_and_let_test.cc",
]
deps = [
"${tint_src_dir}:gmock_and_gtest",
diff --git a/src/tint/lang/glsl/writer/call_test.cc b/src/tint/lang/glsl/writer/call_test.cc
index b7148f1..c4ead84 100644
--- a/src/tint/lang/glsl/writer/call_test.cc
+++ b/src/tint/lang/glsl/writer/call_test.cc
@@ -33,8 +33,7 @@
namespace tint::glsl::writer {
namespace {
-// TODO(dsinclair): Enable when `let` is supported
-TEST_F(GlslWriterTest, DISABLED_CallWithoutParams) {
+TEST_F(GlslWriterTest, CallWithoutParams) {
auto* f = b.Function("a", ty.bool_());
f->Block()->Append(b.Return(f, false));
@@ -50,12 +49,10 @@
bool a() {
return false;
}
-
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main() {
- bool x = a();
+ bool x = a();
}
-
)");
}
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc
index 8ce53bd..456c1ce 100644
--- a/src/tint/lang/glsl/writer/printer/printer.cc
+++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -37,6 +37,7 @@
#include "src/tint/lang/core/ir/core_unary.h"
#include "src/tint/lang/core/ir/exit_if.h"
#include "src/tint/lang/core/ir/function.h"
+#include "src/tint/lang/core/ir/let.h"
#include "src/tint/lang/core/ir/load.h"
#include "src/tint/lang/core/ir/load_vector_element.h"
#include "src/tint/lang/core/ir/module.h"
@@ -176,6 +177,7 @@
tint::Switch(
inst, //
[&](const core::ir::Call* i) { EmitCallStmt(i); }, //
+ [&](const core::ir::Let* i) { EmitLet(i); }, //
[&](const core::ir::Return* r) { EmitReturn(r); }, //
[&](const core::ir::Unreachable*) { EmitUnreachable(); }, //
@@ -194,6 +196,17 @@
}
}
+ void EmitLet(const core::ir::Let* l) {
+ auto out = Line();
+
+ // TODO(dsinclair): Investigate using `const` here as well, the AST printer doesn't emit
+ // const with a let, but we should be able to.
+ EmitTypeAndName(out, l->Result(0)->Type(), NameOf(l->Result(0)));
+ out << " = ";
+ EmitValue(out, l->Value());
+ out << ";";
+ }
+
void EmitCallStmt(const core::ir::Call* c) {
if (!c->Result(0)->IsUsed()) {
auto out = Line();
@@ -213,10 +226,26 @@
Line() << "#extension " << name << ": require";
}
+ void EmitTypeAndName(StringStream& out, const core::type::Type* type, const std::string& name) {
+ bool name_printed = false;
+ EmitType(out, type, name, &name_printed);
+
+ if (!name.empty() && !name_printed) {
+ out << " " << name;
+ }
+ }
+
/// Emit a type
/// @param out the stream to emit too
/// @param ty the type to emit
- void EmitType(StringStream& out, const core::type::Type* ty) {
+ void EmitType(StringStream& out,
+ const core::type::Type* ty,
+ [[maybe_unused]] const std::string& name = "",
+ bool* name_printed = nullptr) {
+ if (name_printed) {
+ *name_printed = false;
+ }
+
tint::Switch(
ty, //
[&](const core::type::Bool*) { out << "bool"; },
diff --git a/src/tint/lang/glsl/writer/var_and_let_test.cc b/src/tint/lang/glsl/writer/var_and_let_test.cc
new file mode 100644
index 0000000..aaee3f8
--- /dev/null
+++ b/src/tint/lang/glsl/writer/var_and_let_test.cc
@@ -0,0 +1,54 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/glsl/writer/helper_test.h"
+
+using namespace tint::core::fluent_types; // NOLINT
+using namespace tint::core::number_suffixes; // NOLINT
+
+namespace tint::glsl::writer {
+namespace {
+
+TEST_F(GlslWriterTest, Let) {
+ auto* func = b.Function("main", ty.void_(), core::ir::Function::PipelineStage::kCompute);
+ func->SetWorkgroupSize(1, 1, 1);
+ b.Append(func->Block(), [&] {
+ b.Let("a", 2_f);
+ b.Return(func);
+ });
+
+ ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+ EXPECT_EQ(output_.glsl, GlslHeader() + R"(
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void main() {
+ float a = 2.0f;
+}
+)");
+}
+
+} // namespace
+} // namespace tint::glsl::writer