Import Tint changes from Dawn

Changes:
  - bfebbf03cd28ab1c1ef646823de594b7b6c9bd4f Move tint writer outputs into the SPIRV request. by dan sinclair <dsinclair@chromium.org>
  - d2eb05cdd56d40a0cc21a8a5efa61a968eaeec10 GLSL validation: don't print error message twice. by Stephen White <senorblanco@chromium.org>
  - 39c8708eab8bb0decec9675be0a0b19857e02e70 tint: avoid copying iterator by Antonio Maiorano <amaiorano@google.com>
GitOrigin-RevId: bfebbf03cd28ab1c1ef646823de594b7b6c9bd4f
Change-Id: I1e665fd6eca19c1d3e64f7c678b84f7ac9d172b6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/156500
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/cmd/tint/main.cc b/src/tint/cmd/tint/main.cc
index 31e4522..40ffd5d 100644
--- a/src/tint/cmd/tint/main.cc
+++ b/src/tint/cmd/tint/main.cc
@@ -926,7 +926,7 @@
 #else
             auto val = tint::glsl::validate::Validate(result->glsl, result->entry_points);
             if (!val) {
-                std::cerr << "Error parsing GLSL shader:\n" << val.Failure();
+                std::cerr << val.Failure();
                 return false;
             }
 #endif
