[wgsl] Relax constraints for uniform_buffer_standard_layout

Update or remove tests that use the old constraints.

Suppress some CTS tests that are waiting on a CTS update.

Bug: 452662924
Change-Id: I4518aaeb6184d897ec91b4dabccb434d037bf2c6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/267515
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp b/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp
index ce6bb0d..391cc0f 100644
--- a/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp
+++ b/src/dawn/tests/end2end/ComputeLayoutMemoryBufferTests.cpp
@@ -1157,7 +1157,14 @@
 
     std::vector<ComputeLayoutMemoryBufferTestParams> filtered;
     for (auto param : params) {
-        if (param.mAddressSpace != AddressSpace::Storage && param.mField.IsStorageBufferOnly()) {
+        // If the decompose_uniform_buffers toggle is disabled then Tint will not support the
+        // relaxed constraints on uniform buffers. We can remove this (and all of the
+        // StorageBufferOnly logic) when the killswitch for decompose_uniform_buffers is removed.
+        bool supportsUniformBufferStandardLayout =
+            std::find(param.forceDisabledWorkarounds.begin(), param.forceDisabledWorkarounds.end(),
+                      "decompose_uniform_buffers") == param.forceDisabledWorkarounds.end();
+        if (param.mAddressSpace != AddressSpace::Storage && param.mField.IsStorageBufferOnly() &&
+            !supportsUniformBufferStandardLayout) {
             continue;
         }
         filtered.emplace_back(param);
diff --git a/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc b/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc
index 0be725a..d8c0e76 100644
--- a/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc
@@ -94,8 +94,8 @@
     // };
     //
     // struct Outer {
-    //   scalar : f32;
-    //   inner : Inner;
+    //   @size(5) scalar : f32;
+    //   @align(1) inner : Inner;
     // };
     //
     // @group(0) @binding(0)
@@ -105,10 +105,11 @@
                                                     Member("scalar", ty.i32()),
                                                 });
 
-    Structure(Ident(Source{{34, 56}}, "Outer"), Vector{
-                                                    Member("scalar", ty.f32()),
-                                                    Member(Source{{56, 78}}, "inner", ty("Inner")),
-                                                });
+    Structure(Ident(Source{{34, 56}}, "Outer"),
+              Vector{
+                  Member("scalar", ty.f32(), Vector{MemberSize(5_a)}),
+                  Member(Source{{56, 78}}, "inner", ty("Inner"), Vector{MemberAlign(1_a)}),
+              });
 
     GlobalVar(Source{{78, 90}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
               Binding(0_a));
@@ -116,12 +117,13 @@
     ASSERT_FALSE(r()->Resolve());
     EXPECT_EQ(
         r()->error(),
-        R"(56:78 error: the offset of a struct member of type 'Inner' in address space 'uniform' must be a multiple of 16 bytes, but 'inner' is currently at offset 4. Consider setting '@align(16)' on this member
+        R"(56:78 error: the offset of a struct member of type 'Inner' in address space 'uniform' must be a multiple of 4 bytes, but 'inner' is currently at offset 5. Consider setting '@align(4)' on this member
 34:56 note: see layout of struct:
-/*           align(4) size(8) */ struct Outer {
-/* offset(0) align(4) size(4) */   scalar : f32,
-/* offset(4) align(4) size(4) */   inner : Inner,
-/*                            */ };
+/*           align(4) size(12) */ struct Outer {
+/* offset(0) align(4) size( 5) */   scalar : f32,
+/* offset(5) align(1) size( 4) */   inner : Inner,
+/* offset(9) align(1) size( 3) */   // -- implicit struct size padding --
+/*                             */ };
 12:34 note: and layout of struct member:
 /*           align(4) size(4) */ struct Inner {
 /* offset(0) align(4) size(4) */   scalar : i32,
@@ -136,8 +138,8 @@
     // };
     //
     // struct Outer {
-    //   scalar : f32;
-    //   @align(16) inner : Inner;
+    //   @size(5) scalar : f32;
+    //   @align(4) inner : Inner;
     // };
     //
     // @group(0) @binding(0)
@@ -148,8 +150,8 @@
                        });
 
     Structure("Outer", Vector{
-                           Member("scalar", ty.f32()),
-                           Member("inner", ty("Inner"), Vector{MemberAlign(16_i)}),
+                           Member("scalar", ty.f32(), Vector{MemberSize(5_a)}),
+                           Member("inner", ty("Inner"), Vector{MemberAlign(4_i)}),
                        });
 
     GlobalVar("a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a), Binding(0_a));
@@ -157,107 +159,6 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-// Detect uniform buffers with byte offset between 2 members that is not a
-// multiple of 16 bytes
-TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_MembersOffsetNotMultipleOf16) {
-    // struct Inner {
-    //   @align(4) @size(5) scalar : i32;
-    // };
-    //
-    // struct Outer {
-    //   inner : Inner;
-    //   scalar : i32;
-    // };
-    //
-    // @group(0) @binding(0)
-    // var<uniform> a : Outer;
-
-    Structure(Ident(Source{{12, 34}}, "Inner"),
-              Vector{
-                  Member("scalar", ty.i32(), Vector{MemberAlign(4_i), MemberSize(5_a)}),
-              });
-
-    Structure(Source{{34, 56}}, "Outer",
-              Vector{
-                  Member(Source{{56, 78}}, "inner", ty("Inner")),
-                  Member(Source{{78, 90}}, "scalar", ty.i32()),
-              });
-
-    GlobalVar(Source{{22, 24}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(78:90 error: 'uniform' storage requires that the number of bytes between the start of the previous member of type struct and the current member be a multiple of 16 bytes, but there are currently 8 bytes between 'inner' and 'scalar'. Consider setting '@align(16)' on this member
-note: see layout of struct:
-/*            align(4) size(12) */ struct Outer {
-/* offset( 0) align(4) size( 8) */   inner : Inner,
-/* offset( 8) align(4) size( 4) */   scalar : i32,
-/*                              */ };
-12:34 note: and layout of previous member struct:
-/*           align(4) size(8) */ struct Inner {
-/* offset(0) align(4) size(5) */   scalar : i32,
-/* offset(5) align(1) size(3) */   // -- implicit struct size padding --
-/*                            */ };
-22:24 note: 'Outer' used in address space 'uniform' here)");
-}
-
-// See https://crbug.com/tint/1344
-TEST_F(ResolverAddressSpaceLayoutValidationTest,
-       UniformBuffer_MembersOffsetNotMultipleOf16_InnerMoreMembersThanOuter) {
-    // struct Inner {
-    //   a : i32;
-    //   b : i32;
-    //   c : i32;
-    //   @align(4) @size(5) scalar : i32;
-    // };
-    //
-    // struct Outer {
-    //   inner : Inner;
-    //   scalar : i32;
-    // };
-    //
-    // @group(0) @binding(0)
-    // var<uniform> a : Outer;
-
-    Structure(Ident(Source{{12, 34}}, "Inner"),
-              Vector{
-                  Member("a", ty.i32()),
-                  Member("b", ty.i32()),
-                  Member("c", ty.i32()),
-                  Member("scalar", ty.i32(), Vector{MemberAlign(4_i), MemberSize(5_a)}),
-              });
-
-    Structure(Source{{34, 56}}, "Outer",
-              Vector{
-                  Member(Source{{56, 78}}, "inner", ty("Inner")),
-                  Member(Source{{78, 90}}, "scalar", ty.i32()),
-              });
-
-    GlobalVar(Source{{22, 24}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(78:90 error: 'uniform' storage requires that the number of bytes between the start of the previous member of type struct and the current member be a multiple of 16 bytes, but there are currently 20 bytes between 'inner' and 'scalar'. Consider setting '@align(16)' on this member
-note: see layout of struct:
-/*            align(4) size(24) */ struct Outer {
-/* offset( 0) align(4) size(20) */   inner : Inner,
-/* offset(20) align(4) size( 4) */   scalar : i32,
-/*                              */ };
-12:34 note: and layout of previous member struct:
-/*            align(4) size(20) */ struct Inner {
-/* offset( 0) align(4) size( 4) */   a : i32,
-/* offset( 4) align(4) size( 4) */   b : i32,
-/* offset( 8) align(4) size( 4) */   c : i32,
-/* offset(12) align(4) size( 5) */   scalar : i32,
-/* offset(17) align(1) size( 3) */   // -- implicit struct size padding --
-/*                              */ };
-22:24 note: 'Outer' used in address space 'uniform' here)");
-}
-
 TEST_F(ResolverAddressSpaceLayoutValidationTest,
        UniformBuffer_MembersOffsetNotMultipleOf16_SuggestedFix) {
     // struct Inner {
@@ -330,153 +231,6 @@
     ASSERT_TRUE(r()->Resolve()) << r()->error();
 }
 
-// Detect array stride must be a multiple of 16 bytes for uniform buffers
-TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Scalar) {
-    // type Inner = array<f32, 10u>;
-    //
-    // struct Outer {
-    //   inner : Inner;
-    //   scalar : i32;
-    // };
-    //
-    // @group(0) @binding(0)
-    // var<uniform> a : Outer;
-
-    Alias("Inner", ty.array<f32, 10>());
-
-    Structure(Ident(Source{{12, 34}}, "Outer"), Vector{
-                                                    Member("inner", ty(Source{{34, 56}}, "Inner")),
-                                                    Member("scalar", ty.i32()),
-                                                });
-
-    GlobalVar(Source{{78, 90}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
-12:34 note: see layout of struct:
-/*            align(4) size(44) */ struct Outer {
-/* offset( 0) align(4) size(40) */   inner : array<f32, 10>,
-/* offset(40) align(4) size( 4) */   scalar : i32,
-/*                              */ };
-78:90 note: 'Outer' used in address space 'uniform' here)");
-}
-
-TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Vector) {
-    // type Inner = array<vec2<f32>, 10u>;
-    //
-    // struct Outer {
-    //   inner : Inner;
-    //   scalar : i32;
-    // };
-    //
-    // @group(0) @binding(0)
-    // var<uniform> a : Outer;
-
-    Alias("Inner", ty.array<vec2<f32>, 10>());
-
-    Structure(Ident(Source{{12, 34}}, "Outer"), Vector{
-                                                    Member("inner", ty(Source{{34, 56}}, "Inner")),
-                                                    Member("scalar", ty.i32()),
-                                                });
-
-    GlobalVar(Source{{78, 90}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'vec2<f32>' has a stride of 8 bytes. Consider using a vec4 instead.
-12:34 note: see layout of struct:
-/*            align(8) size(88) */ struct Outer {
-/* offset( 0) align(8) size(80) */   inner : array<vec2<f32>, 10>,
-/* offset(80) align(4) size( 4) */   scalar : i32,
-/* offset(84) align(1) size( 4) */   // -- implicit struct size padding --
-/*                              */ };
-78:90 note: 'Outer' used in address space 'uniform' here)");
-}
-
-TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_Struct) {
-    // struct ArrayElem {
-    //   a : f32;
-    //   b : i32;
-    // }
-    // type Inner = array<ArrayElem, 10u>;
-    //
-    // struct Outer {
-    //   inner : Inner;
-    //   scalar : i32;
-    // };
-    //
-    // @group(0) @binding(0)
-    // var<uniform> a : Outer;
-
-    auto* array_elem = Structure("ArrayElem", Vector{
-                                                  Member("a", ty.f32()),
-                                                  Member("b", ty.i32()),
-                                              });
-    Alias("Inner", ty.array(ty.Of(array_elem), 10_u));
-
-    Structure(Ident(Source{{12, 34}}, "Outer"), Vector{
-                                                    Member("inner", ty(Source{{34, 56}}, "Inner")),
-                                                    Member("scalar", ty.i32()),
-                                                });
-
-    GlobalVar(Source{{78, 90}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'ArrayElem' has a stride of 8 bytes. Consider using the '@size' attribute on the last struct member.
-12:34 note: see layout of struct:
-/*            align(4) size(84) */ struct Outer {
-/* offset( 0) align(4) size(80) */   inner : array<ArrayElem, 10>,
-/* offset(80) align(4) size( 4) */   scalar : i32,
-/*                              */ };
-78:90 note: 'Outer' used in address space 'uniform' here)");
-}
-
-TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_TopLevelArray) {
-    // @group(0) @binding(0)
-    // var<uniform> a : array<f32, 4u>;
-    GlobalVar("a", ty.array(ty.f32(), 4_u), core::AddressSpace::kUniform, Group(0_a), Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.)");
-}
-
-TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_InvalidArrayStride_NestedArray) {
-    // struct Outer {
-    //   inner : array<array<f32, 4u>, 4u>
-    // };
-    //
-    // @group(0) @binding(0)
-    // var<uniform> a : array<Outer, 4u>;
-
-    Structure(Ident(Source{{12, 34}}, "Outer"),
-              Vector{
-                  Member("inner", ty.array(Source{{34, 56}}, ty.array<f32, 4>(), 4_u)),
-              });
-
-    GlobalVar(Source{{78, 90}}, "a", ty("Outer"), core::AddressSpace::kUniform, Group(0_a),
-              Binding(0_a));
-
-    ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(34:56 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'f32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
-12:34 note: see layout of struct:
-/*            align(4) size(64) */ struct Outer {
-/* offset( 0) align(4) size(64) */   inner : array<array<f32, 4>, 4>,
-/*                              */ };
-78:90 note: 'Outer' used in address space 'uniform' here)");
-}
-
 // Detect unaligned member for immediate data buffers
 TEST_F(ResolverAddressSpaceLayoutValidationTest, Immediate_UnalignedMember) {
     // enable chromium_experimental_immediate;
diff --git a/src/tint/lang/wgsl/resolver/address_space_validation_test.cc b/src/tint/lang/wgsl/resolver/address_space_validation_test.cc
index 43c3201..d071af0 100644
--- a/src/tint/lang/wgsl/resolver/address_space_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/address_space_validation_test.cc
@@ -555,14 +555,10 @@
     Alias("t", ty.ptr<uniform>(Source{{90, 12}}, ty("S")));
 
     ASSERT_FALSE(r()->Resolve());
-    EXPECT_EQ(
-        r()->error(),
-        R"(12:34 error: 'uniform' storage requires that array elements are aligned to 16 bytes, but array element of type 'i32' has a stride of 4 bytes. Consider using a vector or struct as the element type instead.
-note: see layout of struct:
-/*           align(4) size(4) */ struct S {
-/* offset(0) align(4) size(4) */   m : array<i32>,
-/*                            */ };
-90:12 note: 'S' used in address space 'uniform' here)");
+    EXPECT_EQ(r()->error(),
+              R"(12:34 error: runtime-sized arrays can only be used in the <storage> address space
+56:78 note: while analyzing structure member S.m
+90:12 note: while instantiating ptr<uniform, S, read>)");
 }
 
 TEST_F(ResolverAddressSpaceValidationTest, GlobalVariable_UniformBufferBool) {
diff --git a/src/tint/lang/wgsl/resolver/validator.cc b/src/tint/lang/wgsl/resolver/validator.cc
index 50e06c3..caca5d1 100644
--- a/src/tint/lang/wgsl/resolver/validator.cc
+++ b/src/tint/lang/wgsl/resolver/validator.cc
@@ -583,7 +583,9 @@
     auto required_alignment_of = [&](const core::type::Type* ty) {
         uint32_t actual_align = ty->Align();
         uint32_t required_align = actual_align;
-        if (is_uniform_struct_or_array(ty)) {
+        if (is_uniform_struct_or_array(ty) &&
+            !allowed_features_.features.contains(
+                wgsl::LanguageFeature::kUniformBufferStandardLayout)) {
             required_align = tint::RoundUp(16u, actual_align);
         }
         return required_align;
@@ -649,7 +651,9 @@
             // For uniform buffers, validate that the number of bytes between the previous member of
             // type struct and the current is a multiple of 16 bytes.
             auto* const prev_member = (i == 0) ? nullptr : str->Members()[i - 1];
-            if (prev_member && is_uniform_struct(prev_member->Type())) {
+            if (prev_member && is_uniform_struct(prev_member->Type()) &&
+                !allowed_features_.features.contains(
+                    wgsl::LanguageFeature::kUniformBufferStandardLayout)) {
                 const uint32_t prev_to_curr_offset = m->Offset() - prev_member->Offset();
                 if (prev_to_curr_offset % 16 != 0) {
                     AddError(m->Declaration()->source)
@@ -700,7 +704,9 @@
             return false;
         }
 
-        if (address_space == core::AddressSpace::kUniform) {
+        if (address_space == core::AddressSpace::kUniform &&
+            !allowed_features_.features.contains(
+                wgsl::LanguageFeature::kUniformBufferStandardLayout)) {
             // We already validated that this array member is itself aligned to 16 bytes above, so
             // we only need to validate that stride is a multiple of 16 bytes.
             if (arr->ImplicitStride() % 16 != 0) {
diff --git a/webgpu-cts/compat-expectations.txt b/webgpu-cts/compat-expectations.txt
index 24f715b..22806ed 100644
--- a/webgpu-cts/compat-expectations.txt
+++ b/webgpu-cts/compat-expectations.txt
@@ -712,6 +712,27 @@
 crbug.com/444283285 [ android-pixel-6 ] webgpu:api,validation,createBindGroupLayout:max_resources_per_stage,in_pipeline_layout:* [ Failure ]
 crbug.com/444283285 [ android-pixel-6 ] webgpu:api,validation,createPipelineLayout:number_of_dynamic_buffers_exceeds_the_maximum_value:* [ Failure ]
 
+# Temporary suppressions while CTS is updated for the relaxed layout rules.
+crbug.com/452662924 webgpu:shader,validation,shader_io,align:required_alignment:address_space="uniform";align="alignment";type={"name":"array%3Cvec2%3Ci32%3E,%202%3E","storage":8,"uniform":16} [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,align:required_alignment:address_space="uniform";align=32;type={"name":"array%3Cvec2%3Ci32%3E,%202%3E","storage":8,"uniform":16} [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_f16" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_f32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_i32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_mat2x2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_mat3x2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_size_5" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_u32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_vec2f" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_vec2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_u32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec2f" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec3h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec4h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="struct_array_u32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="struct_padding" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="struct_size_5" [ Failure ]
+
 ################################################################################
 # Autogenerated Failure expectations. Please triage.
 # ##ROLLER_AUTOGENERATED_FAILURES##
diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt
index bb85d66..f970b25 100644
--- a/webgpu-cts/expectations.txt
+++ b/webgpu-cts/expectations.txt
@@ -1144,6 +1144,27 @@
 # The spec doesn't precisely require a behavior and the CTS tests only one of them. Remove suppressions once the spec / CTS is fixed.
 crbug.com/449980070 webgpu:api,validation,encoding,encoder_open_state:* [ Failure ]
 
+# Temporary suppressions while CTS is updated for the relaxed layout rules.
+crbug.com/452662924 webgpu:shader,validation,shader_io,align:required_alignment:address_space="uniform";align="alignment";type={"name":"array%3Cvec2%3Ci32%3E,%202%3E","storage":8,"uniform":16} [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,align:required_alignment:address_space="uniform";align=32;type={"name":"array%3Cvec2%3Ci32%3E,%202%3E","storage":8,"uniform":16} [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_f16" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_f32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_i32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_mat2x2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_mat3x2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_size_5" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_u32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_vec2f" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_struct_vec2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_u32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec2f" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec2h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec3h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="array_vec4h" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="struct_array_u32" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="struct_padding" [ Failure ]
+crbug.com/452662924 webgpu:shader,validation,shader_io,layout_constraints:layout_constraints:case="struct_size_5" [ Failure ]
+
 ################################################################################
 # Autogenerated Failure expectations. Please triage.
 # ##ROLLER_AUTOGENERATED_FAILURES##