Skip to content

Commit ed15f85

Browse files
jrpriceDawn LUCI CQ
authored andcommitted
[tint] Validate that @align() is large enough
Make sure that `n = k × RequiredAlignOf(T,C)` as per the spec, when `@align(n)` is applied to the member of a structure that is used in a host-shareable address space. Suppress some CTS tests until they are updated upstream. Fixed: 375123371 Include-Ci-Only-Tests: true Change-Id: I3240b9ab0a42986e918a1c6a86268844861b9fed Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/212315 Commit-Queue: James Price <[email protected]> Reviewed-by: dan sinclair <[email protected]>
1 parent aee66d2 commit ed15f85

File tree

4 files changed

+61
-13
lines changed

4 files changed

+61
-13
lines changed

src/tint/lang/wgsl/resolver/address_space_layout_validation_test.cc

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_UnalignedMember_A
216216
// multiple of 16 bytes
217217
TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_MembersOffsetNotMultipleOf16) {
218218
// struct Inner {
219-
// @align(1) @size(5) scalar : i32;
219+
// @align(4) @size(5) scalar : i32;
220220
// };
221221
//
222222
// struct Outer {
@@ -229,7 +229,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_MembersOffsetNotM
229229

230230
Structure(Ident(Source{{12, 34}}, "Inner"),
231231
Vector{
232-
Member("scalar", ty.i32(), Vector{MemberAlign(1_i), MemberSize(5_a)}),
232+
Member("scalar", ty.i32(), Vector{MemberAlign(4_i), MemberSize(5_a)}),
233233
});
234234

235235
Structure(Source{{34, 56}}, "Outer",
@@ -247,13 +247,13 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, UniformBuffer_MembersOffsetNotM
247247
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
248248
note: see layout of struct:
249249
/* align(4) size(12) */ struct Outer {
250-
/* offset( 0) align(1) size( 5) */ inner : Inner,
251-
/* offset( 5) align(1) size( 3) */ // -- implicit field alignment padding --
250+
/* offset( 0) align(4) size( 8) */ inner : Inner,
252251
/* offset( 8) align(4) size( 4) */ scalar : i32,
253252
/* */ };
254253
12:34 note: and layout of previous member struct:
255-
/* align(1) size(5) */ struct Inner {
256-
/* offset(0) align(1) size(5) */ scalar : i32,
254+
/* align(4) size(8) */ struct Inner {
255+
/* offset(0) align(4) size(5) */ scalar : i32,
256+
/* offset(5) align(1) size(3) */ // -- implicit struct size padding --
257257
/* */ };
258258
22:24 note: 'Outer' used in address space 'uniform' here)");
259259
}
@@ -265,7 +265,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest,
265265
// a : i32;
266266
// b : i32;
267267
// c : i32;
268-
// @align(1) @size(5) scalar : i32;
268+
// @align(4) @size(5) scalar : i32;
269269
// };
270270
//
271271
// struct Outer {
@@ -281,7 +281,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest,
281281
Member("a", ty.i32()),
282282
Member("b", ty.i32()),
283283
Member("c", ty.i32()),
284-
Member("scalar", ty.i32(), Vector{MemberAlign(1_i), MemberSize(5_a)}),
284+
Member("scalar", ty.i32(), Vector{MemberAlign(4_i), MemberSize(5_a)}),
285285
});
286286

287287
Structure(Source{{34, 56}}, "Outer",
@@ -307,7 +307,7 @@ note: see layout of struct:
307307
/* offset( 0) align(4) size( 4) */ a : i32,
308308
/* offset( 4) align(4) size( 4) */ b : i32,
309309
/* offset( 8) align(4) size( 4) */ c : i32,
310-
/* offset(12) align(1) size( 5) */ scalar : i32,
310+
/* offset(12) align(4) size( 5) */ scalar : i32,
311311
/* offset(17) align(1) size( 3) */ // -- implicit struct size padding --
312312
/* */ };
313313
22:24 note: 'Outer' used in address space 'uniform' here)");
@@ -316,7 +316,7 @@ note: see layout of struct:
316316
TEST_F(ResolverAddressSpaceLayoutValidationTest,
317317
UniformBuffer_MembersOffsetNotMultipleOf16_SuggestedFix) {
318318
// struct Inner {
319-
// @align(1) @size(5) scalar : i32;
319+
// @align(4) @size(5) scalar : i32;
320320
// };
321321
//
322322
// struct Outer {
@@ -328,7 +328,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest,
328328
// var<uniform> a : Outer;
329329

330330
Structure("Inner", Vector{
331-
Member("scalar", ty.i32(), Vector{MemberAlign(1_i), MemberSize(5_a)}),
331+
Member("scalar", ty.i32(), Vector{MemberAlign(4_i), MemberSize(5_a)}),
332332
});
333333

334334
Structure("Outer", Vector{
@@ -659,7 +659,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_MemberOffs
659659
// enable chromium_internal_relaxed_uniform_layout;
660660
//
661661
// struct Inner {
662-
// @align(1) @size(5) scalar : i32;
662+
// @align(4) @size(5) scalar : i32;
663663
// };
664664
//
665665
// struct Outer {
@@ -673,7 +673,7 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_MemberOffs
673673
Enable(wgsl::Extension::kChromiumInternalRelaxedUniformLayout);
674674

675675
Structure("Inner", Vector{
676-
Member("scalar", ty.i32(), Vector{MemberAlign(1_i), MemberSize(5_a)}),
676+
Member("scalar", ty.i32(), Vector{MemberAlign(4_i), MemberSize(5_a)}),
677677
});
678678

679679
Structure("Outer", Vector{
@@ -730,5 +730,29 @@ TEST_F(ResolverAddressSpaceLayoutValidationTest, RelaxedUniformLayout_ArrayStrid
730730
EXPECT_TRUE(r()->Resolve()) << r()->error();
731731
}
732732

733+
TEST_F(ResolverAddressSpaceLayoutValidationTest, AlignAttributeTooSmall) {
734+
// struct S {
735+
// @align(4) vector : vec4u;
736+
// scalar : u32;
737+
// };
738+
//
739+
// @group(0) @binding(0)
740+
// var<storage, read_write> a : array<S>;
741+
Structure(
742+
"S", Vector{
743+
Member("vector", ty.vec4<u32>(), Vector{MemberAlign(Expr(Source{{12, 34}}, 4_a))}),
744+
Member("scalar", ty.u32()),
745+
});
746+
747+
GlobalVar(Source{{56, 78}}, "a", ty("S"), core::AddressSpace::kStorage,
748+
core::Access::kReadWrite, Group(0_a), Binding(0_a));
749+
750+
ASSERT_FALSE(r()->Resolve());
751+
EXPECT_EQ(
752+
r()->error(),
753+
R"(12:34 error: alignment must be a multiple of '16' bytes for the 'storage' address space
754+
56:78 note: 'S' used in address space 'storage' here)");
755+
}
756+
733757
} // namespace
734758
} // namespace tint::resolver

src/tint/lang/wgsl/resolver/validator.cc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,22 @@ bool Validator::AddressSpaceLayout(const core::type::Type* store_ty,
641641
return false;
642642
}
643643
}
644+
645+
// If an alignment was explicitly specified, we need to validate that it satisfies the
646+
// alignment requirement of the address space.
647+
auto* align_attr =
648+
ast::GetAttribute<ast::StructMemberAlignAttribute>(m->Declaration()->attributes);
649+
if (align_attr && !enabled_extensions_.Contains(
650+
wgsl::Extension::kChromiumInternalRelaxedUniformLayout)) {
651+
auto align = sem_.GetVal(align_attr->expr)->ConstantValue()->ValueAs<uint32_t>();
652+
if (align % required_align != 0) {
653+
AddError(align_attr->expr->source)
654+
<< "alignment must be a multiple of " << style::Literal(required_align)
655+
<< " bytes for the " << style::Enum(address_space) << " address space";
656+
note_usage();
657+
return false;
658+
}
659+
}
644660
}
645661
}
646662

webgpu-cts/compat-expectations.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,10 @@ crbug.com/dawn/372654300 webgpu:api,validation,render_pipeline,resource_compatib
273273
crbug.com/dawn/372654300 webgpu:api,validation,render_pipeline,resource_compatibility:resource_compatibility:stage="vertex";apiResource="texture_uint_cube-array_false" [ Failure ]
274274
crbug.com/dawn/372654300 webgpu:api,validation,render_pipeline,resource_compatibility:resource_compatibility:stage="vertex";apiResource="texture_unfilterable-float_cube-array_false" [ Failure ]
275275

276+
# Failures due to change in `@align()` validation.
277+
crbug.com/375467276 webgpu:shader,execution,expression,access,structure,index:buffer_align:* [ Failure ]
278+
crbug.com/375467276 webgpu:shader,validation,shader_io,align:* [ Failure ]
279+
276280
### This section represents things that will require Compat validation
277281
### These tests will never pass, but should be skipped in CTS once Compat
278282
### validation has been added

webgpu-cts/expectations.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,10 @@ crbug.com/dawn/0000 [ nvidia-0x2184 nvidia_lt_535.183.01 ] webgpu:shader,executi
14571457
crbug.com/dawn/366000875 webgpu:shader,validation,decl,var:var_access_mode_bad_other_template_contents:accessMode="read";prefix="storage,";suffix="," [ Failure ]
14581458
crbug.com/dawn/366000875 webgpu:shader,validation,decl,var:var_access_mode_bad_other_template_contents:accessMode="read_write";prefix="storage,";suffix="," [ Failure ]
14591459

1460+
# Failures due to change in `@align()` validation.
1461+
crbug.com/375467276 webgpu:shader,execution,expression,access,structure,index:buffer_align:* [ Failure ]
1462+
crbug.com/375467276 webgpu:shader,validation,shader_io,align:* [ Failure ]
1463+
14601464
# Minor accuracy issue with the introduction of texture sample bias clampling
14611465
# specific subtest case: samplePoints="spiral";addressModeU="clamp-to-edge";addressModeV="mirror-repeat";minFilter="linear"
14621466
crbug.com/dawn/371033198 [ amd mac ] webgpu:shader,execution,expression,call,builtin,textureSampleBias:sampled_2d_coords:format="bc1-rgba-unorm";offset=true [ Failure ]

0 commit comments

Comments
 (0)