Import Tint changes from Dawn

Changes:
  - 38c78794a9a994cd7fcfbdf650819a9b024dc613 Fix Texture1DTo2D not appending .x for builtin as a call ... by Shrek Shao <shrekshao@google.com>
  - 4759145c009e50f09fb27e0992ae8b282c15b45e tint/cmake: fix TINT_BUILD_GLSL_VALIDATOR when !TINT_BUIL... by Antonio Maiorano <amaiorano@google.com>
  - 2df52b25ccab8e6cbefdd6592efb3db109b8fc0c [ir][glsl] Basic function emitting by dan sinclair <dsinclair@chromium.org>
  - 7fec38ce6e7fed55875bc555abecdc0031013f4c [ir][glsl] Pull common printing code out to suppport file. by dan sinclair <dsinclair@chromium.org>
GitOrigin-RevId: 38c78794a9a994cd7fcfbdf650819a9b024dc613
Change-Id: If86039a9959bac3bb9acd3f11c23f2233bc53f85
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/157160
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/externals.json b/src/tint/externals.json
index 6cdd1b2..a7631a5 100644
--- a/src/tint/externals.json
+++ b/src/tint/externals.json
@@ -46,13 +46,13 @@
         "IncludePatterns": [
             "glslang/Public/ShaderLang.h"
         ],
-        "Condition": "tint_build_glsl_writer",
+        "Condition": "tint_build_glsl_validator",
     },
     "glslang-res-limits": {
         "IncludePatterns": [
             "glslang/Public/ResourceLimits.h"
         ],
-        "Condition": "tint_build_glsl_writer",
+        "Condition": "tint_build_glsl_validator",
     },
     "gtest": {
         "IncludePatterns": [
@@ -66,4 +66,4 @@
         ],
         "Condition": "is_win",
     },
-}
+}
\ No newline at end of file
diff --git a/src/tint/lang/glsl/validate/BUILD.bazel b/src/tint/lang/glsl/validate/BUILD.bazel
index 9a40836..1c3f71a 100644
--- a/src/tint/lang/glsl/validate/BUILD.bazel
+++ b/src/tint/lang/glsl/validate/BUILD.bazel
@@ -57,7 +57,7 @@
     "//src/tint/utils/text",
     "//src/tint/utils/traits",
   ] + select({
-    ":tint_build_glsl_writer": [
+    ":tint_build_glsl_validator": [
       
       
     ],
@@ -72,8 +72,3 @@
   actual = "//src/tint:tint_build_glsl_validator_true",
 )
 
-alias(
-  name = "tint_build_glsl_writer",
-  actual = "//src/tint:tint_build_glsl_writer_true",
-)
-
diff --git a/src/tint/lang/glsl/validate/BUILD.cmake b/src/tint/lang/glsl/validate/BUILD.cmake
index ce1aaed..51a2a16 100644
--- a/src/tint/lang/glsl/validate/BUILD.cmake
+++ b/src/tint/lang/glsl/validate/BUILD.cmake
@@ -59,11 +59,11 @@
   tint_utils_traits
 )
 
-if(TINT_BUILD_GLSL_WRITER)
+if(TINT_BUILD_GLSL_VALIDATOR)
   tint_target_add_external_dependencies(tint_lang_glsl_validate lib
     "glslang"
     "glslang-res-limits"
   )
-endif(TINT_BUILD_GLSL_WRITER)
+endif(TINT_BUILD_GLSL_VALIDATOR)
 
 endif(TINT_BUILD_GLSL_VALIDATOR)
\ No newline at end of file
diff --git a/src/tint/lang/glsl/validate/BUILD.gn b/src/tint/lang/glsl/validate/BUILD.gn
index 9006a48..021b4b3 100644
--- a/src/tint/lang/glsl/validate/BUILD.gn
+++ b/src/tint/lang/glsl/validate/BUILD.gn
@@ -57,7 +57,7 @@
       "${tint_src_dir}/utils/traits",
     ]
 
