Skip to content

Metal shader translation does not align vec3s to match std140 #4522

@kpreid

Description

@kpreid

See later updates as this original description is an incorrect diagnosis.

My application worked OK under the Metal backend but mis-shaded under the WebGL backend. I made the problem disappear by modifying my camera uniform struct to avoid lone f32s in favor of vec4<f32>s.

My understanding is that this is because WebGL uniforms expect “std140” layout which pads every field up to a multiple of 16 bytes (the size of a vec4<f32>). (My own knowledge of GL is limited here, as I never used structs in uniforms rather than individual scalar/vector/matrix uniforms before starting to use wgpu, so I could be missing some nuance.)

It seems to me that, to support portability between backends, wgpu should either:

  • do whatever code transformation is necessary to effectively not have std140 padding on the WebGL backend (probably not a good idea), or
  • consider it a MissingDownlevelFlags error when a shader has a struct used as a uniform which has padding under std140 that would not be present on other backends. (In particular, DownlevelFlags::BUFFER_BINDINGS_NOT_16_BYTE_ALIGNED probably applies to the same situations; maybe it should be renamed and expanded to cover this?)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions