mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-02-20 19:54:19 +01:00
[vulkan] Recreate the surface on surface loss.
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.
This commit is contained in:
parent
b5f859915a
commit
e633dbc06f
@ -10,8 +10,8 @@ namespace dxvk::vk {
|
||||
const Rc<DeviceFn>& vkd,
|
||||
PresenterDevice device,
|
||||
const PresenterDesc& desc)
|
||||
: m_vki(vki), m_vkd(vkd), m_device(device) {
|
||||
if (createSurface(window) != VK_SUCCESS)
|
||||
: m_vki(vki), m_vkd(vkd), m_device(device), m_window(window) {
|
||||
if (createSurface() != VK_SUCCESS)
|
||||
throw DxvkError("Failed to create surface");
|
||||
|
||||
if (recreateSwapChain(desc) != VK_SUCCESS)
|
||||
@ -105,8 +105,20 @@ namespace dxvk::vk {
|
||||
VkResult status;
|
||||
|
||||
if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
m_device.adapter, m_surface, &caps)) != VK_SUCCESS)
|
||||
return status;
|
||||
m_device.adapter, m_surface, &caps)) != VK_SUCCESS) {
|
||||
while (status == VK_ERROR_SURFACE_LOST_KHR) {
|
||||
// Recreate the surface and try again.
|
||||
if (m_surface)
|
||||
destroySurface();
|
||||
if ((status = createSurface()) != VK_SUCCESS)
|
||||
continue;
|
||||
if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||
m_device.adapter, m_surface, &caps)) != VK_SUCCESS)
|
||||
continue;
|
||||
}
|
||||
if (status != VK_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
if ((status = getSupportedFormats(formats)) != VK_SUCCESS)
|
||||
return status;
|
||||
@ -355,16 +367,16 @@ namespace dxvk::vk {
|
||||
}
|
||||
|
||||
|
||||
VkResult Presenter::createSurface(HWND window) {
|
||||
VkResult Presenter::createSurface() {
|
||||
HINSTANCE instance = reinterpret_cast<HINSTANCE>(
|
||||
GetWindowLongPtr(window, GWLP_HINSTANCE));
|
||||
GetWindowLongPtr(m_window, GWLP_HINSTANCE));
|
||||
|
||||
VkWin32SurfaceCreateInfoKHR info;
|
||||
info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
|
||||
info.pNext = nullptr;
|
||||
info.flags = 0;
|
||||
info.hinstance = instance;
|
||||
info.hwnd = window;
|
||||
info.hwnd = m_window;
|
||||
|
||||
VkResult status = m_vki->vkCreateWin32SurfaceKHR(
|
||||
m_vki->instance(), &info, nullptr, &m_surface);
|
||||
@ -412,4 +424,4 @@ namespace dxvk::vk {
|
||||
m_vki->vkDestroySurfaceKHR(m_vki->instance(), m_surface, nullptr);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +174,7 @@ namespace dxvk::vk {
|
||||
PresenterDevice m_device;
|
||||
PresenterInfo m_info;
|
||||
|
||||
HWND m_window = nullptr;
|
||||
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
||||
|
||||
@ -213,7 +214,7 @@ namespace dxvk::vk {
|
||||
VkPresentModeKHR presentMode,
|
||||
uint32_t desired);
|
||||
|
||||
VkResult createSurface(HWND window);
|
||||
VkResult createSurface();
|
||||
|
||||
void destroySwapchain();
|
||||
|
||||
@ -221,4 +222,4 @@ namespace dxvk::vk {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user