Skip to content

[Flutter GPU] Add normalized, packed, half-float, BGRA-swizzled, and 64-bit vertex attribute formats #186309

Description

@bdero

The VertexFormat enum shipped in #186310 only covers the 32-bit-per-component scalar types (float32, uint32, sint32 in 1, 2, 3, and 4 component widths). This is enough for hand-rolled vertex buffers and most flutter_gpu samples, but it forces every glTF, KTX2, or other industry-format asset to be expanded to 32-bit-per-component on the CPU before upload. It also prevents storing the dart:ui Color packed-byte representation directly in a vertex stream.

Proposal

Grow VertexFormat with the following values, each adding only a new enum entry (no breaking change to existing ones):

  • 8-bit normalized integer: unorm8, unorm8x2, unorm8x4, snorm8, snorm8x2, snorm8x4, uint8, uint8x2, uint8x4, sint8, sint8x2, sint8x4.
  • 8-bit packed BGRA: unorm8x4Bgra (canonical Color packed format, swizzled).
  • 16-bit normalized integer: unorm16, unorm16x2, unorm16x4, snorm16, snorm16x2, snorm16x4, uint16, uint16x2, uint16x4, sint16, sint16x2, sint16x4.
  • 16-bit half-float: float16, float16x2, float16x4.
  • 10/10/10/2 packed: unorm10_10_10_2 (compact normalized normals / tangents).
  • 64-bit float (optional, gated by capability): float64, float64x2, float64x3, float64x4.

Each VertexFormat value would expose its bytesPerElement and componentCount getters as today. Validation would continue to enforce that the shader's declared scalar type class (float / signed int / unsigned int) matches the supplied format; component-count substitution rules (missing components fill to (0, 0, 0, 1)) stay backend-default.

HAL dependency

Today ShaderStageIOSlot describes the format as a (ShaderType, bit_width, vec_size, columns, relaxed_precision) tuple, which can't represent normalization or packed formats and has no way to mark bgra swizzle. Two options:

  1. Add a flat VertexAttributeFormat enum on ShaderStageIOSlot that captures all of the above directly (the modern shape used by every HAL we target).
  2. Add a normalize: bool bit and a separate packed_format: enum on ShaderStageIOSlot to retrofit on top of the current decomposed shape.

Option 1 is much cleaner and matches what the backends ultimately need.

Closes once landed

#102778 (Impeller-side feature request to map host-side uint32 colors to shader-side vec4).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    c: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterengineflutter/engine related. See also e: labels.flutter-gputeam-fluttergpuOwned by Flutter GPU team

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status
    💡 Features

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions