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

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