[tint] Add binding_array indexing to the resolver.
Bug: 393558555
Change-Id: Ia4f4227c8ba509576621867e355957ff7f99eb1f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/229174
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/constant/eval_indexing_test.cc b/src/tint/lang/core/constant/eval_indexing_test.cc
index 8583390..f45ccbd 100644
--- a/src/tint/lang/core/constant/eval_indexing_test.cc
+++ b/src/tint/lang/core/constant/eval_indexing_test.cc
@@ -319,6 +319,30 @@
EXPECT_EQ(r()->error(), "12:34 error: index -2 out of bounds");
}
+TEST_F(ConstEvalTest, BindingArray_Index_OOB_Low) {
+ GlobalVar(
+ "a", Binding(0_a), Group(0_a),
+ ty("binding_array", ty.sampled_texture(core::type::TextureDimension::k2d, ty.f32()), 4_u));
+ auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, -1_i));
+ auto* call = Call("textureDimensions", acc);
+ WrapInFunction(call);
+
+ EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 error: index -1 out of bounds [0..3]");
+}
+
+TEST_F(ConstEvalTest, BindingArray_Index_OOB_High) {
+ GlobalVar(
+ "a", Binding(0_a), Group(0_a),
+ ty("binding_array", ty.sampled_texture(core::type::TextureDimension::k2d, ty.f32()), 4_u));
+ auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, 4_i));
+ auto* call = Call("textureDimensions", acc);
+ WrapInFunction(call);
+
+ EXPECT_FALSE(r()->Resolve()) << r()->error();
+ EXPECT_EQ(r()->error(), "12:34 error: index 4 out of bounds [0..3]");
+}
+
TEST_F(ConstEvalTest, ChainedIndex) {
auto* arr_expr = Call<array<mat2x3<f32>, 2>>( //
Call<mat2x3<f32>>(Call<vec3<f32>>(1_f, 2_f, 3_f), //
diff --git a/src/tint/lang/wgsl/resolver/array_accessor_test.cc b/src/tint/lang/wgsl/resolver/array_accessor_test.cc
index b3e98ed..fbbc9a8 100644
--- a/src/tint/lang/wgsl/resolver/array_accessor_test.cc
+++ b/src/tint/lang/wgsl/resolver/array_accessor_test.cc
@@ -198,6 +198,68 @@
EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
}
+TEST_F(ResolverIndexAccessorTest, BindingArray_F32) {
+ GlobalVar(
+ "a", Binding(0_a), Group(0_a),
+ ty("binding_array", ty.sampled_texture(core::type::TextureDimension::k2d, ty.f32()), 4_u));
+ auto* acc = IndexAccessor("a", Expr(Source{{12, 34}}, 2_f));
+ auto* call = Call("textureDimensions", acc);
+ WrapInFunction(call);
+
+ EXPECT_FALSE(r()->Resolve());
+ EXPECT_EQ(r()->error(), "12:34 error: index must be of type 'i32' or 'u32', found: 'f32'");
+}
+
+TEST_F(ResolverIndexAccessorTest, BindingArray_Literal_i32) {
+ GlobalVar(
+ "a", Binding(0_a), Group(0_a),
+ ty("binding_array", ty.sampled_texture(core::type::TextureDimension::k2d, ty.f32()), 4_u));
+ auto* acc = IndexAccessor("a", 2_i);
+ auto* call = Call("textureDimensions", acc);
+ WrapInFunction(call);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(acc), nullptr);
+ EXPECT_TRUE(TypeOf(acc)->Is<core::type::SampledTexture>());
+ ASSERT_TRUE(TypeOf(acc)->As<core::type::SampledTexture>()->Type()->Is<core::type::F32>());
+ ASSERT_EQ(TypeOf(acc)->As<core::type::SampledTexture>()->Dim(),
+ core::type::TextureDimension::k2d);
+
+ auto idx_sem = Sem().Get(acc)->UnwrapLoad()->As<sem::IndexAccessorExpression>();
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
+}
+
+TEST_F(ResolverIndexAccessorTest, BindingArray_Dynamic_i32) {
+ GlobalVar(
+ "a", Binding(0_a), Group(0_a),
+ ty("binding_array", ty.sampled_texture(core::type::TextureDimension::k2d, ty.f32()), 4_u));
+ auto* idx = Var("idx", ty.i32(), Call<i32>());
+ auto* acc = IndexAccessor("a", idx);
+ auto* call = Call("textureDimensions", acc);
+ auto* f = Var("f", call);
+ Func("my_func", tint::Empty, ty.void_(),
+ Vector{
+ Decl(idx),
+ Decl(f),
+ });
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+
+ ASSERT_NE(TypeOf(acc), nullptr);
+ EXPECT_TRUE(TypeOf(acc)->Is<core::type::SampledTexture>());
+ ASSERT_TRUE(TypeOf(acc)->As<core::type::SampledTexture>()->Type()->Is<core::type::F32>());
+ ASSERT_EQ(TypeOf(acc)->As<core::type::SampledTexture>()->Dim(),
+ core::type::TextureDimension::k2d);
+
+ auto idx_sem = Sem().Get(acc)->UnwrapLoad()->As<sem::IndexAccessorExpression>();
+ ASSERT_NE(idx_sem, nullptr);
+ EXPECT_EQ(idx_sem->Index()->Declaration(), acc->index);
+ EXPECT_EQ(idx_sem->Object()->Declaration(), acc->object);
+}
+
TEST_F(ResolverIndexAccessorTest, Array_Literal_i32) {
GlobalVar("my_var", ty.array<f32, 3>(), core::AddressSpace::kPrivate);
auto* acc = IndexAccessor("my_var", 2_i);
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 09abd13..5e5c029 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -2027,6 +2027,7 @@
auto* ty = Switch(
storage_ty, //
[&](const sem::Array* arr) { return arr->ElemType(); },
+ [&](const core::type::BindingArray* arr) { return arr->ElemType(); },
[&](const core::type::Vector* vec) { return vec->Type(); },
[&](const core::type::Matrix* mat) {
return b.create<core::type::Vector>(mat->Type(), mat->Rows());