Skip to content

[Impeller] Move queue submission into a callback that is invoked by FenceWaiterVK::AddFence only if it can accept the fence#187761

Merged
auto-submit[bot] merged 4 commits into
flutter:masterfrom
jason-simmons:iplr_add_fence_before_submit_2
Jun 16, 2026
Merged

[Impeller] Move queue submission into a callback that is invoked by FenceWaiterVK::AddFence only if it can accept the fence#187761
auto-submit[bot] merged 4 commits into
flutter:masterfrom
jason-simmons:iplr_add_fence_before_submit_2

Conversation

@jason-simmons

@jason-simmons jason-simmons commented Jun 9, 2026

Copy link
Copy Markdown
Member

The FenceWaiterVK owns the lifetime of the fences that signal completion of a Vulkan command buffer submitted through vkQueueSubmit.

Prior to this PR, CommandQueueVK::Submit was submitting the command buffer to the queue with a fence before calling
FenceWaiterVK::AddFence. If AddFence failed, then the fence would be destroyed even though the Vulkan driver still holds its handle. That could cause a crash when the command completes and the Vulkan driver tries to signal the fence.

With this PR, the vkQueueSubmit call is moved into a callback that will be invoked by FenceWaiterVK::AddFence only if the FenceWaiterVK can take ownership of the fence. If the FenceWaiterVK has been terminated, then AddFence will skip the submit and destroy the fence.

Fixes #187703

…enceWaiterVK::AddFence only if it can accept the fence

The FenceWaiterVK owns the lifetime of the fences that signal
completion of a Vulkan command buffer submitted through vkQueueSubmit.

Prior to this PR, CommandQueueVK::Submit was submitting the command
buffer to the queue with a fence before calling
FenceWaiterVK::AddFence.  If AddFence failed, then the fence would be
destroyed even though the Vulkan driver still holds its handle.  That
could cause a crash when the command completes and the Vulkan driver
tries to signal the fence.

With this PR, the vkQueueSubmit call is moved into a callback that will
be invoked by FenceWaiterVK::AddFence only if the FenceWaiterVK can
take ownership of the fence.  If the FenceWaiterVK has been terminated,
then AddFence will skip the submit and destroy the fence.

Fixes flutter#187703
@jason-simmons jason-simmons requested a review from gaaclarke June 9, 2026 22:44
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 9, 2026
@github-actions github-actions Bot added engine flutter/engine related. See also e: labels. e: impeller Impeller rendering backend issues and features requests labels Jun 9, 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 Vulkan command submission by moving the queue submission step into FenceWaiterVK::AddFence via a callback, preventing submissions if the fence waiter is terminated. Unit tests and mock Vulkan helpers are updated to verify this behavior. Feedback recommends including <functional> in fence_waiter_vk.h to support std::function and declaring default_submit_callback as const auto in the unit tests to avoid potential linker errors.

@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 9, 2026
@jason-simmons jason-simmons added the CICD Run CI/CD label Jun 9, 2026

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking good, just a few notes.

Am I crazy or did I already submit a review on this? Did this PR get recreated? Maybe I just looked at it and didn't get a chance to submit my review =)

Comment on lines +26 to +27
EXPECT_EQ(std::find(called->begin(), called->end(), "vkQueueSubmit"),
called->end());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add a simple test to show that vkQueueSubmit is properly recorded too, please?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

/// the submitted command completes and the fence is signaled.
fml::Status AddFence(vk::UniqueFence fence,
std::function<fml::Status(vk::Fence)> submit_callback,
const fml::closure& completion_callback);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: we are going to store this so we could std::move it and often people put rvalues in callback parameters.

Suggested change
const fml::closure& completion_callback);
fml::closure completion_callback);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

EXPECT_FALSE(waiter->AddFence(std::move(fence), nullptr));
const auto add_status =
waiter->AddFence(std::move(fence), default_submit_callback, nullptr);
EXPECT_FALSE(add_status.ok());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

instead of expecting something is not ok, can you turn it to a equality assertion about what the error should be?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

namespace impeller {
namespace testing {

const auto default_submit_callback = [](vk::Fence) { return fml::Status(); };

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think gemini's advice here wrong. I would have just put it in an anonymous namespace.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

EXPECT_FALSE(waiter->AddFence(vk::UniqueFence(), []() {}));
const auto add_status =
waiter->AddFence(vk::UniqueFence(), default_submit_callback, []() {});
EXPECT_FALSE(add_status.ok());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

same here, eq test not false test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

VALIDATION_LOG << "Failed to submit queue: " << vk::to_string(status);
return fml::Status(fml::StatusCode::kCancelled, "Failed to submit queue: ");
}
auto submit_callback = [&](vk::Fence submit_fence) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"Use default capture by reference ([&]) only when the lifetime of the lambda is obviously shorter than any potential captures."

https://google.github.io/styleguide/cppguide.html#Lambda_expressions

It doesn't escape the current scope, but since we are passing the lambda along instead of calling it, it's probably better to treat it that way.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

Comment on lines +33 to +34
/// @brief Invokes the [submit_callback] and adds the fence to the wait set
/// if it succeeds. The [completion_callback] will be called when

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We should specify that the submit_callback is invoked synchronously so people can reason about lifetimes of objects captured by it.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

done

@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 10, 2026
@jason-simmons

Copy link
Copy Markdown
Member Author

Am I crazy or did I already submit a review on this? Did this PR get recreated? Maybe I just looked at it and didn't get a chance to submit my review =)

This PR is an updated variant of #187698

@jason-simmons jason-simmons added the CICD Run CI/CD label Jun 10, 2026
@gaaclarke gaaclarke self-requested a review June 15, 2026 18:00
gaaclarke
gaaclarke previously approved these changes Jun 15, 2026

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

lgtm, thanks!

@gaaclarke gaaclarke added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 15, 2026
@auto-submit

auto-submit Bot commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/flutter/187761, because - The status or check suite Linux linux_clang_tidy has failed. Please fix the issues identified (or deflake) before re-applying this label.

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 15, 2026
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 15, 2026
@jason-simmons jason-simmons added the CICD Run CI/CD label Jun 15, 2026
@jason-simmons jason-simmons requested a review from gaaclarke June 16, 2026 00:33

@gaaclarke gaaclarke left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

still lgtm

@gaaclarke

Copy link
Copy Markdown
Member

Oops, I said "still lgtm" I mean to say, "thanks, lgtm!" I forgot I didn't approve this one yet.

@jason-simmons jason-simmons added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 16, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue Jun 16, 2026
Merged via the queue into flutter:master with commit d135f1e Jun 16, 2026
206 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jun 16, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Jun 17, 2026
flutter/flutter@3a0420c...b10d0f1

2026-06-17 mr-peipei@web.de Skip platform-specific plugin registration if no platforms enabled (flutter/flutter#186304)
2026-06-17 engine-flutter-autoroll@skia.org Roll Packages from 8286d39 to 6ce00a8 (1 revision) (flutter/flutter#188109)
2026-06-17 engine-flutter-autoroll@skia.org Roll Skia from 79f93fd5f36e to 5d19002eb73e (1 revision) (flutter/flutter#188108)
2026-06-17 simon@journeyapps.com Import `dart:_js_interop_wasm` in addition to `dart:_wasm` to convert between `JSAny` and `WasmExternRef?` (flutter/flutter#186974)
2026-06-17 engine-flutter-autoroll@skia.org Roll Dart SDK from f811ecae9ca0 to e39bde5b1bfc (2 revisions) (flutter/flutter#188107)
2026-06-17 engine-flutter-autoroll@skia.org Roll Skia from 026f6a6be2b9 to 79f93fd5f36e (1 revision) (flutter/flutter#188105)
2026-06-17 engine-flutter-autoroll@skia.org Roll Dart SDK from 462bf0a1d489 to f811ecae9ca0 (1 revision) (flutter/flutter#188099)
2026-06-17 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from VeLhhlDcod09NR4Hb... to or21OEdGtairm6nl9... (flutter/flutter#188098)
2026-06-17 engine-flutter-autoroll@skia.org Roll Skia from 2ffd155313f5 to 026f6a6be2b9 (10 revisions) (flutter/flutter#188097)
2026-06-17 engine-flutter-autoroll@skia.org Roll Dart SDK from 824b4b48b6d4 to 462bf0a1d489 (1 revision) (flutter/flutter#188093)
2026-06-17 jason-simmons@users.noreply.github.com Manual Dart roll from f6c31f4c3a63 to 824b4b48b6d4 (flutter/flutter#188023)
2026-06-17 awolff@google.com Add a platform view test to android_hardware_smoke_test (flutter/flutter#188069)
2026-06-17 44747303+theprantadutta@users.noreply.github.com [flutter_tools] Format empty app template with latest dart format (flutter/flutter#187443)
2026-06-16 49699333+dependabot[bot]@users.noreply.github.com Bump the all-github-actions group across 1 directory with 3 updates (flutter/flutter#188086)
2026-06-16 engine-flutter-autoroll@skia.org Roll Skia from d7196b0b4939 to 2ffd155313f5 (9 revisions) (flutter/flutter#188081)
2026-06-16 43089218+chika3742@users.noreply.github.com Prevent downgrading `project.pbxproj` when greater version number (flutter/flutter#186250)
2026-06-16 magder@google.com Only allow dependabot to autoupdate GitHub-owned actions (flutter/flutter#187936)
2026-06-16 matt.boetger@gmail.com Fall back to source AndroidManifest.xml if AAPT fails or returns garbage (flutter/flutter#187197)
2026-06-16 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#187769)
2026-06-16 jason-simmons@users.noreply.github.com [Impeller] Move queue submission into a callback that is invoked by FenceWaiterVK::AddFence only if it can accept the fence (flutter/flutter#187761)
2026-06-16 jhy03261997@gmail.com Reland [a11y] Map some framework semantics roles to android classes.  (flutter/flutter#188037)
2026-06-16 1961493+harryterkelsen@users.noreply.github.com refactor(web): Unify Image on Skwasm and CanvasKit (flutter/flutter#187873)
2026-06-16 30870216+gaaclarke@users.noreply.github.com Adds arm64 variant of impeller devicelab tests for windows. (flutter/flutter#188053)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC bmparr@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
LouiseHsu pushed a commit to LouiseHsu/flutter that referenced this pull request Jun 18, 2026
…enceWaiterVK::AddFence only if it can accept the fence (flutter#187761)

The FenceWaiterVK owns the lifetime of the fences that signal completion
of a Vulkan command buffer submitted through vkQueueSubmit.

Prior to this PR, CommandQueueVK::Submit was submitting the command
buffer to the queue with a fence before calling
FenceWaiterVK::AddFence. If AddFence failed, then the fence would be
destroyed even though the Vulkan driver still holds its handle. That
could cause a crash when the command completes and the Vulkan driver
tries to signal the fence.

With this PR, the vkQueueSubmit call is moved into a callback that will
be invoked by FenceWaiterVK::AddFence only if the FenceWaiterVK can take
ownership of the fence. If the FenceWaiterVK has been terminated, then
AddFence will skip the submit and destroy the fence.

Fixes flutter#187703
via-guy pushed a commit to via-guy/flutter that referenced this pull request Jun 26, 2026
…enceWaiterVK::AddFence only if it can accept the fence (flutter#187761)

The FenceWaiterVK owns the lifetime of the fences that signal completion
of a Vulkan command buffer submitted through vkQueueSubmit.

Prior to this PR, CommandQueueVK::Submit was submitting the command
buffer to the queue with a fence before calling
FenceWaiterVK::AddFence. If AddFence failed, then the fence would be
destroyed even though the Vulkan driver still holds its handle. That
could cause a crash when the command completes and the Vulkan driver
tries to signal the fence.

With this PR, the vkQueueSubmit call is moved into a callback that will
be invoked by FenceWaiterVK::AddFence only if the FenceWaiterVK can take
ownership of the fence. If the FenceWaiterVK has been terminated, then
AddFence will skip the submit and destroy the fence.

Fixes flutter#187703
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD e: impeller Impeller rendering backend issues and features requests engine flutter/engine related. See also e: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HandleUsingDestroyedMutex assert can occur on Impeller/Vulkan if a command is submitted after shutdown of the FenceWaiter

2 participants