Skip to content

feat(graphics): adopt WGSL uniform_buffer_standard_layout for tighter uniform-buffer packing #8791

@mvaligursky

Description

@mvaligursky

Background

Chrome 144 added the WGSL uniform_buffer_standard_layout language feature. When enabled via requires uniform_buffer_standard_layout;, uniform buffers may use the same memory layout constraints as storage buffers — in particular, the 16-byte alignment requirement on array elements is lifted. This matches GLSL's std430 semantics.

Why this matters

The engine packs uniform data into uniform buffers automatically (via the uniform buffer / dynamic buffer paths). Today, arrays like array<f32, N> or array<vec3<f32>, N> get padded out to 16-byte stride, wasting bandwidth and complicating layouts shared between uniform and storage buffers.

With this feature, the engine could:

  • Pack array<f32, N> and array<vec3<f32>, N> at natural stride
  • Share data structure layouts between uniform and storage buffers without padding hacks
  • Reduce uniform buffer bandwidth for the affected types

Why this is more work than a typical WGSL feature cap

Unlike the other WGSL feature caps (which just emit a requires directive and let shaders opt-in conditionally), the engine's uniform buffer packing code in JS (e.g. UniformBuffer, UniformBufferFormat, the dynamic buffer system) currently encodes the std140-style alignment rules. To benefit from uniform_buffer_standard_layout, the packing logic itself has to branch on the cap and apply std430-style stride when supported.

This means:

  • JS-side packing layout needs to be cap-aware (per-device, since Firefox/Safari may not support it)
  • Shader-side struct layouts may need conditional padding for portability
  • Existing uniform buffer formats / layouts may need versioning to avoid breaking pre-built shaders

Suggested approach

  1. Add the WGSL feature cap infrastructure (supportsUniformBufferStandardLayout, CAPS_UNIFORM_BUFFER_STANDARD_LAYOUT, requires uniform_buffer_standard_layout;) — trivial, follows the existing pattern (feat(graphics): expose WGSL unrestricted_pointer_parameters as a device cap #8785, feat(graphics): expose WGSL pointer_composite_access as a device cap #8786, feat(graphics): expose WGSL packed_4x8_integer_dot_product as a device cap #8787, #TBD).
  2. Audit the JS uniform-buffer packing code paths to identify where the std140 alignment is applied and what would need to change.
  3. Decide on a portability strategy: do shaders always use the tighter layout where supported and fall back where not, or is this opt-in per uniform buffer?
  4. Implement and validate across the WebGPU paths.

References

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions