Move tint writer options into GLSL request.

This CL moves the options which are passed to the tint writer for the
GLSL backend out of the compilation callback and passes them directly
through the `GlslCompilationRequest`. This should incur less copying of
the data in the request.

Change-Id: I070fb7a71bf6e27fbc208533df76acc608b47351
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/156363
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/dawn/native/StreamImplTint.cpp b/src/dawn/native/StreamImplTint.cpp
index 14b82de..b023ae2 100644
--- a/src/dawn/native/StreamImplTint.cpp
+++ b/src/dawn/native/StreamImplTint.cpp
@@ -58,6 +58,33 @@
     StreamInTintObject(options, sink);
 }
 
+#if TINT_BUILD_GLSL_WRITER
+// static
+template <>
+void stream::Stream<tint::glsl::writer::Options>::Write(
+    stream::Sink* sink,
+    const tint::glsl::writer::Options& options) {
+    StreamInTintObject(options, sink);
+}
+
+// static
+template <>
+void stream::Stream<tint::glsl::writer::Version>::Write(
+    stream::Sink* sink,
+    const tint::glsl::writer::Version& version) {
+    StreamInTintObject(version, sink);
+}
+
+// static
+template <>
+void stream::Stream<tint::glsl::writer::SamplerTexturePair>::Write(
+    stream::Sink* sink,
+    const tint::glsl::writer::SamplerTexturePair& options) {
+    StreamInTintObject(options, sink);
+}
+
+#endif  // TINT_BUILD_GLSL_WRITER
+
 // static
 template <>
 void stream::Stream<tint::BindingPoint>::Write(stream::Sink* sink,
diff --git a/src/dawn/native/opengl/ShaderModuleGL.cpp b/src/dawn/native/opengl/ShaderModuleGL.cpp
index aa668f4..76a0d28 100644
--- a/src/dawn/native/opengl/ShaderModuleGL.cpp
+++ b/src/dawn/native/opengl/ShaderModuleGL.cpp
@@ -75,26 +75,18 @@
     X(const tint::Program*, inputProgram)                                                        \
     X(std::string, entryPointName)                                                               \
     X(SingleShaderStage, stage)                                                                  \
-    X(tint::ExternalTextureOptions, externalTextureOptions)                                      \
-    X(BindingMap, glBindings)                                                                    \
-    X(BindingMap, externalTextureExpansionMap)                                                   \
-    X(tint::TextureBuiltinsFromUniformOptions, textureBuiltinsFromUniform)                       \
     X(std::optional<tint::ast::transform::SubstituteOverride::Config>, substituteOverrideConfig) \
     X(LimitsForCompilationRequest, limits)                                                       \
-    X(opengl::OpenGLVersion::Standard, glVersionStandard)                                        \
-    X(uint32_t, glVersionMajor)                                                                  \
-    X(uint32_t, glVersionMinor)                                                                  \
+    X(tint::glsl::writer::Options, tintOptions)                                                  \
     X(CacheKey::UnsafeUnkeyedValue<dawn::platform::Platform*>, platform)
 
 DAWN_MAKE_CACHE_REQUEST(GLSLCompilationRequest, GLSL_COMPILATION_REQUEST_MEMBERS);
 #undef GLSL_COMPILATION_REQUEST_MEMBERS
 
-#define GLSL_COMPILATION_MEMBERS(X)                                                              \
-    X(std::string, glsl)                                                                         \
-    X(bool, needsPlaceholderSampler)                                                             \
-    X(bool, needsInternalUniformBuffer)                                                          \
-    X(tint::TextureBuiltinsFromUniformOptions::BindingPointToFieldAndOffset, bindingPointToData) \
-    X(opengl::CombinedSamplerInfo, combinedSamplerInfo)
+#define GLSL_COMPILATION_MEMBERS(X)     \
+    X(std::string, glsl)                \
+    X(bool, needsInternalUniformBuffer) \
+    X(tint::TextureBuiltinsFromUniformOptions::BindingPointToFieldAndOffset, bindingPointToData)
 
 DAWN_SERIALIZABLE(struct, GLSLCompilation, GLSL_COMPILATION_MEMBERS){};
 #undef GLSL_COMPILATION_MEMBERS
@@ -226,17 +218,59 @@
     req.inputProgram = GetTintProgram();
     req.stage = stage;
     req.entryPointName = programmableStage.entryPoint;
-    req.externalTextureOptions = BuildExternalTextureTransformBindings(layout);
-    req.glBindings = std::move(glBindings);
-    req.externalTextureExpansionMap = std::move(externalTextureExpansionMap);
-    req.textureBuiltinsFromUniform = std::move(textureBuiltinsFromUniform);
     req.substituteOverrideConfig = std::move(substituteOverrideConfig);
     req.limits = LimitsForCompilationRequest::Create(limits.v1);
-    req.glVersionStandard = version.GetStandard();
-    req.glVersionMajor = version.GetMajor();
-    req.glVersionMinor = version.GetMinor();
     req.platform = UnsafeUnkeyedValue(GetDevice()->GetPlatform());
 
+    req.tintOptions.version = tint::glsl::writer::Version(ToTintGLStandard(version.GetStandard()),
+                                                          version.GetMajor(), version.GetMinor());
+
+    req.tintOptions.disable_robustness = false;
+
+    req.tintOptions.external_texture_options = BuildExternalTextureTransformBindings(layout);
+    req.tintOptions.binding_remapper_options.binding_points = std::move(glBindings);
+    req.tintOptions.texture_builtins_from_uniform = std::move(textureBuiltinsFromUniform);
+
+    // When textures are accessed without a sampler (e.g., textureLoad()),
+    // GetSamplerTextureUses() will return this sentinel value.
+    BindingPoint placeholderBindingPoint{static_cast<uint32_t>(kMaxBindGroupsTyped), 0};
+
+    *needsPlaceholderSampler = false;
+    tint::inspector::Inspector inspector(*req.inputProgram);
+    // Find all the sampler/texture pairs for this entry point, and create
+    // CombinedSamplers for them. CombinedSampler records the binding points
+    // of the original texture and sampler, and generates a unique name. The
+    // corresponding uniforms will be retrieved by these generated names
+    // in PipelineGL. Any texture-only references will have
+    // "usePlaceholderSampler" set to true, and only the texture binding point
+    // will be used in naming them. In addition, Dawn will bind a
+    // non-filtering sampler for them (see PipelineGL).
+    auto uses =
+        inspector.GetSamplerTextureUses(programmableStage.entryPoint, placeholderBindingPoint);
+    CombinedSamplerInfo combinedSamplerInfo;
+    for (const auto& use : uses) {
+        CombinedSampler* info =
+            AppendCombinedSampler(&combinedSamplerInfo, use, placeholderBindingPoint);
+
+        if (info->usePlaceholderSampler) {
+            *needsPlaceholderSampler = true;
+            req.tintOptions.placeholder_binding_point = placeholderBindingPoint;
+        }
+        req.tintOptions.binding_map[use] = info->GetName();
+
+        // If the texture has an associated plane1 texture (ie., it's an external texture),
+        // append a new combined sampler with the same sampler and the plane1 texture.
+        BindingMap::iterator plane1Texture =
+            externalTextureExpansionMap.find(use.texture_binding_point);
+        if (plane1Texture != externalTextureExpansionMap.end()) {
+            tint::inspector::SamplerTexturePair plane1Use{use.sampler_binding_point,
+                                                          plane1Texture->second};
+            CombinedSampler* plane1Info =
+                AppendCombinedSampler(&combinedSamplerInfo, plane1Use, placeholderBindingPoint);
+            req.tintOptions.binding_map[plane1Use] = plane1Info->GetName();
+        }
+    }
+
     CacheResult<GLSLCompilation> compilationResult;
     DAWN_TRY_LOAD_OR_RUN(
         compilationResult, GetDevice(), std::move(req), GLSLCompilation::FromBlob,
@@ -267,63 +301,12 @@
                                        program, r.entryPointName.c_str(), r.limits));
             }
 
-            tint::glsl::writer::Options tintOptions;
-            tintOptions.version = tint::glsl::writer::Version(ToTintGLStandard(r.glVersionStandard),
-                                                              r.glVersionMajor, r.glVersionMinor);
-
-            tintOptions.disable_robustness = false;
-
-            tintOptions.external_texture_options = r.externalTextureOptions;
-
-            // When textures are accessed without a sampler (e.g., textureLoad()),
-            // GetSamplerTextureUses() will return this sentinel value.
-            BindingPoint placeholderBindingPoint{static_cast<uint32_t>(kMaxBindGroupsTyped), 0};
-
-            bool needsPlaceholderSampler = false;
-            tint::inspector::Inspector inspector(program);
-            // Find all the sampler/texture pairs for this entry point, and create
-            // CombinedSamplers for them. CombinedSampler records the binding points
-            // of the original texture and sampler, and generates a unique name. The
-            // corresponding uniforms will be retrieved by these generated names
-            // in PipelineGL. Any texture-only references will have
-            // "usePlaceholderSampler" set to true, and only the texture binding point
-            // will be used in naming them. In addition, Dawn will bind a
-            // non-filtering sampler for them (see PipelineGL).
-            auto uses = inspector.GetSamplerTextureUses(r.entryPointName, placeholderBindingPoint);
-            CombinedSamplerInfo combinedSamplerInfo;
-            for (const auto& use : uses) {
-                CombinedSampler* info =
-                    AppendCombinedSampler(&combinedSamplerInfo, use, placeholderBindingPoint);
-
-                if (info->usePlaceholderSampler) {
-                    needsPlaceholderSampler = true;
-                    tintOptions.placeholder_binding_point = placeholderBindingPoint;
-                }
-                tintOptions.binding_map[use] = info->GetName();
-
-                // If the texture has an associated plane1 texture (ie., it's an external texture),
-                // append a new combined sampler with the same sampler and the plane1 texture.
-                BindingMap::iterator plane1Texture =
-                    r.externalTextureExpansionMap.find(use.texture_binding_point);
-                if (plane1Texture != r.externalTextureExpansionMap.end()) {
-                    tint::inspector::SamplerTexturePair plane1Use{use.sampler_binding_point,
-                                                                  plane1Texture->second};
-                    CombinedSampler* plane1Info = AppendCombinedSampler(
-                        &combinedSamplerInfo, plane1Use, placeholderBindingPoint);
-                    tintOptions.binding_map[plane1Use] = plane1Info->GetName();
-                }
-            }
-
-            tintOptions.binding_remapper_options.binding_points = std::move(r.glBindings);
-            tintOptions.texture_builtins_from_uniform = r.textureBuiltinsFromUniform;
-
-            auto result = tint::glsl::writer::Generate(program, tintOptions, r.entryPointName);
+            auto result = tint::glsl::writer::Generate(program, r.tintOptions, r.entryPointName);
             DAWN_INVALID_IF(!result, "An error occurred while generating GLSL:\n%s",
                             result.Failure().reason.str());
 
-            return GLSLCompilation{{std::move(result->glsl), needsPlaceholderSampler,
-                                    result->needs_internal_uniform_buffer,
-                                    result->bindpoint_to_data, std::move(combinedSamplerInfo)}};
+            return GLSLCompilation{{std::move(result->glsl), result->needs_internal_uniform_buffer,
+                                    result->bindpoint_to_data}};
         },
         "OpenGL.CompileShaderToGLSL");
 
@@ -355,7 +338,6 @@
     }
 
     GetDevice()->GetBlobCache()->EnsureStored(compilationResult);
-    *needsPlaceholderSampler = compilationResult->needsPlaceholderSampler;
     *needsTextureBuiltinUniformBuffer = compilationResult->needsInternalUniformBuffer;
 
     // Since the TextureBuiltinsFromUniform transform runs before BindingRemapper,
@@ -371,7 +353,7 @@
         bindingPointToData->emplace(bindingPoint, e.second);
     }
 
-    *combinedSamplers = std::move(compilationResult->combinedSamplerInfo);
+    *combinedSamplers = std::move(combinedSamplerInfo);
     return shader;
 }
 
diff --git a/src/tint/lang/glsl/writer/common/options.h b/src/tint/lang/glsl/writer/common/options.h
index 2c9fdcd..a14b8c8 100644
--- a/src/tint/lang/glsl/writer/common/options.h
+++ b/src/tint/lang/glsl/writer/common/options.h
@@ -28,7 +28,8 @@
 
 namespace tint::glsl::writer {
 
-using BindingMap = std::unordered_map<sem::SamplerTexturePair, std::string>;
+using SamplerTexturePair = sem::SamplerTexturePair;
+using BindingMap = std::unordered_map<SamplerTexturePair, std::string>;
 
 /// Configuration options used for generating GLSL.
 struct Options {
diff --git a/src/tint/lang/glsl/writer/common/version.h b/src/tint/lang/glsl/writer/common/version.h
index 0f01a4d..fa5e2df 100644
--- a/src/tint/lang/glsl/writer/common/version.h
+++ b/src/tint/lang/glsl/writer/common/version.h
@@ -17,6 +17,8 @@
 
 #include <cstdint>
 
+#include "src/tint/utils/reflection/reflection.h"
+
 namespace tint::glsl::writer {
 
 /// A structure representing the version of GLSL to be generated.
@@ -51,6 +53,9 @@
 
     /// Minor GLSL version
     uint32_t minor_version = 1;
+
+    /// Reflect the fields of this class so that it can be used by tint::ForeachField()
+    TINT_REFLECT(standard, major_version, minor_version);
 };
 
 }  // namespace tint::glsl::writer
diff --git a/src/tint/lang/wgsl/sem/sampler_texture_pair.h b/src/tint/lang/wgsl/sem/sampler_texture_pair.h
index f20562a..7170f49 100644
--- a/src/tint/lang/wgsl/sem/sampler_texture_pair.h
+++ b/src/tint/lang/wgsl/sem/sampler_texture_pair.h
@@ -19,6 +19,7 @@
 #include <functional>
 
 #include "src/tint/api/common/binding_point.h"
+#include "src/tint/utils/reflection/reflection.h"
 #include "src/tint/utils/text/string_stream.h"
 
 namespace tint::sem {
@@ -42,6 +43,19 @@
     /// @param rhs the SamplerTexturePair to compare against
     /// @returns true if this SamplerTexturePair is not equal to `rhs`
     inline bool operator!=(const SamplerTexturePair& rhs) const { return !(*this == rhs); }
+
+    /// Less than operator
+    /// @param rhs the SamplerTexturePair to compare against
+    /// @returns true if this SamplerTexturePair is less then `rhs`
+    inline bool operator<(const SamplerTexturePair& rhs) const {
+        if (sampler_binding_point == rhs.sampler_binding_point) {
+            return texture_binding_point < rhs.texture_binding_point;
+        }
+        return sampler_binding_point < rhs.sampler_binding_point;
+    }
+
+    /// Reflect the fields of this class so that it can be used by tint::ForeachField()
+    TINT_REFLECT(sampler_binding_point, texture_binding_point);
 };
 
 /// Prints the SamplerTexturePair @p stp to @p o