diff --git a/src/tint/lang/spirv/writer/common/option_builder.cc b/src/tint/lang/spirv/writer/common/option_builder.cc
index 1bec1e9..66df1e4 100644
--- a/src/tint/lang/spirv/writer/common/option_builder.cc
+++ b/src/tint/lang/spirv/writer/common/option_builder.cc
@@ -25,7 +25,7 @@
     auto wgsl_seen = [&diagnostics, &seen_wgsl_bindings](const tint::BindingPoint& info) -> bool {
         if (seen_wgsl_bindings.Contains(info)) {
             std::stringstream str;
-            str << "Found duplicate WGSL binding point: " << info;
+            str << "found duplicate WGSL binding point: " << info;
 
             diagnostics.add_error(diag::System::Writer, str.str());
             return true;
@@ -38,7 +38,7 @@
                        &seen_spirv_bindings](const binding::BindingInfo& info) -> bool {
         if (seen_spirv_bindings.Contains(info)) {
             std::stringstream str;
-            str << "Found duplicate SPIR-V binding point: [group: " << info.group
+            str << "found duplicate SPIR-V binding point: [group: " << info.group
                 << ", binding: " << info.binding << "]";
             diagnostics.add_error(diag::System::Writer, str.str());
             return true;
@@ -48,7 +48,7 @@
     };
 
     auto valid = [&wgsl_seen, &spirv_seen](const auto& hsh) -> bool {
-        for (const auto it : hsh) {
+        for (const auto& it : hsh) {
             const auto& src_binding = it.first;
             const auto& dst_binding = it.second;
 
@@ -64,27 +64,27 @@
     };
 
     if (!valid(options.bindings.uniform)) {
-        diagnostics.add_note(diag::System::Writer, "When processing uniform", {});
+        diagnostics.add_note(diag::System::Writer, "when processing uniform", {});
         return false;
     }
     if (!valid(options.bindings.storage)) {
-        diagnostics.add_note(diag::System::Writer, "When processing storage", {});
+        diagnostics.add_note(diag::System::Writer, "when processing storage", {});
         return false;
     }
     if (!valid(options.bindings.texture)) {
-        diagnostics.add_note(diag::System::Writer, "When processing texture", {});
+        diagnostics.add_note(diag::System::Writer, "when processing texture", {});
         return false;
     }
     if (!valid(options.bindings.storage_texture)) {
-        diagnostics.add_note(diag::System::Writer, "When processing storage_texture", {});
+        diagnostics.add_note(diag::System::Writer, "when processing storage_texture", {});
         return false;
     }
     if (!valid(options.bindings.sampler)) {
-        diagnostics.add_note(diag::System::Writer, "When processing sampler", {});
+        diagnostics.add_note(diag::System::Writer, "when processing sampler", {});
         return false;
     }
 
-    for (const auto it : options.bindings.external_texture) {
+    for (const auto& it : options.bindings.external_texture) {
         const auto& src_binding = it.first;
         const auto& plane0 = it.second.plane0;
         const auto& plane1 = it.second.plane1;
@@ -92,20 +92,20 @@
 
         // Validate with the actual source regardless of what the remapper will do
         if (wgsl_seen(src_binding)) {
-            diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+            diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
             return false;
         }
 
         if (spirv_seen(plane0)) {
-            diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+            diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
             return false;
         }
         if (spirv_seen(plane1)) {
-            diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+            diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
             return false;
         }
         if (spirv_seen(metadata)) {
-            diagnostics.add_note(diag::System::Writer, "When processing external_texture", {});
+            diagnostics.add_note(diag::System::Writer, "when processing external_texture", {});
             return false;
         }
     }
@@ -158,7 +158,7 @@
                                            RemapperData& remapper_data,
                                            ExternalTextureOptions& external_texture) {
     auto create_remappings = [&remapper_data](const auto& hsh) {
-        for (const auto it : hsh) {
+        for (const auto& it : hsh) {
             const BindingPoint& src_binding_point = it.first;
             const binding::Uniform& dst_binding_point = it.second;
 
@@ -180,7 +180,7 @@
     create_remappings(options.bindings.sampler);
 
     // External textures are re-bound to their plane0 location
-    for (const auto it : options.bindings.external_texture) {
+    for (const auto& it : options.bindings.external_texture) {
         const BindingPoint& src_binding_point = it.first;
         const binding::BindingInfo& plane0 = it.second.plane0;
         const binding::BindingInfo& plane1 = it.second.plane1;
diff --git a/src/tint/lang/spirv/writer/helpers/generate_bindings.cc b/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
index 0285b0b..5ed371c 100644
--- a/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
+++ b/src/tint/lang/spirv/writer/helpers/generate_bindings.cc
@@ -25,6 +25,8 @@
 #include "src/tint/lang/wgsl/ast/module.h"
 #include "src/tint/lang/wgsl/program/program.h"
 #include "src/tint/lang/wgsl/sem/variable.h"
+#include "src/tint/utils/containers/hashmap.h"
+#include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/rtti/switch.h"
 
 namespace tint::spirv::writer {
@@ -38,31 +40,34 @@
     std::unordered_set<tint::BindingPoint> seen_binding_points;
 
     // Collect next valid binding number per group
-    std::unordered_map<uint32_t, uint32_t> group_to_next_binding_number;
-    std::vector<tint::BindingPoint> ext_tex_bps;
+    Hashmap<uint32_t, uint32_t, 4> group_to_next_binding_number;
+    Vector<tint::BindingPoint, 4> ext_tex_bps;
     for (auto* var : program.AST().GlobalVariables()) {
         if (auto* sem_var = program.Sem().Get(var)->As<sem::GlobalVariable>()) {
             if (auto bp = sem_var->BindingPoint()) {
                 // This is a bit of a hack. The binding points must be unique over all the `binding`
                 // entries. But, this is looking at _all_ entry points where bindings can overlap.
                 // In the case where both entry points used the same type (uniform, sampler, etc)
-                // then it woudl be fine as it just overwrites with itself. But, if one entry point
+                // then it would be fine as it just overwrites with itself. But, if one entry point
                 // has a uniform and the other a sampler at the same (group,binding) pair then we'll
                 // get a validation error due to duplicate WGSL bindings.
                 //
-                // For generate bindings we don't really care as we always map to itself, so if it
+                // For generating bindings we don't really care as we always map to itself, so if it
                 // exists anywhere, we just pretend that's the only one.
                 if (seen_binding_points.find(*bp) != seen_binding_points.end()) {
                     continue;
                 }
                 seen_binding_points.emplace(*bp);
 
-                auto& n = group_to_next_binding_number[bp->group];
-                n = std::max(n, bp->binding + 1);
+                if (auto val = group_to_next_binding_number.Find(bp->group)) {
+                    *val = std::max(*val, bp->binding + 1);
+                } else {
+                    group_to_next_binding_number.Add(bp->group, bp->binding + 1);
+                }
 
                 // Store up the external textures, we'll add them in the next step
                 if (sem_var->Type()->UnwrapRef()->Is<core::type::ExternalTexture>()) {
-                    ext_tex_bps.emplace_back(*bp);
+                    ext_tex_bps.Push(*bp);
                     continue;
                 }
 
@@ -104,12 +109,14 @@
 
     for (auto bp : ext_tex_bps) {
         uint32_t g = bp.group;
-        uint32_t& next_num = group_to_next_binding_number[g];
+        uint32_t next_num = *(group_to_next_binding_number.GetOrZero(g));
 
         binding::BindingInfo plane0{bp.group, bp.binding};
         binding::BindingInfo plane1{g, next_num++};
         binding::BindingInfo metadata{g, next_num++};
 
+        group_to_next_binding_number.Replace(g, next_num);
+
         bindings.external_texture.emplace(bp, binding::ExternalTexture{metadata, plane0, plane1});
     }