Skip to content

[Impeller] Submit a Vulkan command buffer only if its fence was successfully added to the FenceWaiterVK#187698

Closed
jason-simmons wants to merge 3 commits into
flutter:masterfrom
jason-simmons:iplr_add_fence_before_submit
Closed

[Impeller] Submit a Vulkan command buffer only if its fence was successfully added to the FenceWaiterVK#187698
jason-simmons wants to merge 3 commits into
flutter:masterfrom
jason-simmons:iplr_add_fence_before_submit

Conversation

@jason-simmons

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

Copy link
Copy Markdown
Member

The FenceWaiterVK may be in a state where it is unable to add a new fence. This could happen if the FenceWaiterVK has been terminated during engine shutdown.

If FenceWaiterVK::AddFence fails, then CommandQueueVK::Submit should not submit the command buffer.

Prior to this PR, CommandQueueVK::Submit was submitting the command buffer to the queue with the fence before calling 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.

Fixes #187703

…ssfully added to the FenceWaiterVK

The FenceWaiterVK may be in a state where it is unable to add a new
fence.  This could happen if the FenceWaiterVK has been terminated
during engine shutdown.

If FenceWaiterVK::AddFence fails, then CommandQueueVK::Submit should
not submit the command buffer.

Prior to this PR, CommandQueueVK::Submit was submitting the command
buffer to the queue with the fence before calling 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.
@jason-simmons jason-simmons requested a review from gaaclarke June 8, 2026 21:04
@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 8, 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 8, 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 modifies the Vulkan backend in Impeller to register fences with the FenceWaiterVK before submitting command buffers to the graphics queue, preventing potential race conditions. It also adds a RemoveFence method for cleanup on submission failure, introduces mock Vulkan support for queue submissions, and adds a unit test. Feedback on these changes includes appending the Vulkan result string to the submission error status, adding a null check for the fence entry in RemoveFence, refactoring the mock implementation to avoid const_cast by returning a non-const queue reference, and asserting that the submission status is a failure in the new unit test.

Comment thread engine/src/flutter/impeller/renderer/backend/vulkan/command_queue_vk.cc Outdated
Comment thread engine/src/flutter/impeller/renderer/backend/vulkan/test/mock_vulkan.cc Outdated
Comment thread engine/src/flutter/impeller/renderer/backend/vulkan/test/mock_vulkan.cc Outdated
Comment thread engine/src/flutter/impeller/renderer/backend/vulkan/test/mock_vulkan.cc Outdated
Comment thread engine/src/flutter/impeller/renderer/backend/vulkan/command_queue_vk_unittests.cc Outdated
@github-actions github-actions Bot removed the CICD Run CI/CD label Jun 8, 2026
@gaaclarke gaaclarke added the CICD Run CI/CD label Jun 8, 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, just some minor comments. Is there an issue that this should be linked to in the description?

MockDevice& device() const { return device_; }

private:
MockDevice& device_;

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: I'd prefer not to have a raw pointer here. It's not as big of a deal in testing code. We should add a comment about the ownership at least.

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.

Added a comment - the MockDevice owns the MockQueues, and each MockQueue holds a reference to its parent device.


void FenceWaiterVK::RemoveFence(vk::Fence fence) {
std::scoped_lock lock(wait_set_mutex_);
auto match = [fence](const std::shared_ptr<WaitSetEntry>& entry) {

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: I'm not sure if vk::Fence has a move constructor.

Suggested change
auto match = [fence](const std::shared_ptr<WaitSetEntry>& entry) {
auto match = [fence = std::move(fence)](const std::shared_ptr<WaitSetEntry>& entry) {

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.

no - vk::Fence is a thin wrapper over a VkFence and does not represent ownership.

auto buffer = context->CreateCommandBuffer();
context->GetFenceWaiter()->Terminate();
auto status = context->GetCommandQueue()->Submit({buffer});
EXPECT_FALSE(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 asserting ~ok() can we have an equality assert on what the error actually is?

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 8, 2026
@jason-simmons

Copy link
Copy Markdown
Member Author

LGTM, just some minor comments. Is there an issue that this should be linked to in the description?

This was a situation I noticed that could trigger a HandleUsingDestroyedMutex assert in the Mali Vulkan implementation. Filed #187703 with more info.

This may be related to other HandleUsingDestroyedMutex scenarios such as #187140.

@jason-simmons jason-simmons added the CICD Run CI/CD label Jun 8, 2026
@jason-simmons

Copy link
Copy Markdown
Member Author

This approach can lead to a situation where vkQueueSubmit is called concurrently with a vkWaitForFences call in the FenceWaiterVK that includes the same fence. That violates the Vulkan synchronization rules.

Closing this in favor of #187761

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