GPU: Avoid calling SDL_GetWindowSizeInPixels when possible (#11139)

This commit is contained in:
Evan Hemsley
2024-10-09 18:59:07 -07:00
committed by GitHub
parent 4707bb730e
commit da5a1585cd
3 changed files with 65 additions and 52 deletions

View File

@@ -5269,9 +5269,8 @@ static bool D3D11_INTERNAL_CreateSwapchain(
return false; return false;
} }
int w, h; res = IDXGISwapChain_GetDesc(swapchain, &swapchainDesc);
SDL_SyncWindow(windowData->window); CHECK_D3D11_ERROR_AND_RETURN("Failed to get swapchain descriptor!", false);
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
// Initialize dummy container, width/height will be filled out in AcquireSwapchainTexture // Initialize dummy container, width/height will be filled out in AcquireSwapchainTexture
SDL_zerop(&windowData->textureContainer); SDL_zerop(&windowData->textureContainer);
@@ -5288,14 +5287,14 @@ static bool D3D11_INTERNAL_CreateSwapchain(
windowData->textureContainer.header.info.num_levels = 1; windowData->textureContainer.header.info.num_levels = 1;
windowData->textureContainer.header.info.sample_count = SDL_GPU_SAMPLECOUNT_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.usage = SDL_GPU_TEXTUREUSAGE_COLOR_TARGET;
windowData->textureContainer.header.info.width = w; windowData->textureContainer.header.info.width = swapchainDesc.BufferDesc.Width;
windowData->textureContainer.header.info.height = h; windowData->textureContainer.header.info.height = swapchainDesc.BufferDesc.Height;
windowData->texture.container = &windowData->textureContainer; windowData->texture.container = &windowData->textureContainer;
windowData->texture.containerIndex = 0; windowData->texture.containerIndex = 0;
windowData->width = w; windowData->width = swapchainDesc.BufferDesc.Width;
windowData->height = h; windowData->height = swapchainDesc.BufferDesc.Height;
return true; return true;
} }
@@ -5310,16 +5309,12 @@ static bool D3D11_INTERNAL_ResizeSwapchain(
SDL_free(windowData->texture.subresources[0].colorTargetViews); SDL_free(windowData->texture.subresources[0].colorTargetViews);
SDL_free(windowData->texture.subresources); SDL_free(windowData->texture.subresources);
int w, h;
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
// Resize the swapchain // Resize the swapchain
HRESULT res = IDXGISwapChain_ResizeBuffers( HRESULT res = IDXGISwapChain_ResizeBuffers(
windowData->swapchain, windowData->swapchain,
0, // Keep buffer count the same 0, // Keep buffer count the same
w, 0, // Use client window width
h, 0, // Use client window height
DXGI_FORMAT_UNKNOWN, // Keep the old format DXGI_FORMAT_UNKNOWN, // Keep the old format
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0); renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
CHECK_D3D11_ERROR_AND_RETURN("Could not resize swapchain buffers", false); CHECK_D3D11_ERROR_AND_RETURN("Could not resize swapchain buffers", false);
@@ -5332,10 +5327,14 @@ static bool D3D11_INTERNAL_ResizeSwapchain(
(windowData->swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : windowData->swapchainFormat, (windowData->swapchainComposition == SDL_GPU_SWAPCHAINCOMPOSITION_SDR_LINEAR) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : windowData->swapchainFormat,
&windowData->texture); &windowData->texture);
windowData->textureContainer.header.info.width = w; DXGI_SWAP_CHAIN_DESC swapchainDesc;
windowData->textureContainer.header.info.height = h; res = IDXGISwapChain_GetDesc(windowData->swapchain, &swapchainDesc);
windowData->width = w; CHECK_D3D11_ERROR_AND_RETURN("Failed to get swapchain descriptor!", false);
windowData->height = h;
windowData->textureContainer.header.info.width = swapchainDesc.BufferDesc.Width;
windowData->textureContainer.header.info.height = swapchainDesc.BufferDesc.Height;
windowData->width = swapchainDesc.BufferDesc.Width;
windowData->height = swapchainDesc.BufferDesc.Height;
windowData->needsSwapchainRecreate = !result; windowData->needsSwapchainRecreate = !result;
return result; return result;
} }

View File

