From 0d7aff9c56ef3dbf5744b61209839831539004f3 Mon Sep 17 00:00:00 2001 From: Frank Praznik Date: Thu, 31 Jul 2025 19:56:46 -0400 Subject: [PATCH] GPU: Vulkan backend flags command buffer for cleanup when swapchain is requested When skipping presentation due to the window being hidden, presentDataCount is not incremented on the command buffer, and subsequently the submitted command buffers will not be cleaned up as long as the window is hidden. This results in a lag spike when showing the window due to all previously submitted command buffers suddenly being cleaned up at once, and lag at shutdown due to an equivalent number of fences needing to be destroyed. Instead of relying on presentDataCount to determine whether a command buffer should be cleaned up, use a flag, which is set under the appropriate circumstances. (cherry picked from commit 42463569d5e0b0949674b90247dae8d934765442) --- src/gpu/vulkan/SDL_gpu_vulkan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 7eabee8d14..66f486fa6d 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -1108,6 +1108,7 @@ typedef struct VulkanCommandBuffer VulkanFenceHandle *inFlightFence; bool autoReleaseFence; + bool swapchainRequested; bool isDefrag; // Whether this CB was created for defragging } VulkanCommandBuffer; @@ -9934,6 +9935,9 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false); } + // The command buffer is flagged for cleanup when the swapchain is requested as a cleanup timing mechanism + vulkanCommandBuffer->swapchainRequested = true; + if (window->flags & SDL_WINDOW_HIDDEN) { // Edge case, texture is filled in with NULL but not an error return true; @@ -10392,6 +10396,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( commandBuffer->presentDataCount = 0; commandBuffer->waitSemaphoreCount = 0; commandBuffer->signalSemaphoreCount = 0; + commandBuffer->swapchainRequested = false; // Reset defrag state @@ -10548,7 +10553,7 @@ static bool VULKAN_Submit( VulkanTextureSubresource *swapchainTextureSubresource; VulkanMemorySubAllocator *allocator; bool performCleanups = - (renderer->claimedWindowCount > 0 && vulkanCommandBuffer->presentDataCount > 0) || + (renderer->claimedWindowCount > 0 && vulkanCommandBuffer->swapchainRequested) || renderer->claimedWindowCount == 0; SDL_LockMutex(renderer->submitLock);