-    if (tint_build_glsl_writer) {
+    if (tint_build_glsl_validator) {
       deps += [
         "${tint_glslang_dir}:glslang_default_resource_limits_sources",
         "${tint_glslang_dir}:glslang_lib_sources",
diff --git a/src/tint/lang/glsl/validate/validate.cc b/src/tint/lang/glsl/validate/validate.cc
index 8134c34..c8383b0 100644
--- a/src/tint/lang/glsl/validate/validate.cc
+++ b/src/tint/lang/glsl/validate/validate.cc
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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/validate/validate.h"
 
diff --git a/src/tint/lang/glsl/validate/validate.h b/src/tint/lang/glsl/validate/validate.h
index c30b23c..b1bf730 100644
--- a/src/tint/lang/glsl/validate/validate.h
+++ b/src/tint/lang/glsl/validate/validate.h
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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.
 
 #ifndef SRC_TINT_LANG_GLSL_VALIDATE_VALIDATE_H_
 #define SRC_TINT_LANG_GLSL_VALIDATE_VALIDATE_H_
diff --git a/src/tint/lang/glsl/writer/ast_printer/BUILD.bazel b/src/tint/lang/glsl/writer/ast_printer/BUILD.bazel
index b03bc6f..de7e6a6 100644
--- a/src/tint/lang/glsl/writer/ast_printer/BUILD.bazel
+++ b/src/tint/lang/glsl/writer/ast_printer/BUILD.bazel
@@ -67,7 +67,6 @@
     "//src/tint/utils/reflection",
     "//src/tint/utils/result",
     "//src/tint/utils/rtti",
-    "//src/tint/utils/strconv",
     "//src/tint/utils/symbol",
     "//src/tint/utils/text",
     "//src/tint/utils/traits",
diff --git a/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake b/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake
index b1496cf..687d173 100644
--- a/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/ast_printer/BUILD.cmake
@@ -68,7 +68,6 @@
   tint_utils_reflection
   tint_utils_result
   tint_utils_rtti
-  tint_utils_strconv
   tint_utils_symbol
   tint_utils_text
   tint_utils_traits
diff --git a/src/tint/lang/glsl/writer/ast_printer/BUILD.gn b/src/tint/lang/glsl/writer/ast_printer/BUILD.gn
index d3155e5..bfd4c88 100644
--- a/src/tint/lang/glsl/writer/ast_printer/BUILD.gn
+++ b/src/tint/lang/glsl/writer/ast_printer/BUILD.gn
@@ -70,7 +70,6 @@
       "${tint_src_dir}/utils/reflection",
       "${tint_src_dir}/utils/result",
       "${tint_src_dir}/utils/rtti",
-      "${tint_src_dir}/utils/strconv",
       "${tint_src_dir}/utils/symbol",
       "${tint_src_dir}/utils/text",
       "${tint_src_dir}/utils/traits",
diff --git a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
index 6186a55..fc9a7ed 100644
--- a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
@@ -51,6 +51,7 @@
 #include "src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d.h"
 #include "src/tint/lang/glsl/writer/ast_raise/texture_builtins_from_uniform.h"
 #include "src/tint/lang/glsl/writer/common/options.h"
+#include "src/tint/lang/glsl/writer/common/printer_support.h"
 #include "src/tint/lang/wgsl/ast/call_statement.h"
 #include "src/tint/lang/wgsl/ast/id_attribute.h"
 #include "src/tint/lang/wgsl/ast/internal_attribute.h"
@@ -97,7 +98,6 @@
 #include "src/tint/utils/macros/defer.h"
 #include "src/tint/utils/macros/scoped_assignment.h"
 #include "src/tint/utils/rtti/switch.h"
-#include "src/tint/utils/strconv/float_to_string.h"
 #include "src/tint/utils/text/string.h"
 #include "src/tint/utils/text/string_stream.h"
 
@@ -130,37 +130,6 @@
     }
 }
 
-void PrintI32(StringStream& out, int32_t value) {
-    // GLSL parses `-2147483648` as a unary minus and `2147483648` as separate tokens, and the
-    // latter doesn't fit into an (32-bit) `int`. Emit `(-2147483647 - 1)` instead, which ensures
-    // the expression type is `int`.
-    if (auto int_min = std::numeric_limits<int32_t>::min(); value == int_min) {
-        out << "(" << int_min + 1 << " - 1)";
-    } else {
-        out << value;
-    }
-}
-
-void PrintF32(StringStream& out, float value) {
-    if (std::isinf(value)) {
-        out << "0.0f " << (value >= 0 ? "/* inf */" : "/* -inf */");
-    } else if (std::isnan(value)) {
-        out << "0.0f /* nan */";
-    } else {
-        out << tint::writer::FloatToString(value) << "f";
-    }
-}
-
-void PrintF16(StringStream& out, float value) {
-    if (std::isinf(value)) {
-        out << "0.0hf " << (value >= 0 ? "/* inf */" : "/* -inf */");
-    } else if (std::isnan(value)) {
-        out << "0.0hf /* nan */";
-    } else {
-        out << tint::writer::FloatToString(value) << "hf";
-    }
-}
-
 }  // namespace
 
 SanitizedResult::SanitizedResult() = default;
