Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[vulkan] Recreate the surface on surface loss. #991

Merged
merged 3 commits into from
Apr 2, 2019

Conversation

cdavis5e
Copy link
Contributor

@cdavis5e cdavis5e commented Apr 1, 2019

According to the Vulkan spec:

Several WSI functions return VK_ERROR_SURFACE_LOST_KHR if the
surface becomes no longer available. After such an error, the surface
(and any child swapchain, if one exists) should be destroyed, as
there is no way to restore them to a not-lost state.

So if we get this error, we need to recreate the surface in addition to
the swapchain.

According to the Vulkan spec:

> Several WSI functions return `VK_ERROR_SURFACE_LOST_KHR` if the
> surface becomes no longer available. After such an error, the surface
> (and any child swapchain, if one exists) **should** be destroyed, as
> there is no way to restore them to a not-lost state.

So if we get this error, we need to recreate the surface in addition to
the swapchain.
@doitsujin
Copy link
Owner

Does this actually fix anything? Asking because this should really not happen in any application that isn't broken on Windows.

@cdavis5e
Copy link
Contributor Author

cdavis5e commented Apr 1, 2019

Does this actually fix anything? Asking because this should really not happen in any application that isn't broken on Windows.

On Mac, the system will sometimes recreate any CAMetalLayer backing a view. This happens, for example, switching between windowed and fullscreen in Final Fantasy XIV--the window style is altered, and the system recreates all the backing stores, including the CAMetalLayer, in response. I have a change out on MoltenVK to make it generate VK_ERROR_SURFACE_LOST_KHR when this happens. Without both changes, the window changes to black and stays that way, because the surface we were using got pulled out from under us. With only the change to MoltenVK, FFXIV exits on switching from windowed to fullscreen, because the surface is now lost. With both these changes, I can switch between windowed and fullscreen at will.

If the surface is lost in a way that can't be recovered by recreating
the surface from the window, the previous change would wind up looping
forever. Just retry 5 times before giving up.
m_device.adapter, m_surface, &caps)) != VK_SUCCESS)
return status;
m_device.adapter, m_surface, &caps)) != VK_SUCCESS) {
for (uint32_t i = 0; i < 5 && status == VK_ERROR_SURFACE_LOST_KHR; i++) {
Copy link
Owner

Choose a reason for hiding this comment

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

Is there a valid scenario where this can fail an arbitrary number of times in a row? I'd prefer a solution with no more than one attempt if that is reasonable, since any functions that affect the window should have completed at this point.

@misyltoad
Copy link
Collaborator

misyltoad commented Apr 2, 2019

I have a change out on MoltenVK to make it generate VK_ERROR_SURFACE_LOST_KHR when this happens.

Slightly unrelated note, and I might be wrong here but: I have a feeling this will probably break lots of things (on the mvk side.)
I would be very skeptical of games/apps actually handling this correctly, (as in, remaining working) if at all.

If typical games treat that in the same way they treat d3d device loss, or lack thereof, then I'd think twice about not doing that transparently.

@doitsujin doitsujin merged commit 910e1a1 into doitsujin:master Apr 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants