mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-05 19:08:12 +00:00
GPU: recreate swapchain on window pixel size change event (#10985)
This commit is contained in:
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
// Wait so we don't release in-flight views
|
||||
D3D12_Wait((SDL_GPURenderer *)renderer);
|
||||
|
||||
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);
|
||||
|
||||
// Present a black screen
|
||||
renderer->commandQueue->PresentX(0, NULL, NULL);
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
// Wait so we don't release in-flight views
|
||||
D3D12_Wait((SDL_GPURenderer *)renderer);
|
||||
|
||||
// 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]);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
int w, h;
|
||||
SDL_SyncWindow(windowData->window);
|
||||
SDL_GetWindowSizeInPixels(
|
||||
windowData->window,
|
||||
&w,
|
||||
&h);
|
||||
|
||||
IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc);
|
||||
SDL_GetWindowSize(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)
|
||||
|
||||
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);
|
||||
|
||||
// Release views and clean up
|
||||
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
|
||||
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
|
||||
// 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->srvHandle);
|
||||
D3D12_INTERNAL_ReleaseCpuDescriptorHandle(
|
||||
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,
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user