Skip to content

[Flutter GPU] Allow specifying vertex step mode and instance step rate #186307

Description

@bdero

The VertexBufferLayout shipped in #186310 only supports per-vertex stepping. There is no way today to mark a vertex buffer slot as supplying per-instance data, which is the primitive every modern asset-heavy renderer (sprite batchers, particles, foliage and decal scattering, light volumes, GPU-driven UI lists) leans on for cheap instanced draws.

Proposal

Extend VertexBufferLayout with two new named parameters:

enum VertexStepMode { vertex, instance }

class VertexBufferLayout {
  const VertexBufferLayout({
    required this.binding,
    required this.strideInBytes,
    this.stepMode = VertexStepMode.vertex,
    this.stepRate = 1,
  });

  final int binding;
  final int strideInBytes;
  final VertexStepMode stepMode;
  final int stepRate;
}

stepMode defaults to vertex (today's behavior). stepRate defaults to 1 and only takes effect when stepMode == VertexStepMode.instance; a value of 2 means "the same attribute is reused across two consecutive instances before advancing", which is what every other modern HAL with instanced rendering exposes.

Both parameters default to their no-op values, so adding them is a non-breaking change.

Validation

createRenderPipeline should throw a Dart exception if:

  • stepMode == VertexStepMode.vertex and stepRate != 1.
  • stepRate < 1.

HAL dependency

ShaderStageBufferLayout in impeller/core/shader_types.h would need an inputRate field (mirroring the VkVertexInputRate/MTLVertexStepFunction cross-HAL primitive), and the Vulkan backend would need VK_KHR_vertex_attribute_divisor (or 1.4 core) plumbing for stepRate > 1. The Metal and OpenGLES backends already have native support.

Out of scope

  • Per-attribute step mode. None of the modern HALs expose this; the step mode lives on the buffer layout.
  • stepRate = 0 ('broadcast a single attribute value across every instance'). Useful but rare; can be added later via a third enum value (VertexStepMode.constant) without breaking this proposal.

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