|
|
@@ -668,6 +668,7 @@ typedef struct WindowData
|
|
|
SDL_GPUSwapchainComposition swapchainComposition;
|
|
|
SDL_GPUPresentMode presentMode;
|
|
|
bool needsSwapchainRecreate;
|
|
|
+ bool needsSurfaceRecreate;
|
|
|
Uint32 swapchainCreateWidth;
|
|
|
Uint32 swapchainCreateHeight;
|
|
|
|
|
|
@@ -4656,7 +4657,8 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
|
|
|
swapchainCreateInfo.compositeAlpha = compositeAlphaFlag;
|
|
|
swapchainCreateInfo.presentMode = SDLToVK_PresentMode[windowData->presentMode];
|
|
|
swapchainCreateInfo.clipped = VK_TRUE;
|
|
|
- swapchainCreateInfo.oldSwapchain = windowData->swapchain;
|
|
|
+ // The old swapchain could belong to a surface that no longer exists due to app switching.
|
|
|
+ swapchainCreateInfo.oldSwapchain = windowData->needsSurfaceRecreate ? (VkSwapchainKHR)0 : windowData->swapchain;
|
|
|
vulkanResult = renderer->vkCreateSwapchainKHR(
|
|
|
renderer->logicalDevice,
|
|
|
&swapchainCreateInfo,
|
|
|
@@ -9662,6 +9664,7 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e)
|
|
|
if (e->type == SDL_EVENT_DID_ENTER_BACKGROUND) {
|
|
|
data = VULKAN_INTERNAL_FetchWindowData(w);
|
|
|
data->needsSwapchainRecreate = true;
|
|
|
+ data->needsSurfaceRecreate = true;
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
@@ -9977,6 +9980,24 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ if (windowData->needsSurfaceRecreate) {
|
|
|
+ SDL_VideoDevice *videoDevice = SDL_GetVideoDevice();
|
|
|
+ SDL_assert(videoDevice);
|
|
|
+ SDL_assert(videoDevice->Vulkan_CreateSurface);
|
|
|
+ renderer->vkDestroySurfaceKHR(
|
|
|
+ renderer->instance,
|
|
|
+ windowData->surface,
|
|
|
+ NULL);
|
|
|
+ if (!videoDevice->Vulkan_CreateSurface(
|
|
|
+ videoDevice,
|
|
|
+ windowData->window,
|
|
|
+ renderer->instance,
|
|
|
+ NULL, // FIXME: VAllocationCallbacks
|
|
|
+ &windowData->surface)) {
|
|
|
+ SET_STRING_ERROR_AND_RETURN("Failed to recreate Vulkan surface!", false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// If window data marked as needing swapchain recreate, try to recreate
|
|
|
if (windowData->needsSwapchainRecreate) {
|
|
|
Uint32 recreateSwapchainResult = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData);
|
|
|
@@ -9992,6 +10013,10 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
+ // Unset this flag until after the swapchain has been recreated to let VULKAN_INTERNAL_CreateSwapchain()
|
|
|
+ // know whether it needs to pass the old swapchain or not.
|
|
|
+ windowData->needsSurfaceRecreate = false;
|
|
|
}
|
|
|
|
|
|
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
|