GPU: Fix Android surface and swapchain recreation on app resume (#14676)

This commit is contained in:
999pingGG 2025-12-19 11:54:08 -06:00 committed by GitHub
parent 2c3657a0ce
commit 190b902fac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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) {