[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##