It’s slightly different because here we’re talking about the alignment of fields in-situ, rather than a general requirement for all instances of the type.
Given these WGSL
structures:
struct A {
v1: vec3<u32>,
a: f32,
v2: vec3<u32>,
}
struct B {
v1: vec3<u32>,
v2: vec3<u32>,
}
The best Rust translations right now are:
#[repr(C, align(16))]
struct A {
v1: [u32;3],
a: f32,
v2: [u32;3],
}
#[repr(C, align(16))]
struct B {
v1: [u32;3],
_padding: MaybeUninit<u32>,
v2: [u32;3],
}
In both cases, the padding at the end of the Rust struct to bring the size to a multiple of 16 is also required by WGSL, and for the same reason.
An alternative approach would be to define a newtype wrapper around [u32;3]
with an alignment of 16. This would eliminate the manual padding in B
but make A
unrepresentable— To match this alternate Rust definition of A
, manual padding entries would be required in the WGSL
code, and the whole structure will be significantly larger.
With a field alignment attribute, however, we could then represent both structures on the Rust side in a way that directly corresponds to the WGSL definition:
#[repr(C)]
struct A {
#[align(16)] // optional, because it’s the first field
v1: [u32;3],
a: f32,
#[align(16)]
v2: [u32;3],
}
#[repr(C)]
struct B {
#[align(16)] // optional, because it’s the first field
v1: [u32;3],
#[align(16)]
v2: [u32;3],
}