diff --git a/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d.cc b/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d.cc
index 4dc3480..df5452a 100644
--- a/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d.cc
+++ b/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d.cc
@@ -154,11 +154,6 @@
             }
 
             if (builtin->Fn() == wgsl::BuiltinFn::kTextureDimensions) {
-                // If this textureDimensions() call is in a CallStatement, we can leave it
-                // unmodified since the return value will be dropped on the floor anyway.
-                if (call->Stmt()->Declaration()->Is<ast::CallStatement>()) {
-                    return nullptr;
-                }
                 auto* new_call = ctx.CloneWithoutTransform(c);
                 return ctx.dst->MemberAccessor(new_call, "x");
             }
diff --git a/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d_test.cc b/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d_test.cc
index 35de36b..7441fe3 100644
--- a/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d_test.cc
+++ b/src/tint/lang/glsl/writer/ast_raise/texture_1d_to_2d_test.cc
@@ -153,17 +153,21 @@
 
 TEST_F(Texture1DTo2DTest, Global1DDeclAndTextureDimensionsInCallStmt) {
     auto* src = R"(
-@group(0) @binding(0) var t : texture_1d<f32>;
+@group(0) @binding(0) var st : texture_storage_1d<r32uint, write>;
+
+@group(0) @binding(1) var t : texture_1d<f32>;
 
 fn main() {
-  _ = textureDimensions(t);
+  textureStore(st, clamp(5, 0, i32((textureDimensions(st) - 1))), vec4u(0, 0, 0, 0));
 }
 )";
     auto* expect = R"(
-@group(0) @binding(0) var t : texture_2d<f32>;
+@group(0) @binding(0) var st : texture_storage_2d<r32uint, write>;
+
+@group(0) @binding(1) var t : texture_2d<f32>;
 
 fn main() {
-  _ = textureDimensions(t).x;
+  textureStore(st, vec2<i32>(clamp(5, 0, i32((textureDimensions(st).x - 1))), 0), vec4u(0, 0, 0, 0));
 }
 )";
 
diff --git a/src/tint/lang/glsl/writer/common/BUILD.bazel b/src/tint/lang/glsl/writer/common/BUILD.bazel
index 7c09ff5..1a61a9b 100644
--- a/src/tint/lang/glsl/writer/common/BUILD.bazel
+++ b/src/tint/lang/glsl/writer/common/BUILD.bazel
@@ -40,9 +40,11 @@
   name = "common",
   srcs = [
     "options.cc",
+    "printer_support.cc",
   ],
   hdrs = [
     "options.h",
+    "printer_support.h",
     "version.h",
   ],
   deps = [
@@ -53,6 +55,7 @@
     "//src/tint/utils/macros",
     "//src/tint/utils/math",
     "//src/tint/utils/reflection",
+    "//src/tint/utils/strconv",
     "//src/tint/utils/text",
     "//src/tint/utils/traits",
   ],
