Skip to content

Commit

Permalink
GPU: Add SDL_WaitForGPUSwapchain()
Browse files Browse the repository at this point in the history
  • Loading branch information
lmurray authored and thatcosmonaut committed Dec 11, 2024
1 parent e6e468d commit 77c954e
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 0 deletions.
20 changes: 20 additions & 0 deletions include/SDL3/SDL_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -3580,6 +3580,7 @@ extern SDL_DECLSPEC SDL_GPUTextureFormat SDLCALL SDL_GetGPUSwapchainTextureForma
* \sa SDL_SubmitGPUCommandBufferAndAcquireFence
* \sa SDL_CancelGPUCommandBuffer
* \sa SDL_GetWindowSizeInPixels
* \sa SDL_WaitForGPUSwapchain
*/
extern SDL_DECLSPEC bool SDLCALL SDL_AcquireGPUSwapchainTexture(
SDL_GPUCommandBuffer *command_buffer,
Expand Down Expand Up @@ -3674,6 +3675,25 @@ extern SDL_DECLSPEC bool SDLCALL SDL_CancelGPUCommandBuffer(
extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUIdle(
SDL_GPUDevice *device);

/**
* Blocks the thread until a swapchain texture is available to be acquired.
* Calling this function before SDL_AcquireGPUSwapchainTexture() will ensure
* that the acquire will immediately return a swapchain texture under most, but
* not all, conditions.
*
* \param device a GPU context.
* \param window a window that has been claimed.
* \returns true on success, false on failure; call SDL_GetError() for more
* information.
*
* \since This function is available since SDL 3.2.0.
*
* \sa SDL_AcquireGPUSwapchainTexture
*/
extern SDL_DECLSPEC bool SDLCALL SDL_WaitForGPUSwapchain(
SDL_GPUDevice *device,
SDL_Window *window);

/**
* Blocks the thread until the given fences are signaled.
*
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,7 @@ SDL3_0.0.0 {
SDL_WaitEventTimeout;
SDL_WaitForGPUFences;
SDL_WaitForGPUIdle;
SDL_WaitForGPUSwapchain;
SDL_WaitProcess;
SDL_WaitSemaphore;
SDL_WaitSemaphoreTimeout;
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -999,6 +999,7 @@
#define SDL_WaitEventTimeout SDL_WaitEventTimeout_REAL
#define SDL_WaitForGPUFences SDL_WaitForGPUFences_REAL
#define SDL_WaitForGPUIdle SDL_WaitForGPUIdle_REAL
#define SDL_WaitForGPUSwapchain SDL_WaitForGPUSwapchain_REAL
#define SDL_WaitProcess SDL_WaitProcess_REAL
#define SDL_WaitSemaphore SDL_WaitSemaphore_REAL
#define SDL_WaitSemaphoreTimeout SDL_WaitSemaphoreTimeout_REAL
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,7 @@ SDL_DYNAPI_PROC(bool,SDL_WaitEvent,(SDL_Event *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_WaitEventTimeout,(SDL_Event *a, Sint32 b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_WaitForGPUFences,(SDL_GPUDevice *a, bool b, SDL_GPUFence *const *c, Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_WaitForGPUIdle,(SDL_GPUDevice *a),(a),return)
SDL_DYNAPI_PROC(bool,SDL_WaitForGPUSwapchain,(SDL_GPUDevice *a, SDL_Window *b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_WaitProcess,(SDL_Process *a, bool b, int *c),(a,b,c),return)
SDL_DYNAPI_PROC(void,SDL_WaitSemaphore,(SDL_Semaphore *a),(a),)
SDL_DYNAPI_PROC(bool,SDL_WaitSemaphoreTimeout,(SDL_Semaphore *a, Sint32 b),(a,b),return)
Expand Down
11 changes: 11 additions & 0 deletions src/gpu/SDL_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2809,6 +2809,17 @@ bool SDL_WaitForGPUIdle(
device->driverData);
}

bool SDL_WaitForGPUSwapchain(
SDL_GPUDevice *device,
SDL_Window *window)
{
CHECK_DEVICE_MAGIC(device, false);

return device->WaitForSwapchain(
device->driverData,
window);
}

bool SDL_WaitForGPUFences(
SDL_GPUDevice *device,
bool wait_all,
Expand Down
5 changes: 5 additions & 0 deletions src/gpu/SDL_sysgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,10 @@ struct SDL_GPUDevice
bool (*Wait)(
SDL_GPURenderer *driverData);

bool (*WaitForSwapchain)(
SDL_GPURenderer *driverData,
SDL_Window *window);

bool (*WaitForFences)(
SDL_GPURenderer *driverData,
bool waitAll,
Expand Down Expand Up @@ -941,6 +945,7 @@ struct SDL_GPUDevice
ASSIGN_DRIVER_FUNC(SubmitAndAcquireFence, name) \
ASSIGN_DRIVER_FUNC(Cancel, name) \
ASSIGN_DRIVER_FUNC(Wait, name) \
ASSIGN_DRIVER_FUNC(WaitForSwapchain, name) \
ASSIGN_DRIVER_FUNC(WaitForFences, name) \
ASSIGN_DRIVER_FUNC(QueryFence, name) \
ASSIGN_DRIVER_FUNC(ReleaseFence, name) \
Expand Down
24 changes: 24 additions & 0 deletions src/gpu/d3d12/SDL_gpu_d3d12.c
Original file line number Diff line number Diff line change
Expand Up @@ -7124,6 +7124,30 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
return (SDL_GPUCommandBuffer *)commandBuffer;
}

static bool D3D12_WaitForSwapchain(
SDL_GPURenderer *driverData,
SDL_Window *window)
{
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);

if (windowData == NULL) {
SET_STRING_ERROR_AND_RETURN("Cannot wait for a swapchain from an unclaimed window!", false);
}

if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
if (!D3D12_WaitForFences(
driverData,
true,
&windowData->inFlightFences[windowData->frameCounter],
1)) {
return false;
}
}

return true;
}

static bool D3D12_AcquireSwapchainTexture(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
Expand Down
26 changes: 26 additions & 0 deletions src/gpu/metal/SDL_gpu_metal.m
Original file line number Diff line number Diff line change
Expand Up @@ -3671,6 +3671,32 @@ static void METAL_ReleaseWindow(
}
}

static bool METAL_WaitForSwapchain(
SDL_GPURenderer *driverData,
SDL_Window *window)
{
@autoreleasepool {
MetalRenderer *renderer = (MetalRenderer *)driverData;
MetalWindowData *windowData = METAL_INTERNAL_FetchWindowData(window);

if (windowData == NULL) {
SET_STRING_ERROR_AND_RETURN("Cannot wait for a swapchain from an unclaimed window!", false);
}

if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
if (!METAL_WaitForFences(
driverData,
true,
&windowData->inFlightFences[windowData->frameCounter],
1)) {
return false;
}
}

return true;
}
}

static bool METAL_AcquireSwapchainTexture(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
Expand Down
24 changes: 24 additions & 0 deletions src/gpu/vulkan/SDL_gpu_vulkan.c
Original file line number Diff line number Diff line change
Expand Up @@ -9655,6 +9655,30 @@ static Uint32 VULKAN_INTERNAL_RecreateSwapchain(
return VULKAN_INTERNAL_CreateSwapchain(renderer, windowData);
}

static bool VULKAN_WaitForSwapchain(
SDL_GPURenderer *driverData,
SDL_Window *window)
{
VulkanRenderer *renderer = (VulkanRenderer *)driverData;
WindowData *windowData = VULKAN_INTERNAL_FetchWindowData(window);

if (windowData == NULL) {
SET_STRING_ERROR_AND_RETURN("Cannot wait for a swapchain from an unclaimed window!", false);
}

if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
if (!VULKAN_WaitForFences(
driverData,
true,
&windowData->inFlightFences[windowData->frameCounter],
1)) {
return false;
}
}

return true;
}

static bool VULKAN_AcquireSwapchainTexture(
SDL_GPUCommandBuffer *commandBuffer,
SDL_Window *window,
Expand Down

0 comments on commit 77c954e

Please sign in to comment.