From 2638537f92c833c24d212baf1b366300a68c4d3a Mon Sep 17 00:00:00 2001
From: HTuanPhong <[EMAIL REDACTED]>
Date: Thu, 2 Oct 2025 16:34:58 +0700
Subject: [PATCH] Fix vulkan gpu resize lag on windows
---
src/gpu/vulkan/SDL_gpu_vulkan.c | 78 ++++++++++++++++++++-------------
1 file changed, 48 insertions(+), 30 deletions(-)
diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c
index 25b05581cabfa..9ba63141a353f 100644
--- a/src/gpu/vulkan/SDL_gpu_vulkan.c
+++ b/src/gpu/vulkan/SDL_gpu_vulkan.c
@@ -3164,7 +3164,7 @@ static void VULKAN_INTERNAL_DestroySampler(
SDL_free(vulkanSampler);
}
-static void VULKAN_INTERNAL_DestroySwapchain(
+static void VULKAN_INTERNAL_DestroySwapchainImage(
VulkanRenderer *renderer,
WindowData *windowData)
{
@@ -3190,22 +3190,6 @@ static void VULKAN_INTERNAL_DestroySwapchain(
SDL_free(windowData->textureContainers);
windowData->textureContainers = NULL;
- if (windowData->swapchain) {
- renderer->vkDestroySwapchainKHR(
- renderer->logicalDevice,
- windowData->swapchain,
- NULL);
- windowData->swapchain = VK_NULL_HANDLE;
- }
-
- if (windowData->surface) {
- renderer->vkDestroySurfaceKHR(
- renderer->instance,
- windowData->surface,
- NULL);
- windowData->surface = VK_NULL_HANDLE;
- }
-
for (i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
if (windowData->imageAvailableSemaphore[i]) {
renderer->vkDestroySemaphore(
@@ -3230,6 +3214,33 @@ static void VULKAN_INTERNAL_DestroySwapchain(
windowData->imageCount = 0;
}
+static void VULKAN_INTERNAL_DestroySwapchain(
+ VulkanRenderer *renderer,
+ WindowData *windowData)
+{
+ if (windowData == NULL) {
+ return;
+ }
+
+ VULKAN_INTERNAL_DestroySwapchainImage(renderer, windowData);
+
+ if (windowData->swapchain) {
+ renderer->vkDestroySwapchainKHR(
+ renderer->logicalDevice,
+ windowData->swapchain,
+ NULL);
+ windowData->swapchain = VK_NULL_HANDLE;
+ }
+
+ if (windowData->surface) {
+ renderer->vkDestroySurfaceKHR(
+ renderer->instance,
+ windowData->surface,
+ NULL);
+ windowData->surface = VK_NULL_HANDLE;
+ }
+}
+
static void VULKAN_INTERNAL_DestroyGraphicsPipelineResourceLayout(
VulkanRenderer *renderer,
VulkanGraphicsPipelineResourceLayout *resourceLayout)
@@ -4484,17 +4495,20 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
windowData->frameCounter = 0;
- SDL_VideoDevice *_this = SDL_GetVideoDevice();
- SDL_assert(_this && _this->Vulkan_CreateSurface);
+ // We dont have to create surface again on recreate swapchain
+ if (windowData->surface == VK_NULL_HANDLE) {
+ SDL_VideoDevice *_this = SDL_GetVideoDevice();
+ SDL_assert(_this && _this->Vulkan_CreateSurface);
- // Each swapchain must have its own surface.
- if (!_this->Vulkan_CreateSurface(
- _this,
- windowData->window,
- renderer->instance,
- NULL, // FIXME: VAllocationCallbacks
- &windowData->surface)) {
- return false;
+ // Each swapchain must have its own surface.
+ if (!_this->Vulkan_CreateSurface(
+ _this,
+ windowData->window,
+ renderer->instance,
+ NULL, // FIXME: VAllocationCallbacks
+ &windowData->surface)) {
+ return false;
+ }
}
SDL_assert(windowData->surface);
@@ -4663,14 +4677,17 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
swapchainCreateInfo.compositeAlpha = compositeAlphaFlag;
swapchainCreateInfo.presentMode = SDLToVK_PresentMode[windowData->presentMode];
swapchainCreateInfo.clipped = VK_TRUE;
- swapchainCreateInfo.oldSwapchain = VK_NULL_HANDLE;
-
+ swapchainCreateInfo.oldSwapchain = windowData->swapchain;
vulkanResult = renderer->vkCreateSwapchainKHR(
renderer->logicalDevice,
&swapchainCreateInfo,
NULL,
&windowData->swapchain);
+ if (swapchainCreateInfo.oldSwapchain != VK_NULL_HANDLE) {
+ renderer->vkDestroySwapchainKHR(renderer->logicalDevice, swapchainCreateInfo.oldSwapchain, NULL);
+ }
+
if (swapchainSupportDetails.formatsLength > 0) {
SDL_free(swapchainSupportDetails.formats);
}
@@ -4684,6 +4701,7 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
windowData->surface,
NULL);
windowData->surface = VK_NULL_HANDLE;
+ windowData->swapchain = VK_NULL_HANDLE;
CHECK_VULKAN_ERROR_AND_RETURN(vulkanResult, vkCreateSwapchainKHR, false);
}
@@ -9890,7 +9908,7 @@ static Uint32 VULKAN_INTERNAL_RecreateSwapchain(
}
}
- VULKAN_INTERNAL_DestroySwapchain(renderer, windowData);
+ VULKAN_INTERNAL_DestroySwapchainImage(renderer, windowData);
return VULKAN_INTERNAL_CreateSwapchain(renderer, windowData);
}