diff --git a/src/tint/lang/glsl/writer/common/BUILD.cmake b/src/tint/lang/glsl/writer/common/BUILD.cmake
index e9630c6..8c176fe 100644
--- a/src/tint/lang/glsl/writer/common/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/common/BUILD.cmake
@@ -43,6 +43,8 @@
 tint_add_target(tint_lang_glsl_writer_common lib
   lang/glsl/writer/common/options.cc
   lang/glsl/writer/common/options.h
+  lang/glsl/writer/common/printer_support.cc
+  lang/glsl/writer/common/printer_support.h
   lang/glsl/writer/common/version.h
 )
 
@@ -54,6 +56,7 @@
   tint_utils_macros
   tint_utils_math
   tint_utils_reflection
+  tint_utils_strconv
   tint_utils_text
   tint_utils_traits
 )
diff --git a/src/tint/lang/glsl/writer/common/BUILD.gn b/src/tint/lang/glsl/writer/common/BUILD.gn
index aedd5ec..a91c610 100644
--- a/src/tint/lang/glsl/writer/common/BUILD.gn
+++ b/src/tint/lang/glsl/writer/common/BUILD.gn
@@ -42,6 +42,8 @@
     sources = [
       "options.cc",
       "options.h",
+      "printer_support.cc",
+      "printer_support.h",
       "version.h",
     ]
     deps = [
@@ -52,6 +54,7 @@
       "${tint_src_dir}/utils/macros",
       "${tint_src_dir}/utils/math",
       "${tint_src_dir}/utils/reflection",
+      "${tint_src_dir}/utils/strconv",
       "${tint_src_dir}/utils/text",
       "${tint_src_dir}/utils/traits",
     ]
diff --git a/src/tint/lang/glsl/writer/common/printer_support.cc b/src/tint/lang/glsl/writer/common/printer_support.cc
new file mode 100644
index 0000000..d57f019
--- /dev/null
+++ b/src/tint/lang/glsl/writer/common/printer_support.cc
@@ -0,0 +1,68 @@
+// Copyright 2023 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/common/printer_support.h"
+
+#include <cmath>
+#include <limits>
+
+#include "src/tint/utils/strconv/float_to_string.h"
+
+namespace tint::glsl::writer {
+
+void PrintI32(StringStream& out, int32_t value) {
+    // GLSL parses `-2147483648` as a unary minus and `2147483648` as separate tokens, and the
+    // latter doesn't fit into an (32-bit) `int`. Emit `(-2147483647 - 1)` instead, which ensures
+    // the expression type is `int`.
+    if (auto int_min = std::numeric_limits<int32_t>::min(); value == int_min) {
+        out << "(" << int_min + 1 << " - 1)";
+    } else {
+        out << value;
+    }
+}
+
+void PrintF32(StringStream& out, float value) {
+    if (std::isinf(value)) {
+        out << "0.0f " << (value >= 0 ? "/* inf */" : "/* -inf */");
+    } else if (std::isnan(value)) {
+        out << "0.0f /* nan */";
+    } else {
+        out << tint::writer::FloatToString(value) << "f";
+    }
+}
+
+void PrintF16(StringStream& out, float value) {
+    if (std::isinf(value)) {
+        out << "0.0hf " << (value >= 0 ? "/* inf */" : "/* -inf */");
+    } else if (std::isnan(value)) {
+        out << "0.0hf /* nan */";
+    } else {
+        out << tint::writer::FloatToString(value) << "hf";
+    }
+}
+
+}  // namespace tint::glsl::writer
diff --git a/src/tint/lang/glsl/writer/common/printer_support.h b/src/tint/lang/glsl/writer/common/printer_support.h
new file mode 100644
index 0000000..d36a1d8
--- /dev/null
+++ b/src/tint/lang/glsl/writer/common/printer_support.h
@@ -0,0 +1,54 @@
+// Copyright 2023 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.
+
+#ifndef SRC_TINT_LANG_GLSL_WRITER_COMMON_PRINTER_SUPPORT_H_
+#define SRC_TINT_LANG_GLSL_WRITER_COMMON_PRINTER_SUPPORT_H_
+
+#include <cstdint>
+
+#include "src/tint/utils/text/string_stream.h"
+
+namespace tint::glsl::writer {
+
+/// Prints a float32 to the output stream
+/// @param out the stream to write too
+/// @param value the float32 value
+void PrintF32(StringStream& out, float value);
+
+/// Prints a float16 to the output stream
+/// @param out the stream to write too
+/// @param value the float16 value
+void PrintF16(StringStream& out, float value);
+
+/// Prints an int32 to the output stream
+/// @param out the stream to write too
+/// @param value the int32 value
+void PrintI32(StringStream& out, int32_t value);
+
+}  // namespace tint::glsl::writer
+
+#endif  // SRC_TINT_LANG_GLSL_WRITER_COMMON_PRINTER_SUPPORT_H_
diff --git a/src/tint/lang/glsl/writer/printer/BUILD.bazel b/src/tint/lang/glsl/writer/printer/BUILD.bazel
index 525314d..f54faec 100644
--- a/src/tint/lang/glsl/writer/printer/BUILD.bazel
+++ b/src/tint/lang/glsl/writer/printer/BUILD.bazel
@@ -64,7 +64,12 @@
     "//src/tint/utils/symbol",
     "//src/tint/utils/text",
     "//src/tint/utils/traits",
-  ],
+  ] + select({
+    ":tint_build_glsl_writer": [
+      "//src/tint/lang/glsl/writer/common",
+    ],
+    "//conditions:default": [],
+  }),
   copts = COPTS,
   visibility = ["//visibility:public"],
 )
@@ -73,6 +78,7 @@
   alwayslink = True,
   srcs = [
     "constant_test.cc",
+    "function_test.cc",
     "helper_test.h",
   ],
   deps = [
@@ -100,6 +106,7 @@
     "@gtest",
   ] + select({
     ":tint_build_glsl_writer": [
+      "//src/tint/lang/glsl/writer/common",
       "//src/tint/lang/glsl/writer/printer",
     ],
     "//conditions:default": [],
diff --git a/src/tint/lang/glsl/writer/printer/BUILD.cmake b/src/tint/lang/glsl/writer/printer/BUILD.cmake
index 7f291bc..73f0081 100644
--- a/src/tint/lang/glsl/writer/printer/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/printer/BUILD.cmake
@@ -67,6 +67,12 @@
   tint_utils_traits
 )
 
+if(TINT_BUILD_GLSL_WRITER)
+  tint_target_add_dependencies(tint_lang_glsl_writer_printer lib
+    tint_lang_glsl_writer_common
+  )
+endif(TINT_BUILD_GLSL_WRITER)
+
 endif(TINT_BUILD_GLSL_WRITER)
 if(TINT_BUILD_GLSL_WRITER)
 ################################################################################
@@ -76,6 +82,7 @@
 ################################################################################
 tint_add_target(tint_lang_glsl_writer_printer_test test
   lang/glsl/writer/printer/constant_test.cc
+  lang/glsl/writer/printer/function_test.cc
   lang/glsl/writer/printer/helper_test.h
 )
 
@@ -109,6 +116,7 @@
 
 if(TINT_BUILD_GLSL_WRITER)
   tint_target_add_dependencies(tint_lang_glsl_writer_printer_test test
+    tint_lang_glsl_writer_common
     tint_lang_glsl_writer_printer
   )
 endif(TINT_BUILD_GLSL_WRITER)
diff --git a/src/tint/lang/glsl/writer/printer/BUILD.gn b/src/tint/lang/glsl/writer/printer/BUILD.gn
index 3c9aca8..20efd60 100644
--- a/src/tint/lang/glsl/writer/printer/BUILD.gn
+++ b/src/tint/lang/glsl/writer/printer/BUILD.gn
@@ -68,6 +68,10 @@
       "${tint_src_dir}/utils/text",
       "${tint_src_dir}/utils/traits",
     ]
+
+    if (tint_build_glsl_writer) {
+      deps += [ "${tint_src_dir}/lang/glsl/writer/common" ]
+    }
   }
 }
 if (tint_build_unittests) {
@@ -75,6 +79,7 @@
     tint_unittests_source_set("unittests") {
       sources = [
         "constant_test.cc",
+        "function_test.cc",
         "helper_test.h",
       ]
       deps = [
@@ -103,7 +108,10 @@
       ]
 
       if (tint_build_glsl_writer) {
-        deps += [ "${tint_src_dir}/lang/glsl/writer/printer" ]
+        deps += [
+          "${tint_src_dir}/lang/glsl/writer/common",
+          "${tint_src_dir}/lang/glsl/writer/printer",
+        ]
       }
     }
   }
diff --git a/src/tint/lang/glsl/writer/printer/constant_test.cc b/src/tint/lang/glsl/writer/printer/constant_test.cc
index c4c9c13..55eb4db 100644
--- a/src/tint/lang/glsl/writer/printer/constant_test.cc
+++ b/src/tint/lang/glsl/writer/printer/constant_test.cc
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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/printer/helper_test.h"
 
diff --git a/src/tint/lang/glsl/writer/printer/function_test.cc b/src/tint/lang/glsl/writer/printer/function_test.cc
new file mode 100644
index 0000000..763a051
--- /dev/null
+++ b/src/tint/lang/glsl/writer/printer/function_test.cc
@@ -0,0 +1,45 @@
+// Copyright 2023 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/printer/helper_test.h"
+
+namespace tint::glsl::writer {
+namespace {
+
+TEST_F(GlslPrinterTest, Function_Empty) {
+    auto* func = b.Function("foo", ty.void_());
+    func->Block()->Append(b.Return(func));
+
+    ASSERT_TRUE(Generate()) << err_ << output_;
+    EXPECT_EQ(output_, GlslHeader() + R"(
+void foo() {
+}
+)");
+}
+
+}  // namespace
+}  // namespace tint::glsl::writer
diff --git a/src/tint/lang/glsl/writer/printer/helper_test.h b/src/tint/lang/glsl/writer/printer/helper_test.h
index fcecc3f..709fb17 100644
--- a/src/tint/lang/glsl/writer/printer/helper_test.h
+++ b/src/tint/lang/glsl/writer/printer/helper_test.h
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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.
 
 #ifndef SRC_TINT_LANG_GLSL_WRITER_PRINTER_HELPER_TEST_H_
 #define SRC_TINT_LANG_GLSL_WRITER_PRINTER_HELPER_TEST_H_
@@ -37,6 +50,8 @@
     core::ir::Builder b{mod};
     /// The type manager.
     core::type::Manager& ty{mod.Types()};
+    /// The GLSL version
+    Version version{};
 
   protected:
     /// The GLSL writer.
@@ -57,7 +72,7 @@
             return false;
         }
 
-        auto result = writer_.Generate();
+        auto result = writer_.Generate(version);
         if (!result) {
             err_ = result.Failure().reason.str();
             return false;
@@ -66,6 +81,17 @@
 
         return true;
     }
+
+    /// @returns the metal header string
+    std::string GlslHeader() const {
+        std::stringstream ver;
+        ver << "#version " << version.major_version << version.minor_version << "0";
+        if (version.IsES()) {
+            ver << " es";
+        }
+        ver << "\n";
+        return ver.str();
+    }
 };
 
 using GlslPrinterTest = GlslPrinterTestHelperBase<testing::Test>;
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc
index e14ea19..6351b29 100644
--- a/src/tint/lang/glsl/writer/printer/printer.cc
+++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -1,37 +1,77 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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/printer/printer.h"
 
 #include <utility>
 
