Skip to content

[Flutter GPU] End each pass when the next command is recorded - #194167

Merged
auto-submit[bot] merged 1 commit into
masterfrom
bdero/flutter-gpu-pass-lifecycle
Oct 20, 2026
Merged

auto-submit[bot] merged 1 commit into
masterfrom
bdero/flutter-gpu-pass-lifecycle

Conversation

@bdero

@bdero bdero commented Oct 11, 2026

Copy link
Copy Markdown
Member

Fixes #193867. Part of #188474.

A command buffer now records one pass at a time, so it can hold any number of passes on every backend. Before, every pass stayed open until submit, which on Metal limited a command buffer to one render pass.

  • Creating the next pass, recording a copy, or submitting ends the open pass, and RenderPass.end() ends it explicitly. On Metal and Vulkan the pass is encoded at that point.
  • Using an ended pass, or recording into a submitted command buffer, throws a StateError that says why.

Pre-launch Checklist

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Oct 11, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. flutter-gpu team-fluttergpu Owned by Flutter GPU team labels Oct 11, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the Flutter GPU command buffer to explicitly manage the lifecycle of render and blit passes, ensuring that open passes are ended before new passes or copies are recorded, or when the command buffer is submitted. Feedback on the changes highlights a critical issue in the OpenGL ES backend where deferred passes are never encoded during submission due to the removal of the encoding loop. It is recommended to explicitly encode these deferred passes during submission and update the unit tests to verify this behavior.

@gaaclarke
gaaclarke requested a review from walley892 October 12, 2026 21:43
A command buffer now records one pass at a time. Creating the next render
pass, recording a copy, or submitting ends the open pass, and
RenderPass.end() ends it explicitly. On Metal and Vulkan the ended pass is
encoded at that point, before the next backend pass is created, so one
command buffer can hold any number of passes. OpenGL ES still encodes every
pass in creation order at submit, on the raster thread.

Any call on an ended RenderPass throws a StateError naming what ended it.
Creating a pass or recording a copy after submit throws a StateError.

Fixes #193867.
@bdero
bdero force-pushed the bdero/flutter-gpu-pass-lifecycle branch from 83e96f5 to cb39a29 Compare October 19, 2026 23:05
@bdero bdero added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 20, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Oct 20, 2026
Merged via the queue into master with commit 1cc08bf Oct 20, 2026
38 of 39 checks passed
@auto-submit
auto-submit Bot deleted the bdero/flutter-gpu-pass-lifecycle branch October 20, 2026 22:06
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Oct 20, 2026
@github-project-automation github-project-automation Bot moved this from 🤔 Needs Triage to ✅ Done in Flutter GPU Oct 20, 2026
@bdero
bdero restored the bdero/flutter-gpu-pass-lifecycle branch October 20, 2026 22:36
@bdero
bdero deleted the bdero/flutter-gpu-pass-lifecycle branch October 20, 2026 22:37
bdero added a commit to bdero/flutter that referenced this pull request Oct 20, 2026
Brings in master through the pass lifecycle change (flutter#194167), which this
branch was stacked on and already contains, so the PR diff shows only the
compute changes.
mohamedalsamrai pushed a commit to mohamedalsamrai/flutter that referenced this pull request Oct 26, 2026
Fixes flutter#188477, fixes flutter#188479, fixes
flutter#188480, fixes flutter#193868, fixes
flutter#193869, fixes flutter#193872. Part of
flutter#188474 and flutter#188481.

Adds compute to Flutter GPU on Metal and Vulkan. Stacked on flutter#194167.

- Shader bundles (format version 3) carry each shader's storage buffers
and compute workgroup size.
- `gpuContext.createComputePipeline`, `CommandBuffer.createComputePass`
and `ComputePass`, with storage, uniform and texture bindings, binding
sets and `dispatch`. `gpuContext.supportsCompute` and the compute limits
are exposed; on OpenGL ES compute is unsupported and the compute calls
throw.
- Impeller: workgroup sizes are checked against device limits when a
pipeline is created, bindings persist across dispatches on Vulkan,
dispatches and passes synchronize automatically, and reloading a compute
shader no longer crashes.
- End-to-end tests on Metal and Vulkan, including a compute pass writing
vertices that a render pass draws.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…r#194167)

Fixes flutter#193867. Part of flutter#188474.

A command buffer now records one pass at a time, so it can hold any
number of passes on every backend. Before, every pass stayed open until
submit, which on Metal limited a command buffer to one render pass.

- Creating the next pass, recording a copy, or submitting ends the open
pass, and `RenderPass.end()` ends it explicitly. On Metal and Vulkan the
pass is encoded at that point.
- Using an ended pass, or recording into a submitted command buffer,
throws a `StateError` that says why.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
Fixes flutter#188477, fixes flutter#188479, fixes
flutter#188480, fixes flutter#193868, fixes
flutter#193869, fixes flutter#193872. Part of
flutter#188474 and flutter#188481.

Adds compute to Flutter GPU on Metal and Vulkan. Stacked on flutter#194167.

- Shader bundles (format version 3) carry each shader's storage buffers
and compute workgroup size.
- `gpuContext.createComputePipeline`, `CommandBuffer.createComputePass`
and `ComputePass`, with storage, uniform and texture bindings, binding
sets and `dispatch`. `gpuContext.supportsCompute` and the compute limits
are exposed; on OpenGL ES compute is unsupported and the compute calls
throw.
- Impeller: workgroup sizes are checked against device limits when a
pipeline is created, bindings persist across dispatches on Vulkan,
dispatches and passes synchronize automatically, and reloading a compute
shader no longer crashes.
- End-to-end tests on Metal and Vulkan, including a compute pass writing
vertices that a render pass draws.

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [AI contribution guidelines] and understand my
responsibilities, or I am not using AI tools.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[AI contribution guidelines]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#ai-contribution-guidelines
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD engine flutter/engine related. See also e: labels. flutter-gpu team-fluttergpu Owned by Flutter GPU team

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

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

2 participants