[tint][spirv] Add support for binding_array in BuiltinPolyfill

The rewrite of the texture types into spirv.image need to handle the
inside of binding_array as well.

Bug: 411573958
Change-Id: I00629d18b904dca09f42bc139c2404dcb7a3bb7c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/237934
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
index 6db6703..662b8b9 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill.cc
@@ -34,6 +34,7 @@
 #include "src/tint/lang/core/ir/builder.h"
 #include "src/tint/lang/core/ir/module.h"
 #include "src/tint/lang/core/ir/validator.h"
+#include "src/tint/lang/core/type/binding_array.h"
 #include "src/tint/lang/core/type/builtin_structs.h"
 #include "src/tint/lang/core/type/depth_multisampled_texture.h"
 #include "src/tint/lang/core/type/depth_texture.h"
@@ -136,6 +137,13 @@
             }
             return nullptr;
         },
+        [&](const core::type::BindingArray* arr) -> const core::type::Type* {
+            if (auto* replacement = ReplacementType(ty, arr->ElemType())) {
+                return ty.binding_array(replacement,
+                                        arr->Count()->As<core::type::ConstantArrayCount>()->value);
+            }
+            return nullptr;
+        },
         [&](const core::type::Texture* tex) { return ImageFromTexture(ty, tex); },
         [&](Default) { return nullptr; });
 }
diff --git a/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc b/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc
index add2c03..3137682 100644
--- a/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc
+++ b/src/tint/lang/spirv/writer/raise/builtin_polyfill_test.cc
@@ -32,6 +32,7 @@
 #include "src/tint/lang/core/ir/transform/helper_test.h"
 #include "src/tint/lang/core/type/array.h"
 #include "src/tint/lang/core/type/atomic.h"
+#include "src/tint/lang/core/type/binding_array.h"
 #include "src/tint/lang/core/type/builtin_structs.h"
 #include "src/tint/lang/core/type/depth_texture.h"
 #include "src/tint/lang/core/type/input_attachment.h"
@@ -1224,6 +1225,46 @@
     EXPECT_EQ(expect, str());
 }
 
+TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureLoad_BindingArray_2D) {
+    auto* sampled_texture = ty.sampled_texture(core::type::TextureDimension::k2d, ty.f32());
+    auto* arr = b.FunctionParam("arr", ty.binding_array(sampled_texture, 2));
+    auto* coords = b.FunctionParam("coords", ty.vec2<i32>());
+    auto* lod = b.FunctionParam("lod", ty.i32());
+    auto* func = b.Function("foo", ty.vec4<f32>());
+    func->SetParams({arr, coords, lod});
+
+    b.Append(func->Block(), [&] {
+        auto* result = b.Call(ty.vec4<f32>(), core::BuiltinFn::kTextureLoad,
+                              b.Access(sampled_texture, arr, 0_u), coords, lod);
+        b.Return(func, result);
+    });
+
+    auto* src = R"(
+%foo = func(%arr:binding_array<texture_2d<f32>, 2>, %coords:vec2<i32>, %lod:i32):vec4<f32> {
+  $B1: {
+    %5:texture_2d<f32> = access %arr, 0u
+    %6:vec4<f32> = textureLoad %5, %coords, %lod
+    ret %6
+  }
+}
+)";
+    EXPECT_EQ(src, str());
+
+    auto* expect = R"(
+%foo = func(%arr:binding_array<spirv.image<f32, 2d, not_depth, non_arrayed, single_sampled, sampling_compatible, undefined, read_write>, 2>, %coords:vec2<i32>, %lod:i32):vec4<f32> {
+  $B1: {
+    %5:spirv.image<f32, 2d, not_depth, non_arrayed, single_sampled, sampling_compatible, undefined, read_write> = access %arr, 0u
+    %6:vec4<f32> = spirv.image_fetch %5, %coords, 2u, %lod
+    ret %6
+  }
+}
+)";
+
+    Run(BuiltinPolyfill, false);
+
+    EXPECT_EQ(expect, str());
+}
+
 TEST_F(SpirvWriter_BuiltinPolyfillTest, TextureLoad_2DArray) {
     auto* t =
         b.FunctionParam("t", ty.sampled_texture(core::type::TextureDimension::k2dArray, ty.f32()));