+#include "src/tint/lang/core/ir/return.h"
+#include "src/tint/lang/core/ir/unreachable.h"
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/utils/macros/scoped_assignment.h"
+#include "src/tint/utils/rtti/switch.h"
 
 using namespace tint::core::fluent_types;  // NOLINT
 
 namespace tint::glsl::writer {
 
+// Helper for calling TINT_UNIMPLEMENTED() from a Switch(object_ptr) default case.
+#define UNHANDLED_CASE(object_ptr)                         \
+    TINT_UNIMPLEMENTED() << "unhandled case in Switch(): " \
+                         << (object_ptr ? object_ptr->TypeInfo().name : "<null>")
+
 Printer::Printer(core::ir::Module& module) : ir_(module) {}
 
 Printer::~Printer() = default;
 
-tint::Result<SuccessType> Printer::Generate() {
+tint::Result<SuccessType> Printer::Generate(Version version) {
     auto valid = core::ir::ValidateAndDumpIfNeeded(ir_, "GLSL writer");
     if (!valid) {
         return std::move(valid.Failure());
     }
 
+    {
+        TINT_SCOPED_ASSIGNMENT(current_buffer_, &preamble_buffer_);
+
+        auto out = Line();
+        out << "#version " << version.major_version << version.minor_version << "0";
+        if (version.IsES()) {
+            out << " es";
+        }
+    }
+
+    // Emit module-scope declarations.
+    EmitBlockInstructions(ir_.root_block);
+
+    // Emit functions.
+    for (auto* func : ir_.functions) {
+        EmitFunction(func);
+    }
+
     return Success;
 }
 
@@ -41,4 +81,69 @@
     return ss.str();
 }
 
+void Printer::EmitFunction(core::ir::Function* func) {
+    TINT_SCOPED_ASSIGNMENT(current_function_, func);
+
+    {
+        auto out = Line();
+
+        // TODO(dsinclair): Emit function stage if any
+        // TODO(dsinclair): Handle return type attributes
+
+        EmitType(out, func->ReturnType());
+        out << " " << ir_.NameOf(func).Name() << "() {";
+
+        // TODO(dsinclair): Emit Function parameters
+    }
+    {
+        ScopedIndent si(current_buffer_);
+        EmitBlock(func->Block());
+    }
+
+    Line() << "}";
+}
+
+void Printer::EmitBlock(core::ir::Block* block) {
+    // TODO(dsinclair): Handle marking inline
+    // MarkInlinable(block);
+
+    EmitBlockInstructions(block);
+}
+
+void Printer::EmitBlockInstructions(core::ir::Block* block) {
+    TINT_SCOPED_ASSIGNMENT(current_block_, block);
+
+    for (auto* inst : *block) {
+        Switch(
+            inst,                                                //
+            [&](core::ir::Return* r) { EmitReturn(r); },         //
+            [&](core::ir::Unreachable*) { EmitUnreachable(); },  //
+            [&](Default) { UNHANDLED_CASE(inst); });
+    }
+}
+
+void Printer::EmitType(StringStream& out, [[maybe_unused]] const core::type::Type* ty) {
+    out << "void";
+}
+
+void Printer::EmitReturn(core::ir::Return* r) {
+    // If this return has no arguments and the current block is for the function which is
+    // being returned, skip the return.
+    if (current_block_ == current_function_->Block() && r->Args().IsEmpty()) {
+        return;
+    }
+
+    auto out = Line();
+    out << "return";
+    // TODO(dsinclair): Handle return args
+    // if (!r->Args().IsEmpty()) {
+    //     out << " " << Expr(r->Args().Front());
+    // }
+    out << ";";
+}
+
+void Printer::EmitUnreachable() {
+    Line() << "/* unreachable */";
+}
+
 }  // namespace tint::glsl::writer
