[glsl] Set up internal push constants

Use the PreparePushConstants transform to create entries for all
provided offsets.

Bug: 42251044
Change-Id: I4d6d6a9703d9ad0d43376c6b62d4ec72907e0107
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/209535
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: James Price <jrprice@google.com>
diff --git a/src/tint/lang/glsl/writer/common/options.h b/src/tint/lang/glsl/writer/common/options.h
index a9c9fdd..aabe86c 100644
--- a/src/tint/lang/glsl/writer/common/options.h
+++ b/src/tint/lang/glsl/writer/common/options.h
@@ -259,10 +259,10 @@
     Version version;
 
     /// Offset of the firstVertex push constant.
-    std::optional<int32_t> first_vertex_offset;
+    std::optional<uint32_t> first_vertex_offset;
 
     /// Offset of the firstInstance push constant.
-    std::optional<int32_t> first_instance_offset;
+    std::optional<uint32_t> first_instance_offset;
 
     /// Offsets of the minDepth and maxDepth push constants.
     std::optional<RangeOffsets> depth_range_offsets;
diff --git a/src/tint/lang/glsl/writer/raise/raise.cc b/src/tint/lang/glsl/writer/raise/raise.cc
index 4817271..91d2037 100644
--- a/src/tint/lang/glsl/writer/raise/raise.cc
+++ b/src/tint/lang/glsl/writer/raise/raise.cc
@@ -27,6 +27,7 @@
 
 #include "src/tint/lang/glsl/writer/raise/raise.h"
 
+#include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/transform/add_empty_entry_point.h"
 #include "src/tint/lang/core/ir/transform/array_length_from_uniform.h"
 #include "src/tint/lang/core/ir/transform/bgra8unorm_polyfill.h"
@@ -38,6 +39,7 @@
 #include "src/tint/lang/core/ir/transform/demote_to_helper.h"
 #include "src/tint/lang/core/ir/transform/direct_variable_access.h"
 #include "src/tint/lang/core/ir/transform/multiplanar_external_texture.h"
+#include "src/tint/lang/core/ir/transform/prepare_push_constants.h"
 #include "src/tint/lang/core/ir/transform/preserve_padding.h"
 #include "src/tint/lang/core/ir/transform/remove_continue_in_switch.h"
 #include "src/tint/lang/core/ir/transform/remove_terminator_args.h"
@@ -47,6 +49,8 @@
 #include "src/tint/lang/core/ir/transform/value_to_let.h"
 #include "src/tint/lang/core/ir/transform/vectorize_scalar_matrix_constructors.h"
 #include "src/tint/lang/core/ir/transform/zero_init_workgroup_memory.h"
+#include "src/tint/lang/core/type/f32.h"
+#include "src/tint/lang/core/type/u32.h"
 #include "src/tint/lang/glsl/writer/common/option_helpers.h"
 #include "src/tint/lang/glsl/writer/raise/binary_polyfill.h"
 #include "src/tint/lang/glsl/writer/raise/bitcast_polyfill.h"
@@ -72,6 +76,32 @@
         RUN_TRANSFORM(core::ir::transform::Robustness, module, config);
     }
 
+    // PreparePushConstants must come before any transform that needs internal push constants.
+    core::ir::transform::PreparePushConstantsConfig push_constant_config;
+    if (options.first_instance_offset) {
+        push_constant_config.AddInternalConstant(options.first_instance_offset.value(),
+                                                 module.symbols.New("tint_first_instance"),
+                                                 module.Types().u32());
+    }
+    if (options.first_vertex_offset) {
+        push_constant_config.AddInternalConstant(options.first_vertex_offset.value(),
+                                                 module.symbols.New("tint_first_vertex"),
+                                                 module.Types().u32());
+    }
+    if (options.depth_range_offsets) {
+        push_constant_config.AddInternalConstant(options.depth_range_offsets.value().min,
+                                                 module.symbols.New("tint_frag_depth_min"),
+                                                 module.Types().f32());
+        push_constant_config.AddInternalConstant(options.depth_range_offsets.value().max,
+                                                 module.symbols.New("tint_frag_depth_max"),
+                                                 module.Types().f32());
+    }
+    auto push_constant_layout =
+        core::ir::transform::PreparePushConstants(module, push_constant_config);
+    if (push_constant_layout != Success) {
+        return push_constant_layout.Failure();
+    }
+
     // Note, this comes before binding remapper as Dawn inserts _pre-remapping_ binding information.
     // So, in order to move this later we'd need to update Dawn to send the _post-remapping_ data.
     RUN_TRANSFORM(raise::TextureBuiltinsFromUniform, module,
diff --git a/test/tint/bug/chromium/1251009.wgsl.expected.ir.glsl b/test/tint/bug/chromium/1251009.wgsl.expected.ir.glsl
index 3253d55..bd82bea 100644
--- a/test/tint/bug/chromium/1251009.wgsl.expected.ir.glsl
+++ b/test/tint/bug/chromium/1251009.wgsl.expected.ir.glsl
@@ -1,6 +1,10 @@
 #version 310 es
 
 
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
 struct VertexInputs0 {
   uint vertex_index;
   int loc0;
@@ -11,6 +15,7 @@
   vec4 loc3;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 layout(location = 0) in int tint_symbol_loc0_Input;
 layout(location = 1) in uint tint_symbol_loc1_Input;
 layout(location = 2) in uint tint_symbol_loc2_Input;
diff --git a/test/tint/bug/tint/824.wgsl.expected.ir.glsl b/test/tint/bug/tint/824.wgsl.expected.ir.glsl
index 13d996e..998732c 100644
--- a/test/tint/bug/tint/824.wgsl.expected.ir.glsl
+++ b/test/tint/bug/tint/824.wgsl.expected.ir.glsl
@@ -1,11 +1,16 @@
 #version 310 es
 
 
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
 struct Output {
   vec4 Position;
   vec4 color;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 layout(location = 0) out vec4 tint_symbol_loc0_Output;
 Output tint_symbol_inner(uint VertexIndex, uint InstanceIndex) {
   vec2 zv[4] = vec2[4](vec2(0.20000000298023223877f), vec2(0.30000001192092895508f), vec2(-0.10000000149011611938f), vec2(1.10000002384185791016f));
diff --git a/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.ir.glsl
index 44592b7..789ea76 100644
--- a/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/fragment_output_builtins.wgsl.expected.ir.glsl
@@ -2,6 +2,13 @@
 precision highp float;
 precision highp int;
 
+
+struct tint_push_constant_struct {
+  float tint_frag_depth_min;
+  float tint_frag_depth_max;
+};
+
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 float main1_inner() {
   return 1.0f;
 }
diff --git a/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.ir.glsl
index 0c2221b..3d6f909 100644
--- a/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/fragment_output_builtins_struct.wgsl.expected.ir.glsl
@@ -4,11 +4,17 @@
 precision highp int;
 
 
+struct tint_push_constant_struct {
+  float tint_frag_depth_min;
+  float tint_frag_depth_max;
+};
+
 struct FragmentOutputs {
   float frag_depth;
   uint sample_mask;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 FragmentOutputs tint_symbol_inner() {
   return FragmentOutputs(1.0f, 1u);
 }
diff --git a/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.ir.glsl
index edadaeb..42f7bc4 100644
--- a/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/fragment_output_mixed.wgsl.expected.ir.glsl
@@ -4,6 +4,11 @@
 precision highp int;
 
 
+struct tint_push_constant_struct {
+  float tint_frag_depth_min;
+  float tint_frag_depth_max;
+};
+
 struct FragmentOutputs {
   int loc0;
   float frag_depth;
@@ -13,6 +18,7 @@
   vec4 loc3;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 layout(location = 0) out int tint_symbol_loc0_Output;
 layout(location = 1) out uint tint_symbol_loc1_Output;
 layout(location = 2) out float tint_symbol_loc2_Output;
diff --git a/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.ir.glsl
index ea78395..8a9b3d8 100644
--- a/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/fragment_output_mixed_f16.wgsl.expected.ir.glsl
@@ -5,6 +5,11 @@
 precision highp int;
 
 
+struct tint_push_constant_struct {
+  float tint_frag_depth_min;
+  float tint_frag_depth_max;
+};
+
 struct FragmentOutputs {
   int loc0;
   float frag_depth;
@@ -16,6 +21,7 @@
   f16vec3 loc5;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 layout(location = 0) out int tint_symbol_loc0_Output;
 layout(location = 1) out uint tint_symbol_loc1_Output;
 layout(location = 2) out float tint_symbol_loc2_Output;
diff --git a/test/tint/types/functions/shader_io/vertex_input_builtins.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/vertex_input_builtins.wgsl.expected.ir.glsl
index bb08ff6..69964dc 100644
--- a/test/tint/types/functions/shader_io/vertex_input_builtins.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/vertex_input_builtins.wgsl.expected.ir.glsl
@@ -1,5 +1,11 @@
 #version 310 es
 
+
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 vec4 tint_symbol_inner(uint vertex_index, uint instance_index) {
   uint foo = (vertex_index + instance_index);
   return vec4(0.0f);
diff --git a/test/tint/types/functions/shader_io/vertex_input_builtins_struct.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/vertex_input_builtins_struct.wgsl.expected.ir.glsl
index f7a3d33..11b1fee 100644
--- a/test/tint/types/functions/shader_io/vertex_input_builtins_struct.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/vertex_input_builtins_struct.wgsl.expected.ir.glsl
@@ -1,11 +1,16 @@
 #version 310 es
 
 
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
 struct VertexInputs {
   uint vertex_index;
   uint instance_index;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 vec4 tint_symbol_inner(VertexInputs inputs) {
   uint foo = (inputs.vertex_index + inputs.instance_index);
   return vec4(0.0f);
diff --git a/test/tint/types/functions/shader_io/vertex_input_mixed.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/vertex_input_mixed.wgsl.expected.ir.glsl
index f7e41d8..19fc8ed 100644
--- a/test/tint/types/functions/shader_io/vertex_input_mixed.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/vertex_input_mixed.wgsl.expected.ir.glsl
@@ -1,6 +1,10 @@
 #version 310 es
 
 
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
 struct VertexInputs0 {
   uint vertex_index;
   int loc0;
@@ -11,6 +15,7 @@
   vec4 loc3;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 layout(location = 0) in int tint_symbol_loc0_Input;
 layout(location = 1) in uint tint_symbol_loc1_Input;
 layout(location = 2) in float tint_symbol_loc2_Input;
diff --git a/test/tint/types/functions/shader_io/vertex_input_mixed_f16.wgsl.expected.ir.glsl b/test/tint/types/functions/shader_io/vertex_input_mixed_f16.wgsl.expected.ir.glsl
index a650486..c66c061 100644
--- a/test/tint/types/functions/shader_io/vertex_input_mixed_f16.wgsl.expected.ir.glsl
+++ b/test/tint/types/functions/shader_io/vertex_input_mixed_f16.wgsl.expected.ir.glsl
@@ -2,6 +2,10 @@
 #extension GL_AMD_gpu_shader_half_float: require
 
 
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
 struct VertexInputs0 {
   uint vertex_index;
   int loc0;
@@ -13,6 +17,7 @@
   f16vec3 loc5;
 };
 
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 layout(location = 0) in int tint_symbol_loc0_Input;
 layout(location = 1) in uint tint_symbol_loc1_Input;
 layout(location = 2) in float tint_symbol_loc2_Input;
diff --git a/test/tint/var/uses/instance_index.wgsl.expected.ir.glsl b/test/tint/var/uses/instance_index.wgsl.expected.ir.glsl
index bae3a12..fe37517 100644
--- a/test/tint/var/uses/instance_index.wgsl.expected.ir.glsl
+++ b/test/tint/var/uses/instance_index.wgsl.expected.ir.glsl
@@ -1,5 +1,11 @@
 #version 310 es
 
+
+struct tint_push_constant_struct {
+  uint tint_first_instance;
+};
+
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 vec4 tint_symbol_inner(uint b) {
   return vec4(float(b));
 }
diff --git a/test/tint/var/uses/push_constant_and_instance_index.wgsl.expected.ir.glsl b/test/tint/var/uses/push_constant_and_instance_index.wgsl.expected.ir.glsl
index 10f12c0..e91048e 100644
--- a/test/tint/var/uses/push_constant_and_instance_index.wgsl.expected.ir.glsl
+++ b/test/tint/var/uses/push_constant_and_instance_index.wgsl.expected.ir.glsl
@@ -1,14 +1,15 @@
 #version 310 es
 
 
-struct tint_symbol_2 {
-  float tint_symbol_1;
+struct tint_push_constant_struct {
+  float user_constant;
+  uint tint_first_instance;
 };
 
-layout(location = 0) uniform tint_symbol_2 v;
+layout(location = 0) uniform tint_push_constant_struct tint_push_constants;
 vec4 tint_symbol_inner(uint b) {
-  float v_1 = v.tint_symbol_1;
-  return vec4((v_1 + float(b)));
+  float v = tint_push_constants.user_constant;
+  return vec4((v + float(b)));
 }
 void main() {
   gl_Position = tint_symbol_inner(uint(gl_InstanceID));