diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index a70a399eabee6..5983ce66713b9 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -3263,7 +3263,7 @@ extern SDL_DECLSPEC bool SDLCALL SDL_WindowSupportsGPUPresentMode( * Claims a window, creating a swapchain structure for it. * * This must be called before SDL_AcquireGPUSwapchainTexture is called using - * the window. + * the window. You should only call this function from the thread that created the window. * * The swapchain will be created with SDL_GPU_SWAPCHAINCOMPOSITION_SDR and * SDL_GPU_PRESENTMODE_VSYNC. If you want to have different swapchain diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 90402ede29203..a7472fc136c80 100644 --- a/src/gpu/d3d11/SDL_gpu_d3d11.c +++ b/src/gpu/d3d11/SDL_gpu_d3d11.c @@ -482,6 +482,7 @@ typedef struct D3D11WindowData DXGI_COLOR_SPACE_TYPE swapchainColorSpace; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; Uint32 frameCounter; + bool needsSwapchainRecreate; } D3D11WindowData; typedef struct D3D11Shader @@ -5021,6 +5022,18 @@ static D3D11WindowData *D3D11_INTERNAL_FetchWindowData( return (D3D11WindowData *)SDL_GetPointerProperty(properties, WINDOW_PROPERTY_DATA, NULL); } +static bool D3D11_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) +{ + SDL_Window *w = (SDL_Window *)userdata; + D3D11WindowData *data; + if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) { + data = D3D11_INTERNAL_FetchWindowData(w); + data->needsSwapchainRecreate = true; + } + + return true; +} + static bool D3D11_INTERNAL_InitializeSwapchainTexture( D3D11Renderer *renderer, IDXGISwapChain *swapchain, @@ -5089,7 +5102,6 @@ static bool D3D11_INTERNAL_CreateSwapchain( SDL_GPUPresentMode presentMode) { HWND dxgiHandle; - int width, height; Uint32 i; DXGI_SWAP_CHAIN_DESC swapchainDesc; DXGI_FORMAT swapchainFormat; @@ -5105,9 +5117,6 @@ static bool D3D11_INTERNAL_CreateSwapchain( dxgiHandle = (HWND)windowData->window; #endif - // Get the window size - SDL_GetWindowSize(windowData->window, &width, &height); - swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition]; // Initialize the swapchain buffer descriptor @@ -5216,6 +5225,10 @@ static bool D3D11_INTERNAL_CreateSwapchain( return false; } + int w, h; + SDL_SyncWindow(windowData->window); + SDL_GetWindowSizeInPixels(windowData->window, &w, &h); + // Initialize dummy container, width/height will be filled out in AcquireSwapchainTexture SDL_zerop(&windowData->textureContainer); windowData->textureContainer.textures = SDL_calloc(1, sizeof(D3D11Texture *)); @@ -5231,6 +5244,8 @@ static bool D3D11_INTERNAL_CreateSwapchain( windowData->textureContainer.header.info.num_levels = 1; windowData->textureContainer.header.info.sample_count = SDL_GPU_SAMPLECOUNT_1; windowData->textureContainer.header.info.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET; + windowData->textureContainer.header.info.width = w; + windowData->textureContainer.header.info.height = h; windowData->texture.container = &windowData->textureContainer; windowData->texture.containerIndex = 0; @@ -5240,32 +5255,41 @@ static bool D3D11_INTERNAL_CreateSwapchain( static bool D3D11_INTERNAL_ResizeSwapchain( D3D11Renderer *renderer, - D3D11WindowData *windowData, - Sint32 width, - Sint32 height) + D3D11WindowData *windowData) { + D3D11_Wait((SDL_GPURenderer *)renderer); + // Release the old RTV ID3D11RenderTargetView_Release(windowData->texture.subresources[0].colorTargetViews[0]); SDL_free(windowData->texture.subresources[0].colorTargetViews); SDL_free(windowData->texture.subresources); + int w, h; + SDL_SyncWindow(windowData->window); + SDL_GetWindowSizeInPixels(windowData->window, &w, &h); + // Resize the swapchain HRESULT res = IDXGISwapChain_ResizeBuffers( windowData->swapchain, 0, // Keep buffer count the same - width, - height, + w, + h, DXGI_FORMAT_UNKNOWN, // Keep the old format renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0); CHECK_D3D11_ERROR_AND_RETURN("Could not resize swapchain buffers", false); // Create the texture object for the swapchain - return D3D11_INTERNAL_InitializeSwapchainTexture( + bool result = D3D11_INTERNAL_InitializeSwapchainTexture( renderer, windowData->swapchain, windowData->swapchainFormat, (windowData->swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : windowData->swapchainFormat, &windowData->texture); + + windowData->textureContainer.header.info.width = w; + windowData->textureContainer.header.info.height = h; + windowData->needsSwapchainRecreate = !result; + return result; } static bool D3D11_SupportsSwapchainComposition( @@ -5350,14 +5374,13 @@ static bool D3D11_ClaimWindow( D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(window); if (windowData == NULL) { - windowData = (D3D11WindowData *)SDL_malloc(sizeof(D3D11WindowData)); + windowData = (D3D11WindowData *)SDL_calloc(1, sizeof(D3D11WindowData)); windowData->window = window; if (D3D11_INTERNAL_CreateSwapchain(renderer, windowData, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC)) { SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); SDL_LockMutex(renderer->windowLock); - if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity) { renderer->claimedWindowCapacity *= 2; renderer->claimedWindows = SDL_realloc( @@ -5366,9 +5389,10 @@ static bool D3D11_ClaimWindow( } renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; - SDL_UnlockMutex(renderer->windowLock); + SDL_AddEventWatch(D3D11_INTERNAL_OnWindowResize, window); + return true; } else { SDL_free(windowData); @@ -5439,6 +5463,7 @@ static void D3D11_ReleaseWindow( SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); + SDL_RemoveEventWatch(D3D11_INTERNAL_OnWindowResize, window); } static bool D3D11_AcquireSwapchainTexture( @@ -5449,8 +5474,6 @@ static bool D3D11_AcquireSwapchainTexture( D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer; D3D11Renderer *renderer = (D3D11Renderer *)d3d11CommandBuffer->renderer; D3D11WindowData *windowData; - DXGI_SWAP_CHAIN_DESC swapchainDesc; - int windowW, windowH; HRESULT res; *swapchainTexture = NULL; @@ -5460,16 +5483,8 @@ static bool D3D11_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false) } - // Check for window size changes and resize the swapchain if needed. - IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc); - SDL_GetWindowSize(window, &windowW, &windowH); - - if ((UINT)windowW != swapchainDesc.BufferDesc.Width || (UINT)windowH != swapchainDesc.BufferDesc.Height) { - if (!D3D11_INTERNAL_ResizeSwapchain( - renderer, - windowData, - windowW, - windowH)) { + if (windowData->needsSwapchainRecreate) { + if (!D3D11_INTERNAL_ResizeSwapchain(renderer, windowData)) { return false; } } @@ -5511,10 +5526,6 @@ static bool D3D11_AcquireSwapchainTexture( (void **)&windowData->texture.handle); CHECK_D3D11_ERROR_AND_RETURN("Could not acquire swapchain!", false); - // Update the texture container dimensions - windowData->textureContainer.header.info.width = windowW; - windowData->textureContainer.header.info.height = windowH; - // Set up presentation if (d3d11CommandBuffer->windowDataCount == d3d11CommandBuffer->windowDataCapacity) { d3d11CommandBuffer->windowDataCapacity += 1; diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 37cedb86a8e65..20a6367ee48f4 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -544,7 +544,6 @@ typedef struct D3D12WindowData SDL_Window *window; #if (defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) D3D12XBOX_FRAME_PIPELINE_TOKEN frameToken; - Uint32 swapchainWidth, swapchainHeight; #else IDXGISwapChain3 *swapchain; #endif @@ -555,6 +554,7 @@ typedef struct D3D12WindowData D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT]; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; + bool needsSwapchainRecreate; } D3D12WindowData; typedef struct D3D12PresentData @@ -5973,6 +5973,18 @@ static D3D12WindowData *D3D12_INTERNAL_FetchWindowData( return (D3D12WindowData *)SDL_GetPointerProperty(properties, WINDOW_PROPERTY_DATA, NULL); } +static bool D3D12_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) +{ + SDL_Window *w = (SDL_Window *)userdata; + D3D12WindowData *data; + if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) { + data = D3D12_INTERNAL_FetchWindowData(w); + data->needsSwapchainRecreate = true; + } + + return true; +} + static bool D3D12_SupportsSwapchainComposition( SDL_GPURenderer *driverData, SDL_Window *window, @@ -6063,7 +6075,8 @@ static bool D3D12_INTERNAL_CreateSwapchain( D3D12Texture *texture; // Get the swapchain size - SDL_GetWindowSize(windowData->window, &width, &height); + SDL_SyncWindow(windowData->window); + SDL_GetWindowSizeInPixels(windowData->window, &width, &height); // Create the swapchain textures SDL_zero(createInfo); @@ -6091,8 +6104,6 @@ static bool D3D12_INTERNAL_CreateSwapchain( windowData->swapchainComposition = swapchain_composition; windowData->swapchainColorSpace = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709; windowData->frameCounter = 0; - windowData->swapchainWidth = width; - windowData->swapchainHeight = height; // Precache blit pipelines for the swapchain format for (Uint32 i = 0; i < 5; i += 1) { @@ -6126,35 +6137,31 @@ static void D3D12_INTERNAL_DestroySwapchain( } } -static bool D3D12_INTERNAL_ResizeSwapchainIfNeeded( +static bool D3D12_INTERNAL_ResizeSwapchain( D3D12Renderer *renderer, D3D12WindowData *windowData) { - int w, h; - SDL_GetWindowSize(windowData->window, &w, &h); - - if (w != windowData->swapchainWidth || h != windowData->swapchainHeight) { - // Wait so we don't release in-flight views - D3D12_Wait((SDL_GPURenderer *)renderer); - - // Present a black screen - renderer->commandQueue->PresentX(0, NULL, NULL); + // Wait so we don't release in-flight views + D3D12_Wait((SDL_GPURenderer *)renderer); - // Clean up the previous swapchain textures - for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { - D3D12_INTERNAL_DestroyTexture( - renderer, - windowData->textureContainers[i].activeTexture); - } + // Present a black screen + renderer->commandQueue->PresentX(0, NULL, NULL); - // Create a new swapchain - D3D12_INTERNAL_CreateSwapchain( + // Clean up the previous swapchain textures + for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { + D3D12_INTERNAL_DestroyTexture( renderer, - windowData, - windowData->swapchainComposition, - windowData->present_mode); + windowData->textureContainers[i].activeTexture); } + // Create a new swapchain + D3D12_INTERNAL_CreateSwapchain( + renderer, + windowData, + windowData->swapchainComposition, + windowData->present_mode); + + windowData->needsSwapchainRecreate = false; return true; } #else @@ -6273,58 +6280,58 @@ static bool D3D12_INTERNAL_InitializeSwapchainTexture( return true; } -static bool D3D12_INTERNAL_ResizeSwapchainIfNeeded( +static bool D3D12_INTERNAL_ResizeSwapchain( D3D12Renderer *renderer, D3D12WindowData *windowData) { - DXGI_SWAP_CHAIN_DESC swapchainDesc; - int w, h; + // Wait so we don't release in-flight views + D3D12_Wait((SDL_GPURenderer *)renderer); - IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc); - SDL_GetWindowSize(windowData->window, &w, &h); + // Release views and clean up + for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { + D3D12_INTERNAL_ReleaseCpuDescriptorHandle( + renderer, + &windowData->textureContainers[i].activeTexture->srvHandle); + D3D12_INTERNAL_ReleaseCpuDescriptorHandle( + renderer, + &windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles[0]); - if ((UINT)w != swapchainDesc.BufferDesc.Width || (UINT)h != swapchainDesc.BufferDesc.Height) { - // Wait so we don't release in-flight views - D3D12_Wait((SDL_GPURenderer *)renderer); + SDL_free(windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles); + SDL_free(windowData->textureContainers[i].activeTexture->subresources); + SDL_free(windowData->textureContainers[i].activeTexture); + SDL_free(windowData->textureContainers[i].textures); + } - // Release views and clean up - for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { - D3D12_INTERNAL_ReleaseCpuDescriptorHandle( - renderer, - &windowData->textureContainers[i].activeTexture->srvHandle); - D3D12_INTERNAL_ReleaseCpuDescriptorHandle( + int w, h; + SDL_SyncWindow(windowData->window); + SDL_GetWindowSizeInPixels( + windowData->window, + &w, + &h); + + // Resize the swapchain + HRESULT res = IDXGISwapChain_ResizeBuffers( + windowData->swapchain, + 0, // Keep buffer count the same + w, + h, + DXGI_FORMAT_UNKNOWN, // Keep the old format + renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0); + CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain buffers", false) + + // Create texture object for the swapchain + for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { + if (!D3D12_INTERNAL_InitializeSwapchainTexture( renderer, - &windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles[0]); - - SDL_free(windowData->textureContainers[i].activeTexture->subresources[0].rtvHandles); - SDL_free(windowData->textureContainers[i].activeTexture->subresources); - SDL_free(windowData->textureContainers[i].activeTexture); - SDL_free(windowData->textureContainers[i].textures); - } - - // Resize the swapchain - HRESULT res = IDXGISwapChain_ResizeBuffers( - windowData->swapchain, - 0, // Keep buffer count the same - w, - h, - DXGI_FORMAT_UNKNOWN, // Keep the old format - renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0); - CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain buffers", false) - - // Create texture object for the swapchain - for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { - if (!D3D12_INTERNAL_InitializeSwapchainTexture( - renderer, - windowData->swapchain, - windowData->swapchainComposition, - i, - &windowData->textureContainers[i])) { - return false; - } + windowData->swapchain, + windowData->swapchainComposition, + i, + &windowData->textureContainers[i])) { + return false; } } + windowData->needsSwapchainRecreate = false; return true; } @@ -6358,7 +6365,6 @@ static bool D3D12_INTERNAL_CreateSwapchain( SDL_GPUPresentMode presentMode) { HWND dxgiHandle; - int width, height; DXGI_SWAP_CHAIN_DESC1 swapchainDesc; DXGI_SWAP_CHAIN_FULLSCREEN_DESC fullscreenDesc; DXGI_FORMAT swapchainFormat; @@ -6374,9 +6380,6 @@ static bool D3D12_INTERNAL_CreateSwapchain( dxgiHandle = (HWND)windowData->window; #endif - // Get the window size - SDL_GetWindowSize(windowData->window, &width, &height); - swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition]; // Initialize the swapchain buffer descriptor @@ -6529,7 +6532,6 @@ static bool D3D12_ClaimWindow( SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); SDL_LockMutex(renderer->windowLock); - if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity) { renderer->claimedWindowCapacity *= 2; renderer->claimedWindows = (D3D12WindowData **)SDL_realloc( @@ -6538,9 +6540,10 @@ static bool D3D12_ClaimWindow( } renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; - SDL_UnlockMutex(renderer->windowLock); + SDL_AddEventWatch(D3D12_INTERNAL_OnWindowResize, window); + return true; } else { SDL_free(windowData); @@ -6589,6 +6592,7 @@ static void D3D12_ReleaseWindow( SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); + SDL_RemoveEventWatch(D3D12_INTERNAL_OnWindowResize, window); } static bool D3D12_SetSwapchainParameters( @@ -6918,10 +6922,11 @@ static bool D3D12_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire swapchain texture from an unclaimed window!", false) } - res = D3D12_INTERNAL_ResizeSwapchainIfNeeded( - renderer, - windowData); - CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain", false); + if (windowData->needsSwapchainRecreate) { + if (!D3D12_INTERNAL_ResizeSwapchain(renderer, windowData)) { + return false; + } + } if (windowData->inFlightFences[windowData->frameCounter] != NULL) { if (windowData->present_mode == SDL_GPU_PRESENTMODE_VSYNC) { @@ -6932,7 +6937,7 @@ static bool D3D12_AcquireSwapchainTexture( &windowData->inFlightFences[windowData->frameCounter], 1)) { return false; - } + } } else { if (!D3D12_QueryFence( (SDL_GPURenderer *)renderer, diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 84c073657aca9..280b2bacca9f3 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -1159,6 +1159,7 @@ struct VulkanRenderer SDL_Mutex *acquireUniformBufferLock; SDL_Mutex *renderPassFetchLock; SDL_Mutex *framebufferFetchLock; + SDL_Mutex *windowLock; Uint8 defragInProgress; @@ -4493,35 +4494,6 @@ static bool VULKAN_INTERNAL_CreateSwapchain( &drawableWidth, &drawableHeight); - if (drawableWidth < (Sint32)swapchainSupportDetails.capabilities.minImageExtent.width || - drawableWidth > (Sint32)swapchainSupportDetails.capabilities.maxImageExtent.width || - drawableHeight < (Sint32)swapchainSupportDetails.capabilities.minImageExtent.height || - drawableHeight > (Sint32)swapchainSupportDetails.capabilities.maxImageExtent.height) { - if (swapchainSupportDetails.capabilities.currentExtent.width != SDL_MAX_UINT32) { - drawableWidth = VULKAN_INTERNAL_clamp( - drawableWidth, - (Sint32)swapchainSupportDetails.capabilities.minImageExtent.width, - (Sint32)swapchainSupportDetails.capabilities.maxImageExtent.width); - drawableHeight = VULKAN_INTERNAL_clamp( - drawableHeight, - (Sint32)swapchainSupportDetails.capabilities.minImageExtent.height, - (Sint32)swapchainSupportDetails.capabilities.maxImageExtent.height); - } else { - renderer->vkDestroySurfaceKHR( - renderer->instance, - swapchainData->surface, - NULL); - if (swapchainSupportDetails.formatsLength > 0) { - SDL_free(swapchainSupportDetails.formats); - } - if (swapchainSupportDetails.presentModesLength > 0) { - SDL_free(swapchainSupportDetails.presentModes); - } - SDL_free(swapchainData); - SET_STRING_ERROR_AND_RETURN("No fallback swapchain size available!", false); - } - } - swapchainData->imageCount = MAX_FRAMES_IN_FLIGHT; if (swapchainSupportDetails.capabilities.maxImageCount > 0 && @@ -4833,6 +4805,7 @@ static void VULKAN_DestroyDevice( SDL_DestroyMutex(renderer->acquireUniformBufferLock); SDL_DestroyMutex(renderer->renderPassFetchLock); SDL_DestroyMutex(renderer->framebufferFetchLock); + SDL_DestroyMutex(renderer->windowLock); renderer->vkDestroyDevice(renderer->logicalDevice, NULL); renderer->vkDestroyInstance(renderer->instance, NULL); @@ -9356,7 +9329,7 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) { SDL_Window *w = (SDL_Window *)userdata; WindowData *data; - if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { + if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) { data = VULKAN_INTERNAL_FetchWindowData(w); data->needsSwapchainRecreate = true; } @@ -9460,6 +9433,7 @@ static bool VULKAN_ClaimWindow( if (VULKAN_INTERNAL_CreateSwapchain(renderer, windowData)) { SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); + SDL_LockMutex(renderer->windowLock); if (renderer->claimedWindowCount >= renderer->claimedWindowCapacity) { renderer->claimedWindowCapacity *= 2; renderer->claimedWindows = SDL_realloc( @@ -9469,6 +9443,7 @@ static bool VULKAN_ClaimWindow( renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; + SDL_UnlockMutex(renderer->windowLock); SDL_AddEventWatch(VULKAN_INTERNAL_OnWindowResize, window); @@ -9511,6 +9486,7 @@ static void VULKAN_ReleaseWindow( windowData); } + SDL_LockMutex(renderer->windowLock); for (i = 0; i < renderer->claimedWindowCount; i += 1) { if (renderer->claimedWindows[i]->window == window) { renderer->claimedWindows[i] = renderer->claimedWindows[renderer->claimedWindowCount - 1]; @@ -9518,6 +9494,7 @@ static void VULKAN_ReleaseWindow( break; } } + SDL_UnlockMutex(renderer->windowLock); SDL_free(windowData); @@ -9619,7 +9596,10 @@ static bool VULKAN_AcquireSwapchainTexture( // If window data marked as needing swapchain recreate, try to recreate if (windowData->needsSwapchainRecreate) { - VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData); + if (!VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData)) { + return false; + } + swapchainData = windowData->swapchainData; if (swapchainData == NULL) { @@ -11340,6 +11320,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S renderer->acquireUniformBufferLock = SDL_CreateMutex(); renderer->renderPassFetchLock = SDL_CreateMutex(); renderer->framebufferFetchLock = SDL_CreateMutex(); + renderer->windowLock = SDL_CreateMutex(); /* * Create submitted command buffer list