Skip to content

[Flutter GPU] Pass lifecycle: one recording pass per command buffer, ended by the next command #193867

Closed

Description

@bdero

Part of #188474.

A Flutter GPU pass never ends until submit(). lib/gpu creates the backend pass when the Dart pass is created and encodes every pass at submit, so on Metal two passes in one command buffer have two command encoders open at once, which Metal does not allow. Apps work around this today with one command buffer per render pass, and compute passes (#188480) would hit the same limit.

This implements the pass lifecycle decided on #188474. It changes render passes as well as compute, so it lands on its own.

Changes

  • A command buffer records one pass at a time, and passes execute in the order they are created.
  • Creating the next pass, or recording a copy or readback on the command buffer, ends the current pass. submit() ends the last one.
  • When a pass ends, its Metal or Vulkan encoder ends at that point, so a command buffer can hold any number of passes. OpenGL ES keeps encoding at submit, in the same order.
  • RenderPass.end() ends a pass explicitly and is harmless to call twice.
  • Any call on an ended pass throws a StateError naming what ended it, for example "RenderPass was ended when createRenderPass() was called on the same CommandBuffer".

Testing

gpu_test.dart on Metal, Vulkan and OpenGL ES:

  • Two render passes in one command buffer both render correctly.
  • Using a pass after the next pass was created, after a copy, or after end() throws.
  • Calling end() twice is harmless.

Dependencies

None.

Activity

  1. self-assigned this
    on Oct 5, 2026
  2. added
    c: new featureNothing broken; request for a new capability
    engineflutter/engine related. See also e: labels.
    e: impellerImpeller rendering backend issues and features requests
    on Oct 5, 2026
  3. added a commit that references this issue on Oct 11, 2026
    83e96f5
  4. added a commit that references this issue on Oct 19, 2026
    cb39a29
  5. moved this from 🤔 Needs Triage to 💡 Features in Flutter GPUon Oct 19, 2026
  6. moved this from 💡 Features to ✅ Done in Flutter GPUon Oct 20, 2026
  7. added a commit that references this issue on Oct 20, 2026
    1cc08bf
  8. added a commit that references this issue on Oct 29, 2026
    760740b
  9. github-actions commented on Nov 3, 2026

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  10. locked as resolved and limited conversation to collaborators on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

c: new featureNothing broken; request for a new capabilitye: impellerImpeller rendering backend issues and features requestsengineflutter/engine related. See also e: labels.flutter-gputeam-fluttergpuOwned by Flutter GPU team

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions