1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +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:
Chip Davis 2019-04-01 12:48:22 -05:00 committed by Philip Rebohle
parent b5f859915a
commit e633dbc06f
2 changed files with 23 additions and 10 deletions

View File

@ -10,8 +10,8 @@ namespace dxvk::vk {
const Rc<DeviceFn>& vkd, const Rc<DeviceFn>& vkd,
PresenterDevice device, PresenterDevice device,
const PresenterDesc& desc) const PresenterDesc& desc)
: m_vki(vki), m_vkd(vkd), m_device(device) { : m_vki(vki), m_vkd(vkd), m_device(device), m_window(window) {
if (createSurface(window) != VK_SUCCESS) if (createSurface() != VK_SUCCESS)
throw DxvkError("Failed to create surface"); throw DxvkError("Failed to create surface");
if (recreateSwapChain(desc) != VK_SUCCESS) if (recreateSwapChain(desc) != VK_SUCCESS)
@ -104,9 +104,21 @@ namespace dxvk::vk {
VkResult status; VkResult status;
if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
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( if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
m_device.adapter, m_surface, &caps)) != VK_SUCCESS) m_device.adapter, m_surface, &caps)) != VK_SUCCESS)
continue;
}
if (status != VK_SUCCESS)
return status; return status;
}
if ((status = getSupportedFormats(formats)) != VK_SUCCESS) if ((status = getSupportedFormats(formats)) != VK_SUCCESS)
return status; return status;
@ -355,16 +367,16 @@ namespace dxvk::vk {
} }
VkResult Presenter::createSurface(HWND window) { VkResult Presenter::createSurface() {
HINSTANCE instance = reinterpret_cast<HINSTANCE>( HINSTANCE instance = reinterpret_cast<HINSTANCE>(
GetWindowLongPtr(window, GWLP_HINSTANCE)); GetWindowLongPtr(m_window, GWLP_HINSTANCE));
VkWin32SurfaceCreateInfoKHR info; VkWin32SurfaceCreateInfoKHR info;
info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; info.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR;
info.pNext = nullptr; info.pNext = nullptr;
info.flags = 0; info.flags = 0;
info.hinstance = instance; info.hinstance = instance;
info.hwnd = window; info.hwnd = m_window;
VkResult status = m_vki->vkCreateWin32SurfaceKHR( VkResult status = m_vki->vkCreateWin32SurfaceKHR(
m_vki->instance(), &info, nullptr, &m_surface); m_vki->instance(), &info, nullptr, &m_surface);

View File

@ -174,6 +174,7 @@ namespace dxvk::vk {
PresenterDevice m_device; PresenterDevice m_device;
PresenterInfo m_info; PresenterInfo m_info;
HWND m_window = nullptr;
VkSurfaceKHR m_surface = VK_NULL_HANDLE; VkSurfaceKHR m_surface = VK_NULL_HANDLE;
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
@ -213,7 +214,7 @@ namespace dxvk::vk {
VkPresentModeKHR presentMode, VkPresentModeKHR presentMode,
uint32_t desired); uint32_t desired);
VkResult createSurface(HWND window); VkResult createSurface();
void destroySwapchain(); void destroySwapchain();