GPU: Add swapchain dimension out params (#11003)

This commit is contained in:
Evan Hemsley
2024-09-30 10:23:19 -07:00
committed by GitHub
parent b3388d5753
commit afdf325fb4
11 changed files with 347 additions and 285 deletions
+13 -9
View File
@@ -3316,7 +3316,7 @@ extern SDL_DECLSPEC void SDLCALL SDL_ReleaseWindowFromGPUDevice(
* \param window an SDL_Window that has been claimed.
* \param swapchain_composition the desired composition of the swapchain.
* \param present_mode the desired present mode for the swapchain.
* \returns true if successful, false on error.
* \returns true if successful, false on error; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
@@ -3350,20 +3350,22 @@ extern SDL_DECLSPEC SDL_GPUTextureFormat SDLCALL SDL_GetGPUSwapchainTextureForma
* When a swapchain texture is acquired on a command buffer, it will
* automatically be submitted for presentation when the command buffer is
* submitted. The swapchain texture should only be referenced by the command
* buffer used to acquire it. The swapchain texture handle can be NULL under
* buffer used to acquire it. The swapchain texture handle can be filled in with NULL under
* certain conditions. This is not necessarily an error. If this function
* returns false then there is an error. The swapchain texture is managed by
* the implementation and must not be freed by the user. The texture
* dimensions will be the width and height of the claimed window. You can
* obtain these dimensions by calling SDL_GetWindowSizeInPixels. You MUST NOT
* returns false then there is an error.
*
* The swapchain texture is managed by
* the implementation and must not be freed by the user. You MUST NOT
* call this function from any thread other than the one that created the
* window.
*
* \param command_buffer a command buffer.
* \param window a window that has been claimed.
* \param swapchainTexture a pointer filled in with a swapchain texture
* \param swapchain_texture a pointer filled in with a swapchain texture
* handle.
* \returns true on success, false on error.
* \param swapchain_texture_width a pointer filled in with the swapchain texture width, may be NULL.
* \param swapchain_texture_height a pointer filled in with the swapchain texture height, may be NULL.
* \returns true on success, false on error; call SDL_GetError() for more information.
*
* \since This function is available since SDL 3.0.0.
*
@@ -3375,7 +3377,9 @@ extern SDL_DECLSPEC SDL_GPUTextureFormat SDLCALL SDL_GetGPUSwapchainTextureForma
extern SDL_DECLSPEC bool SDLCALL SDL_AcquireGPUSwapchainTexture(
SDL_GPUCommandBuffer *command_buffer,
SDL_Window *window,
SDL_GPUTexture **swapchainTexture);
SDL_GPUTexture **swapchain_texture,
Uint32 *swapchain_texture_width,
Uint32 *swapchain_texture_height);
/**
* Submits a command buffer so its commands can be processed on the GPU.
+1 -1
View File
@@ -50,7 +50,7 @@ SDL_DYNAPI_PROC(int,SDL_swprintf,(SDL_OUT_Z_CAP(b) wchar_t *a, size_t b, SDL_PRI
// New API symbols are added at the end
SDL_DYNAPI_PROC(SDL_Surface*,SDL_AcquireCameraFrame,(SDL_Camera *a, Uint64 *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_GPUCommandBuffer*,SDL_AcquireGPUCommandBuffer,(SDL_GPUDevice *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_AcquireGPUSwapchainTexture,(SDL_GPUCommandBuffer *a, SDL_Window *b, SDL_GPUTexture **c),(a,b,c),return)
SDL_DYNAPI_PROC(bool,SDL_AcquireGPUSwapchainTexture,(SDL_GPUCommandBuffer *a, SDL_Window *b, SDL_GPUTexture **c, Uint32 *d, Uint32 *e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_AddAtomicInt,(SDL_AtomicInt *a, int b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_AddEventWatch,(SDL_EventFilter a, void *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_AddGamepadMapping,(const char *a),(a),return)
+8 -4
View File
@@ -2613,7 +2613,9 @@ SDL_GPUTextureFormat SDL_GetGPUSwapchainTextureFormat(
bool SDL_AcquireGPUSwapchainTexture(
SDL_GPUCommandBuffer *command_buffer,
SDL_Window *window,
SDL_GPUTexture **swapchainTexture)
SDL_GPUTexture **swapchain_texture,
Uint32 *swapchain_texture_width,
Uint32 *swapchain_texture_height)
{
if (command_buffer == NULL) {
SDL_InvalidParamError("command_buffer");
@@ -2623,8 +2625,8 @@ bool SDL_AcquireGPUSwapchainTexture(
SDL_InvalidParamError("window");
return false;
}
if (swapchainTexture == NULL) {
SDL_InvalidParamError("swapchainTexture");
if (swapchain_texture == NULL) {
SDL_InvalidParamError("swapchain_texture");
return false;
}
@@ -2636,7 +2638,9 @@ bool SDL_AcquireGPUSwapchainTexture(
return COMMAND_BUFFER_DEVICE->AcquireSwapchainTexture(
command_buffer,
window,
swapchainTexture);
swapchain_texture,
swapchain_texture_width,
swapchain_texture_height);
}
bool SDL_SubmitGPUCommandBuffer(
+3 -1
View File
@@ -651,7 +651,9 @@ struct SDL_GPUDevice
bool (*AcquireSwapchainTexture)(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
SDL_GPUTexture **swapchainTexture);
SDL_GPUTexture **swapchainTexture,
Uint32 *swapchainTextureWidth,
Uint32 *swapchainTextureHeight);
bool (*Submit)(
SDL_GPUCommandBuffer *commandBuffer);
+22 -1
View File
@@ -480,6 +480,8 @@ typedef struct D3D11WindowData
SDL_GPUSwapchainComposition swapchainComposition;
DXGI_FORMAT swapchainFormat;
DXGI_COLOR_SPACE_TYPE swapchainColorSpace;
Uint32 width;
Uint32 height;
SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT];
Uint32 frameCounter;
bool needsSwapchainRecreate;
@@ -5250,6 +5252,8 @@ static bool D3D11_INTERNAL_CreateSwapchain(
windowData->texture.container = &windowData->textureContainer;
windowData->texture.containerIndex = 0;
windowData->width = w;
windowData->height = h;
return true;
}
@@ -5288,6 +5292,8 @@ static bool D3D11_INTERNAL_ResizeSwapchain(
windowData->textureContainer.header.info.width = w;
windowData->textureContainer.header.info.height = h;
windowData->width = w;
windowData->height = h;
windowData->needsSwapchainRecreate = !result;
return result;
}
@@ -5469,7 +5475,9 @@ static void D3D11_ReleaseWindow(
static bool D3D11_AcquireSwapchainTexture(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
SDL_GPUTexture **swapchainTexture)
SDL_GPUTexture **swapchainTexture,
Uint32 *swapchainTextureWidth,
Uint32 *swapchainTextureHeight)
{
D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer *)commandBuffer;
D3D11Renderer *renderer = (D3D11Renderer *)d3d11CommandBuffer->renderer;
@@ -5477,6 +5485,12 @@ static bool D3D11_AcquireSwapchainTexture(
HRESULT res;
*swapchainTexture = NULL;
if (swapchainTextureWidth) {
*swapchainTextureWidth = 0;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = 0;
}
windowData = D3D11_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
@@ -5489,6 +5503,13 @@ static bool D3D11_AcquireSwapchainTexture(
}
}
if (swapchainTextureWidth) {
*swapchainTextureWidth = windowData->width;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = windowData->height;
}
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
if (windowData->presentMode == SDL_GPU_PRESENTMODE_VSYNC) {
// In VSYNC mode, block until the least recent presented frame is done
+25 -1
View File
@@ -554,6 +554,8 @@ typedef struct D3D12WindowData
D3D12TextureContainer textureContainers[MAX_FRAMES_IN_FLIGHT];
SDL_GPUFence *inFlightFences[MAX_FRAMES_IN_FLIGHT];
Uint32 width;
Uint32 height;
bool needsSwapchainRecreate;
} D3D12WindowData;
@@ -6331,6 +6333,8 @@ static bool D3D12_INTERNAL_ResizeSwapchain(
}
}
windowData->width = w;
windowData->height = h;
windowData->needsSwapchainRecreate = false;
return true;
}
@@ -6382,6 +6386,9 @@ static bool D3D12_INTERNAL_CreateSwapchain(
swapchainFormat = SwapchainCompositionToTextureFormat[swapchainComposition];
int w, h;
SDL_GetWindowSizeInPixels(windowData->window, &w, &h);
// Initialize the swapchain buffer descriptor
swapchainDesc.Width = 0;
swapchainDesc.Height = 0;
@@ -6477,6 +6484,8 @@ static bool D3D12_INTERNAL_CreateSwapchain(
windowData->swapchainComposition = swapchainComposition;
windowData->swapchainColorSpace = SwapchainCompositionToColorSpace[swapchainComposition];
windowData->frameCounter = 0;
windowData->width = w;
windowData->height = h;
// Precache blit pipelines for the swapchain format
for (Uint32 i = 0; i < 5; i += 1) {
@@ -6907,7 +6916,9 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
static bool D3D12_AcquireSwapchainTexture(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
SDL_GPUTexture **swapchainTexture)
SDL_GPUTexture **swapchainTexture,
Uint32 *swapchainTextureWidth,
Uint32 *swapchainTextureHeight)
{
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
D3D12Renderer *renderer = d3d12CommandBuffer->renderer;
@@ -6916,6 +6927,12 @@ static bool D3D12_AcquireSwapchainTexture(
HRESULT res;
*swapchainTexture = NULL;
if (swapchainTextureWidth) {
*swapchainTextureWidth = 0;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = 0;
}
windowData = D3D12_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
@@ -6928,6 +6945,13 @@ static bool D3D12_AcquireSwapchainTexture(
}
}
if (swapchainTextureWidth) {
*swapchainTextureWidth = windowData->width;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = windowData->height;
}
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
if (windowData->present_mode == SDL_GPU_PRESENTMODE_VSYNC) {
// In VSYNC mode, block until the least recent presented frame is done
+15 -1
View File
@@ -3590,7 +3590,9 @@ static void METAL_ReleaseWindow(
static bool METAL_AcquireSwapchainTexture(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
SDL_GPUTexture **texture)
SDL_GPUTexture **texture,
Uint32 *swapchainTextureWidth,
Uint32 *swapchainTextureHeight)
{
@autoreleasepool {
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
@@ -3599,6 +3601,12 @@ static bool METAL_AcquireSwapchainTexture(
CGSize drawableSize;
*texture = NULL;
if (swapchainTextureWidth) {
*swapchainTextureWidth = 0;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = 0;
}
windowData = METAL_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
@@ -3613,6 +3621,12 @@ static bool METAL_AcquireSwapchainTexture(
drawableSize = windowData->layer.drawableSize;
windowData->textureContainer.header.info.width = (Uint32)drawableSize.width;
windowData->textureContainer.header.info.height = (Uint32)drawableSize.height;
if (swapchainTextureWidth) {
*swapchainTextureWidth = (Uint32)drawableSize.width;
}
if (swapchainTextureHeight) {
*swapchainTextureHeight = (Uint32)drawableSize.height;
}
// Set up presentation
if (metalCommandBuffer->windowDataCount == metalCommandBuffer->windowDataCapacity) {
File diff suppressed because it is too large Load Diff
+9 -10
View File
@@ -957,7 +957,8 @@ static bool GPU_RenderPresent(SDL_Renderer *renderer)
GPU_RenderData *data = (GPU_RenderData *)renderer->internal;
SDL_GPUTexture *swapchain;
bool result = SDL_AcquireGPUSwapchainTexture(data->state.command_buffer, renderer->window, &swapchain);
Uint32 swapchain_texture_width, swapchain_texture_height;
bool result = SDL_AcquireGPUSwapchainTexture(data->state.command_buffer, renderer->window, &swapchain, &swapchain_texture_width, &swapchain_texture_height);
if (!result) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to acquire swapchain texture: %s", SDL_GetError());
@@ -967,8 +968,6 @@ static bool GPU_RenderPresent(SDL_Renderer *renderer)
goto submit;
}
SDL_GPUTextureFormat swapchain_fmt = SDL_GetGPUSwapchainTextureFormat(data->device, renderer->window);
SDL_GPUBlitInfo blit_info;
SDL_zero(blit_info);
@@ -976,18 +975,13 @@ static bool GPU_RenderPresent(SDL_Renderer *renderer)
blit_info.source.w = data->backbuffer.width;
blit_info.source.h = data->backbuffer.height;
blit_info.destination.texture = swapchain;
blit_info.destination.w = renderer->output_pixel_w;
blit_info.destination.h = renderer->output_pixel_h;
blit_info.destination.w = swapchain_texture_width;
blit_info.destination.h = swapchain_texture_height;
blit_info.load_op = SDL_GPU_LOADOP_DONT_CARE;
blit_info.filter = SDL_GPU_FILTER_LINEAR;
SDL_BlitGPUTexture(data->state.command_buffer, &blit_info);
if (renderer->output_pixel_w != data->backbuffer.width || renderer->output_pixel_h != data->backbuffer.height || swapchain_fmt != data->backbuffer.format) {
SDL_ReleaseGPUTexture(data->device, data->backbuffer.texture);
CreateBackbuffer(data, renderer->output_pixel_w, renderer->output_pixel_h, swapchain_fmt);
}
// *** FIXME ***
// This is going to block if there is ever a frame in flight.
// We should do something similar to FNA3D
@@ -1006,6 +1000,11 @@ submit:
SDL_SubmitGPUCommandBuffer(data->state.command_buffer);
#endif
if (swapchain != NULL && (swapchain_texture_width != data->backbuffer.width || swapchain_texture_height != data->backbuffer.height)) {
SDL_ReleaseGPUTexture(data->device, data->backbuffer.texture);
CreateBackbuffer(data, swapchain_texture_width, swapchain_texture_height, SDL_GetGPUSwapchainTextureFormat(data->device, renderer->window));
}
data->state.command_buffer = SDL_AcquireGPUCommandBuffer(data->device);
return true;
+1 -1
View File
@@ -82,7 +82,7 @@ SDL_AppResult SDL_AppIterate(void *appstate)
}
SDL_GPUTexture *swapchainTexture;
if (!SDL_AcquireGPUSwapchainTexture(cmdbuf, state->windows[0], &swapchainTexture)) {
if (!SDL_AcquireGPUSwapchainTexture(cmdbuf, state->windows[0], &swapchainTexture, NULL, NULL)) {
SDL_Log("SDL_AcquireGPUSwapchainTexture failed: %s", SDL_GetError());
return SDL_APP_FAILURE;
}
+2 -4
View File
@@ -333,7 +333,7 @@ Render(SDL_Window *window, const int windownum)
SDL_GPURenderPass *pass;
SDL_GPUBufferBinding vertex_binding;
SDL_GPUBlitInfo blit_info;
int drawablew, drawableh;
Uint32 drawablew, drawableh;
/* Acquire the swapchain texture */
@@ -342,7 +342,7 @@ Render(SDL_Window *window, const int windownum)
SDL_Log("Failed to acquire command buffer :%s", SDL_GetError());
quit(2);
}
if (!SDL_AcquireGPUSwapchainTexture(cmd, state->windows[windownum], &swapchainTexture)) {
if (!SDL_AcquireGPUSwapchainTexture(cmd, state->windows[windownum], &swapchainTexture, &drawablew, &drawableh)) {
SDL_Log("Failed to acquire swapchain texture: %s", SDL_GetError());
quit(2);
}
@@ -353,8 +353,6 @@ Render(SDL_Window *window, const int windownum)
return;
}
SDL_GetWindowSizeInPixels(window, &drawablew, &drawableh);
/*
* Do some rotation with Euler angles. It is not a fixed axis as
* quaterions would be, but the effect is cool.