@@ -6347,19 +6347,12 @@ static bool D3D12_INTERNAL_ResizeSwapchain(
SDL_free(windowData->textureContainers[i].textures); SDL_free(windowData->textureContainers[i].textures);
} }
int w, h;
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(
windowData->window,
&w,
&h);
// Resize the swapchain // Resize the swapchain
HRESULT res = IDXGISwapChain_ResizeBuffers( HRESULT res = IDXGISwapChain_ResizeBuffers(
windowData->swapchain, windowData->swapchain,
0, // Keep buffer count the same 0, // Keep buffer count the same
w, 0, // use client window width
h, 0, // use client window height
DXGI_FORMAT_UNKNOWN, // Keep the old format DXGI_FORMAT_UNKNOWN, // Keep the old format
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0); renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain buffers", false) CHECK_D3D12_ERROR_AND_RETURN("Could not resize swapchain buffers", false)
@@ -6376,8 +6369,12 @@ static bool D3D12_INTERNAL_ResizeSwapchain(
} }
} }
windowData->width = w; DXGI_SWAP_CHAIN_DESC1 swapchainDesc;
windowData->height = h; IDXGISwapChain3_GetDesc1(windowData->swapchain, &swapchainDesc);
CHECK_D3D12_ERROR_AND_RETURN("Failed to retrieve swapchain descriptor!", false)
windowData->width = swapchainDesc.Width;
windowData->height = swapchainDesc.Height;
windowData->needsSwapchainRecreate = false; windowData->needsSwapchainRecreate = false;
return true; return true;
} }
@@ -6429,12 +6426,9 @@ static bool D3D12_INTERNAL_CreateSwapchain(
swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition]; swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition];
int w, h;
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
// Initialize the swapchain buffer descriptor // Initialize the swapchain buffer descriptor
swapchainDesc.Width = 0; swapchainDesc.Width = 0; // use client window width
swapchainDesc.Height = 0; swapchainDesc.Height = 0; // use client window height
swapchainDesc.Format = swapchainFormat; swapchainDesc.Format = swapchainFormat;
swapchainDesc.SampleDesc.Count = 1; swapchainDesc.SampleDesc.Count = 1;
swapchainDesc.SampleDesc.Quality = 0; swapchainDesc.SampleDesc.Quality = 0;
@@ -6521,14 +6515,17 @@ static bool D3D12_INTERNAL_CreateSwapchain(
IDXGIFactory1_Release(pParent); IDXGIFactory1_Release(pParent);
} }
IDXGISwapChain3_GetDesc1(swapchain3, &swapchainDesc);
CHECK_D3D12_ERROR_AND_RETURN("Failed to retrieve swapchain descriptor!", false)
// Initialize the swapchain data // Initialize the swapchain data
windowData->swapchain = swapchain3; windowData->swapchain = swapchain3;
windowData->present_mode = presentMode; windowData->present_mode = presentMode;
windowData->swapchainComposition = swapchainComposition; windowData->swapchainComposition = swapchainComposition;
windowData->swapchainColorSpace = SwapchainCompositionToColorSpace[swapchainComposition]; windowData->swapchainColorSpace = SwapchainCompositionToColorSpace[swapchainComposition];
windowData->frameCounter = 0; windowData->frameCounter = 0;
windowData->width = w; windowData->width = swapchainDesc.Width;
windowData->height = h; windowData->height = swapchainDesc.Height;
// Precache blit pipelines for the swapchain format // Precache blit pipelines for the swapchain format
for (Uint32 i = 0; i < 5; i += 1) { for (Uint32 i = 0; i < 5; i += 1) {

View File

@@ -714,6 +714,8 @@ typedef struct WindowData
SDL_GPUSwapchainComposition swapchainComposition; SDL_GPUSwapchainComposition swapchainComposition;
SDL_GPUPresentMode presentMode; SDL_GPUPresentMode presentMode;
bool needsSwapchainRecreate; bool needsSwapchainRecreate;
Uint32 swapchainCreateWidth;
Uint32 swapchainCreateHeight;
// Window surface // Window surface
VkSurfaceKHR surface; VkSurfaceKHR surface;
@@ -4425,14 +4427,13 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
VkSemaphoreCreateInfo semaphoreCreateInfo; VkSemaphoreCreateInfo semaphoreCreateInfo;
SwapchainSupportDetails swapchainSupportDetails; SwapchainSupportDetails swapchainSupportDetails;
bool hasValidSwapchainComposition, hasValidPresentMode; bool hasValidSwapchainComposition, hasValidPresentMode;
Sint32 drawableWidth, drawableHeight;
Uint32 i; Uint32 i;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_assert(_this && _this->Vulkan_CreateSurface);
windowData->frameCounter = 0; windowData->frameCounter = 0;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
SDL_assert(_this && _this->Vulkan_CreateSurface);
// Each swapchain must have its own surface. // Each swapchain must have its own surface.
if (!_this->Vulkan_CreateSurface( if (!_this->Vulkan_CreateSurface(
_this, _this,
@@ -4535,16 +4536,20 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
return VULKAN_INTERNAL_TRY_AGAIN; return VULKAN_INTERNAL_TRY_AGAIN;
} }
// Sync now to be sure that our swapchain size is correct
SDL_SyncWindow(windowData->window);
SDL_GetWindowSizeInPixels(
windowData->window,
&drawableWidth,
&drawableHeight);
windowData->imageCount = MAX_FRAMES_IN_FLIGHT; windowData->imageCount = MAX_FRAMES_IN_FLIGHT;
windowData->width = drawableWidth;
windowData->height = drawableHeight; #ifdef SDL_PLATFORM_APPLE
windowData->width = swapchainSupportDetails.capabilities.currentExtent.width;
windowData->height = swapchainSupportDetails.capabilities.currentExtent.height;
#else
windowData->width = SDL_clamp(
windowData->swapchainCreateWidth,
swapchainSupportDetails.capabilities.minImageExtent.width,
swapchainSupportDetails.capabilities.maxImageExtent.width);
windowData->height = SDL_clamp(windowData->swapchainCreateHeight,
swapchainSupportDetails.capabilities.minImageExtent.height,
swapchainSupportDetails.capabilities.maxImageExtent.height);
#endif
if (swapchainSupportDetails.capabilities.maxImageCount > 0 && if (swapchainSupportDetails.capabilities.maxImageCount > 0 &&
windowData->imageCount > swapchainSupportDetails.capabilities.maxImageCount) { windowData->imageCount > swapchainSupportDetails.capabilities.maxImageCount) {
@@ -4572,8 +4577,8 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
swapchainCreateInfo.minImageCount = windowData->imageCount; swapchainCreateInfo.minImageCount = windowData->imageCount;
swapchainCreateInfo.imageFormat = windowData->format; swapchainCreateInfo.imageFormat = windowData->format;
swapchainCreateInfo.imageColorSpace = windowData->colorSpace; swapchainCreateInfo.imageColorSpace = windowData->colorSpace;
swapchainCreateInfo.imageExtent.width = drawableWidth; swapchainCreateInfo.imageExtent.width = windowData->width;
swapchainCreateInfo.imageExtent.height = drawableHeight; swapchainCreateInfo.imageExtent.height = windowData->height;
swapchainCreateInfo.imageArrayLayers = 1; swapchainCreateInfo.imageArrayLayers = 1;
swapchainCreateInfo.imageUsage = swapchainCreateInfo.imageUsage =
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
@@ -4647,8 +4652,8 @@ static Uint32 VULKAN_INTERNAL_CreateSwapchain(
// Initialize dummy container // Initialize dummy container
SDL_zero(windowData->textureContainers[i]); SDL_zero(windowData->textureContainers[i]);
windowData->textureContainers[i].canBeCycled = false; windowData->textureContainers[i].canBeCycled = false;
windowData->textureContainers[i].header.info.width = drawableWidth; windowData->textureContainers[i].header.info.width = windowData->width;
windowData->textureContainers[i].header.info.height = drawableHeight; windowData->textureContainers[i].header.info.height = windowData->height;
windowData->textureContainers[i].header.info.layer_count_or_depth = 1; windowData->textureContainers[i].header.info.layer_count_or_depth = 1;
windowData->textureContainers[i].header.info.format = SwapchainCompositionToSDLFormat( windowData->textureContainers[i].header.info.format = SwapchainCompositionToSDLFormat(
windowData->swapchainComposition, windowData->swapchainComposition,
@@ -9411,6 +9416,8 @@ static bool VULKAN_INTERNAL_OnWindowResize(void *userdata, SDL_Event *e)
if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) { if (e->type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED && e->window.windowID == SDL_GetWindowID(w)) {
data = VULKAN_INTERNAL_FetchWindowData(w); data = VULKAN_INTERNAL_FetchWindowData(w);
data->needsSwapchainRecreate = true; data->needsSwapchainRecreate = true;
data->swapchainCreateWidth = e->window.data1;
data->swapchainCreateHeight = e->window.data2;
} }
return true; return true;
@@ -9509,6 +9516,16 @@ static bool VULKAN_ClaimWindow(
windowData->presentMode = SDL_GPU_PRESENTMODE_VSYNC; windowData->presentMode = SDL_GPU_PRESENTMODE_VSYNC;
windowData->swapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR; windowData->swapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR;
// On non-Apple platforms the swapchain capability currentExtent can be different from the window,
// so we have to query the window size.
#ifndef SDL_PLATFORM_APPLE
int w, h;
SDL_SyncWindow(window);
SDL_GetWindowSizeInPixels(window, &w, &h);
windowData->swapchainCreateWidth = w;
windowData->swapchainCreateHeight = h;
#endif
Uint32 createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowData); Uint32 createSwapchainResult = VULKAN_INTERNAL_CreateSwapchain(renderer, windowData);
if (createSwapchainResult == 1) { if (createSwapchainResult == 1) {
SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData); SDL_SetPointerProperty(SDL_GetWindowProperties(window), WINDOW_PROPERTY_DATA, windowData);