[glsl] Emit f32 and f16 types

Add emitting of f32 and f16 types and constants.

Bug: 42251044
Change-Id: Ib58d071b3d83248b38a9b5514c6ddc2224680e65
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/200243
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/glsl/writer/constant_test.cc b/src/tint/lang/glsl/writer/constant_test.cc
index 0de7fe3..a93d1a9 100644
--- a/src/tint/lang/glsl/writer/constant_test.cc
+++ b/src/tint/lang/glsl/writer/constant_test.cc
@@ -108,5 +108,38 @@
 )");
 }
 
+TEST_F(GlslWriterTest, ConstantFloat) {
+    auto* f = b.Function("a", ty.f32());
+    // Use a number close to 1<<30 but whose decimal representation ends in 0.
+    f->Block()->Append(b.Return(f, f32((1 << 30) - 4)));
+
+    ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+    EXPECT_EQ(output_.glsl, GlslHeader() + R"(
+float a() {
+  return 1073741824.0f;
+}
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+}
+)");
+}
+
+TEST_F(GlslWriterTest, ConstantF16) {
+    auto* f = b.Function("a", ty.f16());
+    // Use a number close to 1<<16 but whose decimal representation ends in 0.
+    f->Block()->Append(b.Return(f, f16((1 << 15) - 8)));
+
+    ASSERT_TRUE(Generate()) << err_ << output_.glsl;
+    EXPECT_EQ(output_.glsl, GlslHeader() + R"(#extension GL_AMD_gpu_shader_half_float: require
+
+float16_t a() {
+  return 32752.0hf;
+}
+layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
+void unused_entry_point() {
+}
+)");
+}
+
 }  // namespace
 }  // namespace tint::glsl::writer
diff --git a/src/tint/lang/glsl/writer/printer/printer.cc b/src/tint/lang/glsl/writer/printer/printer.cc
index 8e5455b..02012a4 100644
--- a/src/tint/lang/glsl/writer/printer/printer.cc
+++ b/src/tint/lang/glsl/writer/printer/printer.cc
@@ -36,6 +36,8 @@
 #include "src/tint/lang/core/ir/unreachable.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/core/type/bool.h"
+#include "src/tint/lang/core/type/f16.h"
+#include "src/tint/lang/core/type/f32.h"
 #include "src/tint/lang/core/type/i32.h"
 #include "src/tint/lang/core/type/u32.h"
 #include "src/tint/lang/core/type/void.h"
@@ -50,6 +52,8 @@
 namespace tint::glsl::writer {
 namespace {
 
+constexpr const char* kAMDGpuShaderHalfFloat = "GL_AMD_gpu_shader_half_float";
+
 /// PIMPL class for the MSL generator
 class Printer : public tint::TextGenerator {
   public:
@@ -99,6 +103,8 @@
     /// The current block being emitted
     const core::ir::Block* current_block_ = nullptr;
 
+    Hashset<std::string, 4> emitted_extensions_;
+
     /// Emit the function
     /// @param func the function to emit
     void EmitFunction(const core::ir::Function* func) {
@@ -154,16 +160,32 @@
         }
     }
 
+    void EmitExtension(std::string name) {
+        if (emitted_extensions_.Contains(name)) {
+            return;
+        }
+        emitted_extensions_.Add(name);
+
+        TINT_SCOPED_ASSIGNMENT(current_buffer_, &preamble_buffer_);
+
+        Line() << "#extension " << name << ": require";
+    }
+
     /// 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) {
         tint::Switch(
-            ty,                                               //
-            [&](const core::type::Bool*) { out << "bool"; },  //
-            [&](const core::type::I32*) { out << "int"; },    //
-            [&](const core::type::U32*) { out << "uint"; },   //
-            [&](const core::type::Void*) { out << "void"; },  //
+            ty,  //
+            [&](const core::type::Bool*) { out << "bool"; },
+            [&](const core::type::I32*) { out << "int"; },
+            [&](const core::type::U32*) { out << "uint"; },
+            [&](const core::type::Void*) { out << "void"; },
+            [&](const core::type::F32*) { out << "float"; },
+            [&](const core::type::F16*) {
+                EmitExtension(kAMDGpuShaderHalfFloat);
+                out << "float16_t";
+            },
 
             // TODO(dsinclair): Handle remaining types
             TINT_ICE_ON_NO_MATCH);
@@ -206,6 +228,8 @@
             [&](const core::type::Bool*) { out << (c->ValueAs<AInt>() ? "true" : "false"); },
             [&](const core::type::I32*) { PrintI32(out, c->ValueAs<i32>()); },
             [&](const core::type::U32*) { out << c->ValueAs<AInt>() << "u"; },
+            [&](const core::type::F32*) { PrintF32(out, c->ValueAs<f32>()); },
+            [&](const core::type::F16*) { PrintF16(out, c->ValueAs<f16>()); },
 
             // TODO(dsinclair): Emit remaining constant types
             TINT_ICE_ON_NO_MATCH);
diff --git a/src/tint/utils/generator/text_generator.h b/src/tint/utils/generator/text_generator.h
index e37e4c9..1585d46 100644
--- a/src/tint/utils/generator/text_generator.h
+++ b/src/tint/utils/generator/text_generator.h
@@ -29,7 +29,6 @@
 #define SRC_TINT_UTILS_GENERATOR_TEXT_GENERATOR_H_
 
 #include <string>
-#include <unordered_map>
 #include <utility>
 #include <vector>