From 61755e1e0182d995b34147c5e01b6d28bee5adda Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 28 Sep 2024 13:21:17 -0700 Subject: [PATCH 1/6] GPU: recreate swapchain on window pixel size change event --- src/gpu/d3d11/SDL_gpu_d3d11.c | 65 ++++++++----- src/gpu/d3d12/SDL_gpu_d3d12.c | 161 +++++++++++++++++--------------- src/gpu/vulkan/SDL_gpu_vulkan.c | 29 ------ 3 files changed, 125 insertions(+), 130 deletions(-) diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 90402ede29203..77677b14ab09c 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) { + 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,7 +5374,7 @@ 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)) { @@ -5367,6 +5391,8 @@ static bool D3D11_ClaimWindow( renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; + SDL_AddEventWatch(D3D11_INTERNAL_OnWindowResize, window); + SDL_UnlockMutex(renderer->windowLock); return true; @@ -5439,6 +5465,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 +5476,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 +5485,10 @@ 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 (windowData->needsSwapchainRecreate) { if (!D3D11_INTERNAL_ResizeSwapchain( renderer, - windowData, - windowW, - windowH)) { + windowData)) { return false; } } @@ -5511,10 +5530,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..96167f9c13393 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) { + 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 @@ -6539,6 +6542,8 @@ static bool D3D12_ClaimWindow( renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; + SDL_AddEventWatch(D3D12_INTERNAL_OnWindowResize, window); + SDL_UnlockMutex(renderer->windowLock); return true; @@ -6589,6 +6594,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 +6924,13 @@ 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 +6941,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..a7745b465a796 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -4493,35 +4493,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 && From d028fdb02d2f3e60e24e38886f3515f953b6586d Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 28 Sep 2024 16:54:24 -0700 Subject: [PATCH 2/6] thread safety fixes --- src/gpu/d3d11/SDL_gpu_d3d11.c | 17 +++++++++++------ src/gpu/d3d12/SDL_gpu_d3d12.c | 17 +++++++++++------ src/gpu/vulkan/SDL_gpu_vulkan.c | 21 ++++++++++++++++++++- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 77677b14ab09c..7f8faacb64d0d 100644 --- a/src/gpu/d3d11/SDL_gpu_d3d11.c +++ b/src/gpu/d3d11/SDL_gpu_d3d11.c @@ -483,6 +483,7 @@ typedef struct D3D11WindowData SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; Uint32 frameCounter; bool needsSwapchainRecreate; + SDL_Mutex *lock; } D3D11WindowData; typedef struct D3D11Shader @@ -5028,7 +5029,9 @@ static bool D3D11_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) D3D11WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = D3D11_INTERNAL_FetchWindowData(w); + SDL_LockMutex(data->lock); data->needsSwapchainRecreate = true; + SDL_UnlockMutex(data->lock); } return true; @@ -5376,12 +5379,12 @@ static bool D3D11_ClaimWindow( if (windowData == NULL) { windowData = (D3D11WindowData *)SDL_calloc(1, sizeof(D3D11WindowData)); windowData->window = window; + windowData->lock = SDL_CreateMutex(); 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( @@ -5390,11 +5393,10 @@ static bool D3D11_ClaimWindow( } renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; + SDL_UnlockMutex(renderer->windowLock); SDL_AddEventWatch(D3D11_INTERNAL_OnWindowResize, window); - SDL_UnlockMutex(renderer->windowLock); - return true; } else { SDL_free(windowData); @@ -5462,6 +5464,7 @@ static void D3D11_ReleaseWindow( } SDL_UnlockMutex(renderer->windowLock); + SDL_DestroyMutex(windowData->lock); SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); @@ -5486,9 +5489,11 @@ static bool D3D11_AcquireSwapchainTexture( } if (windowData->needsSwapchainRecreate) { - if (!D3D11_INTERNAL_ResizeSwapchain( - renderer, - windowData)) { + SDL_LockMutex(windowData->lock); + bool resizeSuccess = D3D11_INTERNAL_ResizeSwapchain(renderer, windowData); + SDL_UnlockMutex(windowData->lock); + + if (!resizeSuccess) { return false; } } diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 96167f9c13393..eb9fe25c2a1b4 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -555,6 +555,7 @@ typedef struct D3D12WindowData D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT]; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; bool needsSwapchainRecreate; + SDL_Mutex *lock; } D3D12WindowData; typedef struct D3D12PresentData @@ -5979,7 +5980,9 @@ static bool D3D12_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) D3D12WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = D3D12_INTERNAL_FetchWindowData(w); + SDL_LockMutex(data->lock); data->needsSwapchainRecreate = true; + SDL_UnlockMutex(data->lock); } return true; @@ -6527,12 +6530,12 @@ static bool D3D12_ClaimWindow( return false; } windowData->window = window; + windowData->lock = SDL_CreateMutex(); if (D3D12_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 = (D3D12WindowData **)SDL_realloc( @@ -6541,11 +6544,10 @@ static bool D3D12_ClaimWindow( } renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; + SDL_UnlockMutex(renderer->windowLock); SDL_AddEventWatch(D3D12_INTERNAL_OnWindowResize, window); - SDL_UnlockMutex(renderer->windowLock); - return true; } else { SDL_free(windowData); @@ -6592,6 +6594,7 @@ static void D3D12_ReleaseWindow( } SDL_UnlockMutex(renderer->windowLock); + SDL_DestroyMutex(windowData->lock); SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); SDL_RemoveEventWatch(D3D12_INTERNAL_OnWindowResize, window); @@ -6925,9 +6928,11 @@ static bool D3D12_AcquireSwapchainTexture( } if (windowData->needsSwapchainRecreate) { - if (!D3D12_INTERNAL_ResizeSwapchain( - renderer, - windowData)) { + SDL_LockMutex(windowData->lock); + bool resizeSuccess = D3D12_INTERNAL_ResizeSwapchain(renderer, windowData); + SDL_UnlockMutex(windowData->lock); + + if (!resizeSuccess) { return false; } } diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index a7745b465a796..5f0872048e148 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -697,6 +697,7 @@ typedef struct WindowData SDL_GPUPresentMode presentMode; VulkanSwapchainData *swapchainData; bool needsSwapchainRecreate; + SDL_Mutex *lock; } WindowData; typedef struct SwapchainSupportDetails @@ -1159,6 +1160,7 @@ struct VulkanRenderer SDL_Mutex *acquireUniformBufferLock; SDL_Mutex *renderPassFetchLock; SDL_Mutex *framebufferFetchLock; + SDL_Mutex *windowLock; Uint8 defragInProgress; @@ -4804,6 +4806,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); @@ -9329,7 +9332,9 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = VULKAN_INTERNAL_FetchWindowData(w); + SDL_LockMutex(data->lock); data->needsSwapchainRecreate = true; + SDL_UnlockMutex(data->lock); } return true; @@ -9427,10 +9432,12 @@ static bool VULKAN_ClaimWindow( windowData->window = window; windowData->presentMode = SDL_GPU_PRESENTMODE_VSYNC; windowData->swapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR; + windowData->lock = SDL_CreateMutex(); 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( @@ -9440,6 +9447,7 @@ static bool VULKAN_ClaimWindow( renderer->claimedWindows[renderer->claimedWindowCount] = windowData; renderer->claimedWindowCount += 1; + SDL_UnlockMutex(renderer->windowLock); SDL_AddEventWatch(VULKAN_INTERNAL_OnWindowResize, window); @@ -9482,6 +9490,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]; @@ -9489,7 +9498,9 @@ static void VULKAN_ReleaseWindow( break; } } + SDL_UnlockMutex(renderer->windowLock); + SDL_DestroyMutex(windowData->lock); SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); @@ -9590,7 +9601,14 @@ static bool VULKAN_AcquireSwapchainTexture( // If window data marked as needing swapchain recreate, try to recreate if (windowData->needsSwapchainRecreate) { - VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData); + SDL_LockMutex(windowData->lock); + bool recreateSuccess = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData); + SDL_UnlockMutex(windowData->lock); + + if (!recreateSuccess) { + return false; + } + swapchainData = windowData->swapchainData; if (swapchainData == NULL) { @@ -11311,6 +11329,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 From 7da11b6507e61105565ae8acdda5bce8ebf7e0c8 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 28 Sep 2024 17:14:15 -0700 Subject: [PATCH 3/6] replace window data mutex with atomic int --- src/gpu/d3d11/SDL_gpu_d3d11.c | 19 +++++-------------- src/gpu/d3d12/SDL_gpu_d3d12.c | 19 +++++-------------- src/gpu/vulkan/SDL_gpu_vulkan.c | 19 +++++-------------- 3 files changed, 15 insertions(+), 42 deletions(-) diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 7f8faacb64d0d..98fc33e82691a 100644 --- a/src/gpu/d3d11/SDL_gpu_d3d11.c +++ b/src/gpu/d3d11/SDL_gpu_d3d11.c @@ -482,8 +482,7 @@ typedef struct D3D11WindowData DXGI_COLOR_SPACE_TYPE swapchainColorSpace; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; Uint32 frameCounter; - bool needsSwapchainRecreate; - SDL_Mutex *lock; + SDL_AtomicInt needsSwapchainRecreate; } D3D11WindowData; typedef struct D3D11Shader @@ -5029,9 +5028,7 @@ static bool D3D11_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) D3D11WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = D3D11_INTERNAL_FetchWindowData(w); - SDL_LockMutex(data->lock); - data->needsSwapchainRecreate = true; - SDL_UnlockMutex(data->lock); + SDL_SetAtomicInt(&data->needsSwapchainRecreate, true); } return true; @@ -5291,7 +5288,7 @@ static bool D3D11_INTERNAL_ResizeSwapchain( windowData->textureContainer.header.info.width = w; windowData->textureContainer.header.info.height = h; - windowData->needsSwapchainRecreate = !result; + SDL_SetAtomicInt(&windowData->needsSwapchainRecreate, !result); return result; } @@ -5379,7 +5376,6 @@ static bool D3D11_ClaimWindow( if (windowData == NULL) { windowData = (D3D11WindowData *)SDL_calloc(1, sizeof(D3D11WindowData)); windowData->window = window; - windowData->lock = SDL_CreateMutex(); if (D3D11_INTERNAL_CreateSwapchain(renderer, windowData, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC)) { SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); @@ -5464,7 +5460,6 @@ static void D3D11_ReleaseWindow( } SDL_UnlockMutex(renderer->windowLock); - SDL_DestroyMutex(windowData->lock); SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); @@ -5488,12 +5483,8 @@ static bool D3D11_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false) } - if (windowData->needsSwapchainRecreate) { - SDL_LockMutex(windowData->lock); - bool resizeSuccess = D3D11_INTERNAL_ResizeSwapchain(renderer, windowData); - SDL_UnlockMutex(windowData->lock); - - if (!resizeSuccess) { + if (SDL_GetAtomicInt(&windowData->needsSwapchainRecreate)) { + if (!D3D11_INTERNAL_ResizeSwapchain(renderer, windowData)) { return false; } } diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index eb9fe25c2a1b4..b41dcb4d91261 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -554,8 +554,7 @@ typedef struct D3D12WindowData D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT]; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; - bool needsSwapchainRecreate; - SDL_Mutex *lock; + SDL_AtomicInt needsSwapchainRecreate; } D3D12WindowData; typedef struct D3D12PresentData @@ -5980,9 +5979,7 @@ static bool D3D12_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) D3D12WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = D3D12_INTERNAL_FetchWindowData(w); - SDL_LockMutex(data->lock); - data->needsSwapchainRecreate = true; - SDL_UnlockMutex(data->lock); + SDL_SetAtomicInt(&data->needsSwapchainRecreate, true); } return true; @@ -6334,7 +6331,7 @@ static bool D3D12_INTERNAL_ResizeSwapchain( } } - windowData->needsSwapchainRecreate = false; + SDL_SetAtomicInt(&windowData->needsSwapchainRecreate, false); return true; } @@ -6530,7 +6527,6 @@ static bool D3D12_ClaimWindow( return false; } windowData->window = window; - windowData->lock = SDL_CreateMutex(); if (D3D12_INTERNAL_CreateSwapchain(renderer, windowData, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC)) { SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); @@ -6594,7 +6590,6 @@ static void D3D12_ReleaseWindow( } SDL_UnlockMutex(renderer->windowLock); - SDL_DestroyMutex(windowData->lock); SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); SDL_RemoveEventWatch(D3D12_INTERNAL_OnWindowResize, window); @@ -6927,12 +6922,8 @@ static bool D3D12_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire swapchain texture from an unclaimed window!", false) } - if (windowData->needsSwapchainRecreate) { - SDL_LockMutex(windowData->lock); - bool resizeSuccess = D3D12_INTERNAL_ResizeSwapchain(renderer, windowData); - SDL_UnlockMutex(windowData->lock); - - if (!resizeSuccess) { + if (SDL_GetAtomicInt(&windowData->needsSwapchainRecreate)) { + if (!D3D12_INTERNAL_ResizeSwapchain(renderer, windowData)) { return false; } } diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 5f0872048e148..344a8204295b6 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -696,8 +696,7 @@ typedef struct WindowData SDL_GPUSwapchainComposition swapchainComposition; SDL_GPUPresentMode presentMode; VulkanSwapchainData *swapchainData; - bool needsSwapchainRecreate; - SDL_Mutex *lock; + SDL_AtomicInt needsSwapchainRecreate; } WindowData; typedef struct SwapchainSupportDetails @@ -4672,7 +4671,7 @@ static bool VULKAN_INTERNAL_CreateSwapchain( } windowData->swapchainData = swapchainData; - windowData->needsSwapchainRecreate = false; + SDL_SetAtomicInt(&windowData->needsSwapchainRecreate, false); return true; } @@ -9332,9 +9331,7 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = VULKAN_INTERNAL_FetchWindowData(w); - SDL_LockMutex(data->lock); - data->needsSwapchainRecreate = true; - SDL_UnlockMutex(data->lock); + SDL_SetAtomicInt(&data->needsSwapchainRecreate, true); } return true; @@ -9432,7 +9429,6 @@ static bool VULKAN_ClaimWindow( windowData->window = window; windowData->presentMode = SDL_GPU_PRESENTMODE_VSYNC; windowData->swapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR; - windowData->lock = SDL_CreateMutex(); if (VULKAN_INTERNAL_CreateSwapchain(renderer, windowData)) { SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); @@ -9500,7 +9496,6 @@ static void VULKAN_ReleaseWindow( } SDL_UnlockMutex(renderer->windowLock); - SDL_DestroyMutex(windowData->lock); SDL_free(windowData); SDL_ClearProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA); @@ -9600,12 +9595,8 @@ static bool VULKAN_AcquireSwapchainTexture( } // If window data marked as needing swapchain recreate, try to recreate - if (windowData->needsSwapchainRecreate) { - SDL_LockMutex(windowData->lock); - bool recreateSuccess = VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData); - SDL_UnlockMutex(windowData->lock); - - if (!recreateSuccess) { + if (SDL_GetAtomicInt(&windowData->needsSwapchainRecreate)) { + if (!VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData)) { return false; } From c63dc6d3bdf9fd943dbffa08dce80cdc53b083f5 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 28 Sep 2024 17:26:50 -0700 Subject: [PATCH 4/6] never mind, we don't need thread safety for window data --- src/gpu/d3d11/SDL_gpu_d3d11.c | 8 ++++---- src/gpu/d3d12/SDL_gpu_d3d12.c | 8 ++++---- src/gpu/vulkan/SDL_gpu_vulkan.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 98fc33e82691a..52d26a9f93d73 100644 --- a/src/gpu/d3d11/SDL_gpu_d3d11.c +++ b/src/gpu/d3d11/SDL_gpu_d3d11.c @@ -482,7 +482,7 @@ typedef struct D3D11WindowData DXGI_COLOR_SPACE_TYPE swapchainColorSpace; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; Uint32 frameCounter; - SDL_AtomicInt needsSwapchainRecreate; + bool needsSwapchainRecreate; } D3D11WindowData; typedef struct D3D11Shader @@ -5028,7 +5028,7 @@ static bool D3D11_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) D3D11WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = D3D11_INTERNAL_FetchWindowData(w); - SDL_SetAtomicInt(&data->needsSwapchainRecreate, true); + data->needsSwapchainRecreate = true; } return true; @@ -5288,7 +5288,7 @@ static bool D3D11_INTERNAL_ResizeSwapchain( windowData->textureContainer.header.info.width = w; windowData->textureContainer.header.info.height = h; - SDL_SetAtomicInt(&windowData->needsSwapchainRecreate, !result); + windowData->needsSwapchainRecreate = !result; return result; } @@ -5483,7 +5483,7 @@ static bool D3D11_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire a swapchain texture from an unclaimed window!", false) } - if (SDL_GetAtomicInt(&windowData->needsSwapchainRecreate)) { + if (windowData->needsSwapchainRecreate) { if (!D3D11_INTERNAL_ResizeSwapchain(renderer, windowData)) { return false; } diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index b41dcb4d91261..f18c8797bf054 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -554,7 +554,7 @@ typedef struct D3D12WindowData D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT]; SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT]; - SDL_AtomicInt needsSwapchainRecreate; + bool needsSwapchainRecreate; } D3D12WindowData; typedef struct D3D12PresentData @@ -5979,7 +5979,7 @@ static bool D3D12_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) D3D12WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = D3D12_INTERNAL_FetchWindowData(w); - SDL_SetAtomicInt(&data->needsSwapchainRecreate, true); + data->needsSwapchainRecreate = true; } return true; @@ -6331,7 +6331,7 @@ static bool D3D12_INTERNAL_ResizeSwapchain( } } - SDL_SetAtomicInt(&windowData->needsSwapchainRecreate, false); + windowData->needsSwapchainRecreate = false; return true; } @@ -6922,7 +6922,7 @@ static bool D3D12_AcquireSwapchainTexture( SET_STRING_ERROR_AND_RETURN("Cannot acquire swapchain texture from an unclaimed window!", false) } - if (SDL_GetAtomicInt(&windowData->needsSwapchainRecreate)) { + if (windowData->needsSwapchainRecreate) { if (!D3D12_INTERNAL_ResizeSwapchain(renderer, windowData)) { return false; } diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index 344a8204295b6..aeb88d581e62f 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -696,7 +696,7 @@ typedef struct WindowData SDL_GPUSwapchainComposition swapchainComposition; SDL_GPUPresentMode presentMode; VulkanSwapchainData *swapchainData; - SDL_AtomicInt needsSwapchainRecreate; + bool needsSwapchainRecreate; } WindowData; typedef struct SwapchainSupportDetails @@ -4671,7 +4671,7 @@ static bool VULKAN_INTERNAL_CreateSwapchain( } windowData->swapchainData = swapchainData; - SDL_SetAtomicInt(&windowData->needsSwapchainRecreate, false); + windowData->needsSwapchainRecreate = false; return true; } @@ -9331,7 +9331,7 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e) WindowData *data; if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) { data = VULKAN_INTERNAL_FetchWindowData(w); - SDL_SetAtomicInt(&data->needsSwapchainRecreate, true); + data->needsSwapchainRecreate = true; } return true; @@ -9595,7 +9595,7 @@ static bool VULKAN_AcquireSwapchainTexture( } // If window data marked as needing swapchain recreate, try to recreate - if (SDL_GetAtomicInt(&windowData->needsSwapchainRecreate)) { + if (windowData->needsSwapchainRecreate) { if (!VULKAN_INTERNAL_RecreateSwapchain(renderer, windowData)) { return false; } From 919a6e555cd2367e6e77a61cfd911794bf654510 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 28 Sep 2024 17:30:17 -0700 Subject: [PATCH 5/6] another thread note in header --- include/SDL3/SDL_gpu.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 5ebf57c8e522521c5124cf2998cdb6bf4a839869 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sat, 28 Sep 2024 17:44:24 -0700 Subject: [PATCH 6/6] Check that the window in the event is the relevant window --- src/gpu/d3d11/SDL_gpu_d3d11.c | 2 +- src/gpu/d3d12/SDL_gpu_d3d12.c | 2 +- src/gpu/vulkan/SDL_gpu_vulkan.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c index 52d26a9f93d73..a7472fc136c80 100644 --- a/src/gpu/d3d11/SDL_gpu_d3d11.c +++ b/src/gpu/d3d11/SDL_gpu_d3d11.c @@ -5026,7 +5026,7 @@ 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) { + if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) { data = D3D11_INTERNAL_FetchWindowData(w); data->needsSwapchainRecreate = true; } diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index f18c8797bf054..20a6367ee48f4 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -5977,7 +5977,7 @@ 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) { + if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) { data = D3D12_INTERNAL_FetchWindowData(w); data->needsSwapchainRecreate = true; } diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index aeb88d581e62f..280b2bacca9f3 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -9329,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; }