Skip to content

Commit 5452b20

Browse files
fix(msl-out): emit and init struct member padding always
Resolves [`gfx-rs/wgpu`#4701](#4701).
1 parent 16ec5b0 commit 5452b20

File tree

4 files changed

+54
-7
lines changed

4 files changed

+54
-7
lines changed

naga/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ For changelogs after v0.14, see [the wgpu changelog](../CHANGELOG.md).
7979

8080
- Add and fix minimum Metal version checks for optional functionality. ([#2486](https://github.com/gfx-rs/naga/pull/2486)) **@teoxoy**
8181
- Make varyings' struct members unique. ([#2521](https://github.com/gfx-rs/naga/pull/2521)) **@evahop**
82+
- Emit and init `struct` member padding always ([#4701](https://github.com/gfx-rs/wgpu/pull/4701)) **@ErichDonGubler**
8283

8384
#### GLSL-OUT
8485

naga/src/back/msl/writer.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,11 +357,6 @@ fn should_pack_struct_member(
357357
module: &crate::Module,
358358
) -> Option<crate::Scalar> {
359359
let member = &members[index];
360-
//Note: this is imperfect - the same structure can be used for host-shared
361-
// things, where packed float would matter.
362-
if member.binding.is_some() {
363-
return None;
364-
}
365360

366361
let ty_inner = &module.types[member.ty].inner;
367362
let last_offset = member.offset + ty_inner.size(module.to_ctx());
@@ -3306,7 +3301,7 @@ impl<W: Write> Writer<W> {
33063301
let mut last_offset = 0;
33073302
for (index, member) in members.iter().enumerate() {
33083303
// quick and dirty way to figure out if we need this...
3309-
if member.binding.is_none() && member.offset > last_offset {
3304+
if member.offset > last_offset {
33103305
self.struct_member_pads.insert((handle, index as u32));
33113306
let pad = member.offset - last_offset;
33123307
writeln!(self.out, "{}char _pad{}[{}];", back::INDENT, index, pad)?;
@@ -4273,6 +4268,13 @@ impl<W: Write> Writer<W> {
42734268
if member_index != 0 {
42744269
write!(self.out, ", ")?;
42754270
}
4271+
// insert padding initialization, if needed
4272+
if self
4273+
.struct_member_pads
4274+
.contains(&(arg.ty, member_index as u32))
4275+
{
4276+
write!(self.out, "{{}}, ")?;
4277+
}
42764278
if let Some(crate::Binding::Location { .. }) = member.binding {
42774279
write!(self.out, "{varyings_member_name}.")?;
42784280
}

naga/tests/in/struct-layout.wgsl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Create several type definitions to test `align` and `size` layout.
2+
3+
struct NoPadding {
4+
@location(0)
5+
v3: vec3f, // align 16, size 12; no start padding needed
6+
@location(1)
7+
f3: f32, // align 4, size 4; no start padding needed
8+
}
9+
// struct NoPaddingNoBindings {
10+
// v3: vec3f,
11+
// f3: f32,
12+
// }
13+
@fragment
14+
fn no_padding_frag(input: NoPadding) -> @location(0) vec4f {
15+
_ = input;
16+
return vec4f(0.0);
17+
}
18+
@vertex
19+
fn no_padding_vert(input: NoPadding) -> @builtin(position) vec4f {
20+
_ = input;
21+
return vec4f(0.0);
22+
}
23+
24+
struct NeedsPadding {
25+
@location(0) f3_forces_padding: f32, // align 4, size 4; no start padding needed
26+
@location(1) v3_needs_padding: vec3f, // align 16, size 12; needs 12 bytes of padding
27+
@location(2) f3: f32, // align 4, size 4; no start padding needed
28+
}
29+
// struct NeedsPaddingNoBindings {
30+
// f3_forces_padding: f32,
31+
// v3_needs_padding: vec3f,
32+
// f3: f32,
33+
// }
34+
@fragment
35+
fn needs_padding_frag(input: NeedsPadding) -> @location(0) vec4f {
36+
_ = input;
37+
return vec4f(0.0);
38+
}
39+
@vertex
40+
fn needs_padding_vert(input: NeedsPadding) -> @builtin(position) vec4f {
41+
_ = input;
42+
return vec4f(0.0);
43+
}

naga/tests/out/msl/quad.msl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ using metal::uint;
66

77
struct VertexOutput {
88
metal::float2 uv;
9+
char _pad1[8];
910
metal::float4 position;
1011
};
1112
constant float c_scale = 1.2;
@@ -23,7 +24,7 @@ vertex vert_mainOutput vert_main(
2324
) {
2425
const auto pos = varyings.pos;
2526
const auto uv = varyings.uv;
26-
const auto _tmp = VertexOutput {uv, metal::float4(c_scale * pos, 0.0, 1.0)};
27+
const auto _tmp = VertexOutput {uv, {}, metal::float4(c_scale * pos, 0.0, 1.0)};
2728
return vert_mainOutput { _tmp.uv, _tmp.position };
2829
}
2930

0 commit comments

Comments
 (0)