miniquad icon indicating copy to clipboard operation
miniquad copied to clipboard

Pipeline::with_parms(): basic alignment rules: field is aligned to its element size, total struct size is aligned to maximum element size

Open koalefant opened this issue 5 years ago • 3 comments

I am not sure if this is general-enough solution, but right now it is easy to do vertex layout that breaks due to alignment. I.e. total stride would be incorrectly computed for following layout as trailing padding was not considered (Linux/x64 and wasm32-unknown-unknown).

                miniquad::VertexAttribute::new("eyes", miniquad::VertexFormat::Float4),
                miniquad::VertexAttribute::new("body_direction", miniquad::VertexFormat::Float4),
                miniquad::VertexAttribute::new("world_pos", miniquad::VertexFormat::Float2),
                miniquad::VertexAttribute::new("center", miniquad::VertexFormat::Float2),
                miniquad::VertexAttribute::new("velocity", miniquad::VertexFormat::Float2),
                miniquad::VertexAttribute::new("head_direction", miniquad::VertexFormat::Float2),
                miniquad::VertexAttribute::new("mouth", miniquad::VertexFormat::Float3),
                miniquad::VertexAttribute::new("feet_pos", miniquad::VertexFormat::Float4),
                miniquad::VertexAttribute::new("color_light", miniquad::VertexFormat::Byte3),
                miniquad::VertexAttribute::new("color_mid", miniquad::VertexFormat::Byte3),
                miniquad::VertexAttribute::new("color_dark", miniquad::VertexFormat::Byte3),

And following struct:

#[repr(C)]
struct PawnVertex {
    eyes: [f32; 4],
    body_direction: [f32; 4],
    pos: [f32; 2],
    center: [f32; 2],
    velocity: [f32; 2],
    head_direction: [f32; 2],
    mouth: [f32; 3],
    feet_pos: [f32; 4],
    color_light: [u8; 3],
    color_mid: [u8; 3],
    color_dark: [u8; 3],
}

P.S. Please don't ask me what do I shove into my vertices ^____^

koalefant avatar Mar 20 '20 19:03 koalefant

I am still thinking about this PR.

The other option for your use case: add #[repr(C, packed(1))] to the PawnVertex struct. Unfortunately, it looks like it is impossible to check that struct is packed without proc-macros.

not-fl3 avatar Mar 28 '20 08:03 not-fl3

No rush on my side - I am building with a patched copy of the crate.

I would probably avoid #[repr(C, packed(1))] myself and not suggest to anyone else as it is easy to introduce non-aligned fields with it, those are slower to load on x64 and unaligned float loads crash on ARM.

A random idea: perhaps iterating over fields with some kind of offset_of, would be a cleaner solution? Maybe a derive macro that would help automate this?

koalefant avatar Mar 28 '20 21:03 koalefant

unaligned float loads crash on ARM.

Good point!

I would really, really like to avoid obligatory proc macros :(

not-fl3 avatar Mar 28 '20 23:03 not-fl3