Skip to content

vk: handle non-error cases for swapchain acquire#9909

Merged
poweifeng merged 2 commits intomainfrom
pf/vk-better-handle-swapchain-acquire
May 6, 2026
Merged

vk: handle non-error cases for swapchain acquire#9909
poweifeng merged 2 commits intomainfrom
pf/vk-better-handle-swapchain-acquire

Conversation

@poweifeng
Copy link
Copy Markdown
Contributor

When acquiring an image in a swapchain, we could get VK_ERROR_OUT_OF_DATE_KHR or VK_SUBOPTIMAL_KHR for acceptable states like window resizing. For those cases, instead of failing to acquire, we recreate the swapchain and try to acquire swapchain image again

Fixes #9732

@poweifeng poweifeng added the internal Issue/PR does not affect clients label Apr 16, 2026
@poweifeng poweifeng force-pushed the pf/vk-better-handle-swapchain-acquire branch from 971bf73 to bfadb8b Compare April 16, 2026 18:34
VkResult result = VK_NOT_READY;
size_t acquireTryCount = 0;

while (acquireTryCount++ < MAX_ACQUIRE_TRY_COUNT && result != VK_SUCCESS) {
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.

why do we need to retry? and also if you flushed/waited already, why do it again?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

why do we need to retry?

I'm just trying to account for the case where a user is drag-resizing a window, in which case, I imagine we might hit multiple VK_SUBOPTIMAL_KHR or VK_ERROR_OUT_OF_DATE_KHR. But that's just my guess and not based on any particular platform.

and also if you flushed/waited already, why do it again?

That's a good point, but flush() and wait() is essentially no-op when there is no buffer being recorded. So calling it multiple times is fine.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

let me know if you prefer changes to either of the above.

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.

So I think we should try it once and that's it.

In the case of out of date, it it fails, we just record, submit and wont present anything.
Will that break anything?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

so I had to do more work, but I added some guards so that calls that concern the renderpass are skipped, because we cannot construct a valid renderpass when the acquire fails.

// Check if the swapchain should be resized.
if ((resized = mPlatform->hasResized(swapChain))) {
auto recreateSwapchain = [&]() {
recreated = true;
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.

recreated is only updated to true throughout the code flow. do we need to set it to false as default at the beginning of this function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

sure, done

@poweifeng poweifeng force-pushed the pf/vk-better-handle-swapchain-acquire branch 2 times, most recently from 4ee3d3d to 3654bfd Compare April 22, 2026 21:44
@poweifeng poweifeng force-pushed the pf/vk-better-handle-swapchain-acquire branch from 3654bfd to 2ccecba Compare April 22, 2026 21:57
// Used for cases where the backing swapchain needs to be recreated.
auto recreate = [&]() {
// Calling flush multiptle times is ok, since it's no-op if not recording.
if (mFlushAndWaitOnResize) {
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.

I think its better to just move this function inside the if, easier to read it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

auto swapChain = resource_ptr<VulkanSwapChain>::cast(&mResourceManager, sch);

// Present the backbuffer after the most recent command buffer submission has finished.
swapChain->present(*this);
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.

what about here? in the case of skip, there's no need to do present but do we still have to be aware that things have to be submitted?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

it'll be no-op since the swapchain was not acquired. Other commands will be submitted with the flush call, or on the next frame

When acquiring an image in a swapchain, we could get
VK_ERROR_OUT_OF_DATE_KHR or VK_SUBOPTIMAL_KHR for acceptable states
like window resizing. For those cases, instead of failing to acquire,
we recreate the swapchain and try to acquire swapchain image again.

In case where acquire fails even after the recreation, then we
simply don't draw(). Because acquire happens on beginRenderPass
(we need backing images for the fbo), if acquire fails, then
we assume the renderpass is also invalid, and subsquent calls to
make use of it (e.g. bindPipeline) would just be no-op.

Fixes #9732
@poweifeng poweifeng force-pushed the pf/vk-better-handle-swapchain-acquire branch from 2ccecba to 1d13c81 Compare May 5, 2026 21:06
@poweifeng poweifeng enabled auto-merge (squash) May 6, 2026 17:18
@poweifeng poweifeng merged commit 928a20b into main May 6, 2026
18 checks passed
@poweifeng poweifeng deleted the pf/vk-better-handle-swapchain-acquire branch May 6, 2026 17:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Issue/PR does not affect clients

Projects

None yet

Development

Successfully merging this pull request may close these issues.

VulkanSwapChain::acquire returns early on VK_SUBOPTIMAL_KHR instead of treating it as successful acquire

4 participants