mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-13 07:06:11 +00:00
Deprecate the @stride attribute
Update validation error for invalid uniform array element alignment. Update tests to either remove the @stride attribute or use a different element type. Bug: tint:1381 Change-Id: I50b52cd78a34d9cd162fa5f2171a5fd35dcf3b79 Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/77560 Reviewed-by: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -321,15 +321,29 @@ bool Resolver::ValidateStorageClassLayout(const sem::Struct* str,
|
||||
// bytes above, so we only need to validate that stride is a multiple of
|
||||
// 16 bytes.
|
||||
if (arr->Stride() % 16 != 0) {
|
||||
// Since WGSL has no stride attribute, try to provide a useful hint
|
||||
// for how the shader author can resolve the issue.
|
||||
std::string hint;
|
||||
if (arr->ElemType()->is_scalar()) {
|
||||
hint =
|
||||
"Consider using a vector or struct as the element type "
|
||||
"instead.";
|
||||
} else if (auto* vec = arr->ElemType()->As<sem::Vector>();
|
||||
vec && vec->type()->Size() == 4) {
|
||||
hint = "Consider using a vec4 instead.";
|
||||
} else if (arr->ElemType()->Is<sem::Struct>()) {
|
||||
hint =
|
||||
"Consider using the @size attribute on the last struct member.";
|
||||
} else {
|
||||
hint =
|
||||
"Consider wrapping the element type in a struct and using the "
|
||||
"@size attribute.";
|
||||
}
|
||||
AddError(
|
||||
"uniform storage requires that array elements be aligned to 16 "
|
||||
"bytes, but array stride of '" +
|
||||
"bytes, but array element alignment of '" +
|
||||
member_name_of(m) + "' is currently " +
|
||||
std::to_string(arr->Stride()) +
|
||||
". Consider setting @stride(" +
|
||||
std::to_string(
|
||||
utils::RoundUp(required_align, arr->Stride())) +
|
||||
") on the array type",
|
||||
std::to_string(arr->Stride()) + ". " + hint,
|
||||
m->Declaration()->type->source);
|
||||
AddNote("see layout of struct:\n" + str->Layout(builder_->Symbols()),
|
||||
str->Declaration()->source);
|
||||
|
||||
@@ -378,8 +378,8 @@ TEST_F(ResolverStorageClassLayoutValidationTest,
|
||||
|
||||
// Detect array stride must be a multiple of 16 bytes for uniform buffers
|
||||
TEST_F(ResolverStorageClassLayoutValidationTest,
|
||||
UniformBuffer_InvalidArrayStride) {
|
||||
// type Inner = @stride(8) array<f32, 10>;
|
||||
UniformBuffer_InvalidArrayStride_Scalar) {
|
||||
// type Inner = array<f32, 10>;
|
||||
//
|
||||
// [[block]]
|
||||
// struct Outer {
|
||||
@@ -390,7 +390,7 @@ TEST_F(ResolverStorageClassLayoutValidationTest,
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Alias("Inner", ty.array(ty.f32(), 10, 8));
|
||||
Alias("Inner", ty.array(ty.f32(), 10));
|
||||
|
||||
Structure(Source{{12, 34}}, "Outer",
|
||||
{
|
||||
@@ -405,10 +405,93 @@ TEST_F(ResolverStorageClassLayoutValidationTest,
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(34:56 error: uniform storage requires that array elements be aligned to 16 bytes, but array stride of 'inner' is currently 8. Consider setting @stride(16) on the array type
|
||||
R"(34:56 error: uniform storage requires that array elements be aligned to 16 bytes, but array element alignment of 'inner' is currently 4. 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: see declaration of variable)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassLayoutValidationTest,
|
||||
UniformBuffer_InvalidArrayStride_Vector) {
|
||||
// type Inner = array<vec2<f32>, 10>;
|
||||
//
|
||||
// [[block]]
|
||||
// struct Outer {
|
||||
// inner : Inner;
|
||||
// scalar : i32;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
Alias("Inner", ty.array(ty.vec2<f32>(), 10));
|
||||
|
||||
Structure(Source{{12, 34}}, "Outer",
|
||||
{
|
||||
Member("inner", ty.type_name(Source{{34, 56}}, "Inner")),
|
||||
Member("scalar", ty.i32()),
|
||||
},
|
||||
{StructBlock()});
|
||||
|
||||
Global(Source{{78, 90}}, "a", ty.type_name("Outer"),
|
||||
ast::StorageClass::kUniform, GroupAndBinding(0, 0));
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(34:56 error: uniform storage requires that array elements be aligned to 16 bytes, but array element alignment of 'inner' is currently 8. 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: see declaration of variable)");
|
||||
}
|
||||
|
||||
TEST_F(ResolverStorageClassLayoutValidationTest,
|
||||
UniformBuffer_InvalidArrayStride_Struct) {
|
||||
// struct ArrayElem {
|
||||
// a : f32;
|
||||
// b : i32;
|
||||
// }
|
||||
// type Inner = array<ArrayElem, 10>;
|
||||
//
|
||||
// [[block]]
|
||||
// struct Outer {
|
||||
// inner : Inner;
|
||||
// scalar : i32;
|
||||
// };
|
||||
//
|
||||
// @group(0) @binding(0)
|
||||
// var<uniform> a : Outer;
|
||||
|
||||
auto* array_elem = Structure("ArrayElem", {
|
||||
Member("a", ty.f32()),
|
||||
Member("b", ty.i32()),
|
||||
});
|
||||
Alias("Inner", ty.array(ty.Of(array_elem), 10));
|
||||
|
||||
Structure(Source{{12, 34}}, "Outer",
|
||||
{
|
||||
Member("inner", ty.type_name(Source{{34, 56}}, "Inner")),
|
||||
Member("scalar", ty.i32()),
|
||||
},
|
||||
{StructBlock()});
|
||||
|
||||
Global(Source{{78, 90}}, "a", ty.type_name("Outer"),
|
||||
ast::StorageClass::kUniform, GroupAndBinding(0, 0));
|
||||
|
||||
ASSERT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(
|
||||
r()->error(),
|
||||
R"(34:56 error: uniform storage requires that array elements be aligned to 16 bytes, but array element alignment of 'inner' is currently 8. 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 : @stride(8) array<f32, 10>;
|
||||
/* offset( 0) align(4) size(80) */ inner : array<ArrayElem, 10>;
|
||||
/* offset(80) align(4) size( 4) */ scalar : i32;
|
||||
/* */ };
|
||||
78:90 note: see declaration of variable)");
|
||||
|
||||
Reference in New Issue
Block a user