diff --git a/src/tint/lang/glsl/writer/printer/printer.h b/src/tint/lang/glsl/writer/printer/printer.h
index a18a834..5df46df 100644
--- a/src/tint/lang/glsl/writer/printer/printer.h
+++ b/src/tint/lang/glsl/writer/printer/printer.h
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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.
 
 #ifndef SRC_TINT_LANG_GLSL_WRITER_PRINTER_PRINTER_H_
 #define SRC_TINT_LANG_GLSL_WRITER_PRINTER_PRINTER_H_
@@ -18,6 +31,7 @@
 #include <string>
 
 #include "src/tint/lang/core/ir/module.h"
+#include "src/tint/lang/glsl/writer/common/version.h"
 #include "src/tint/utils/generator/text_generator.h"
 
 // Forward declarations
@@ -42,17 +56,45 @@
     explicit Printer(core::ir::Module& module);
     ~Printer() override;
 
+    /// @param version the GLSL version information
     /// @returns success or failure
-    tint::Result<SuccessType> Generate();
+    tint::Result<SuccessType> Generate(Version version);
 
     /// @copydoc tint::TextGenerator::Result
     std::string Result() const override;
 
   private:
+    /// Emit the function
+    /// @param func the function to emit
+    void EmitFunction(core::ir::Function* func);
+
+    /// Emit a block
+    /// @param block the block to emit
+    void EmitBlock(core::ir::Block* block);
+    /// Emit the instructions in a block
+    /// @param block the block with the instructions to emit
+    void EmitBlockInstructions(core::ir::Block* block);
+
+    /// Emit a return instruction
+    /// @param r the return instruction
+    void EmitReturn(core::ir::Return* r);
+    /// Emit an unreachable instruction
+    void EmitUnreachable();
+
+    /// 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);
+
     core::ir::Module& ir_;
 
     /// The buffer holding preamble text
     TextBuffer preamble_buffer_;
+
+    /// The current function being emitted
+    core::ir::Function* current_function_ = nullptr;
+    /// The current block being emitted
+    core::ir::Block* current_block_ = nullptr;
 };
 
 }  // namespace tint::glsl::writer
diff --git a/src/tint/lang/glsl/writer/raise/raise.cc b/src/tint/lang/glsl/writer/raise/raise.cc
index c038911..33c17e9 100644
--- a/src/tint/lang/glsl/writer/raise/raise.cc
+++ b/src/tint/lang/glsl/writer/raise/raise.cc
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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/raise/raise.h"
 
diff --git a/src/tint/lang/glsl/writer/raise/raise.h b/src/tint/lang/glsl/writer/raise/raise.h
index 137f262..2ff1489 100644
--- a/src/tint/lang/glsl/writer/raise/raise.h
+++ b/src/tint/lang/glsl/writer/raise/raise.h
@@ -1,16 +1,29 @@
-// Copyright 2023 The Tint Authors.
+// Copyright 2023 The Dawn & 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
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
 //
-//     http://www.apache.org/licenses/LICENSE-2.0
+// 1. Redistributions of source code must retain the above copyright notice, this
+//    list of conditions and the following disclaimer.
 //
-// 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.
+// 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.
 
 #ifndef SRC_TINT_LANG_GLSL_WRITER_RAISE_RAISE_H_
 #define SRC_TINT_LANG_GLSL_WRITER_RAISE_RAISE_H_
diff --git a/src/tint/lang/glsl/writer/writer.cc b/src/tint/lang/glsl/writer/writer.cc
index f5743d5..bc0f045 100644
--- a/src/tint/lang/glsl/writer/writer.cc
+++ b/src/tint/lang/glsl/writer/writer.cc
@@ -72,7 +72,7 @@
 
         // Generate the GLSL code.
         auto impl = std::make_unique<Printer>(ir);
-        auto result = impl->Generate();
+        auto result = impl->Generate(options.version);
         if (!result) {
             return result.Failure();
         }