mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-21 18:58:13 +00:00
GPU: Revise swapchain acquisition (#11633)
--------- Co-authored-by: Lucas Murray <22484+lmurray@users.noreply.github.com>
This commit is contained in:
@@ -2694,16 +2694,13 @@ bool SDL_AcquireGPUSwapchainTexture(
|
||||
CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
|
||||
if (command_buffer == NULL) {
|
||||
SDL_InvalidParamError("command_buffer");
|
||||
return false;
|
||||
return SDL_InvalidParamError("command_buffer");
|
||||
}
|
||||
if (window == NULL) {
|
||||
SDL_InvalidParamError("window");
|
||||
return false;
|
||||
return SDL_InvalidParamError("window");
|
||||
}
|
||||
if (swapchain_texture == NULL) {
|
||||
SDL_InvalidParamError("swapchain_texture");
|
||||
return false;
|
||||
return SDL_InvalidParamError("swapchain_texture");
|
||||
}
|
||||
|
||||
if (COMMAND_BUFFER_DEVICE->debug_mode) {
|
||||
@@ -2725,6 +2722,59 @@ bool SDL_AcquireGPUSwapchainTexture(
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SDL_WaitForGPUSwapchain(
|
||||
SDL_GPUDevice *device,
|
||||
SDL_Window *window)
|
||||
{
|
||||
CHECK_DEVICE_MAGIC(device, false);
|
||||
|
||||
if (window == NULL) {
|
||||
return SDL_InvalidParamError("window");
|
||||
}
|
||||
|
||||
return device->WaitForSwapchain(
|
||||
device->driverData,
|
||||
window);
|
||||
}
|
||||
|
||||
bool SDL_WaitAndAcquireGPUSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height)
|
||||
{
|
||||
CommandBufferCommonHeader *commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||
|
||||
if (command_buffer == NULL) {
|
||||
return SDL_InvalidParamError("command_buffer");
|
||||
}
|
||||
if (window == NULL) {
|
||||
return SDL_InvalidParamError("window");
|
||||
}
|
||||
if (swapchain_texture == NULL) {
|
||||
return SDL_InvalidParamError("swapchain_texture");
|
||||
}
|
||||
|
||||
if (COMMAND_BUFFER_DEVICE->debug_mode) {
|
||||
CHECK_COMMAND_BUFFER_RETURN_FALSE
|
||||
CHECK_ANY_PASS_IN_PROGRESS("Cannot acquire a swapchain texture during a pass!", false)
|
||||
}
|
||||
|
||||
bool result = COMMAND_BUFFER_DEVICE->WaitAndAcquireSwapchainTexture(
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
|
||||
if (*swapchain_texture != NULL){
|
||||
commandBufferHeader->swapchain_texture_acquired = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SDL_SubmitGPUCommandBuffer(
|
||||
SDL_GPUCommandBuffer *command_buffer)
|
||||
{
|
||||
|
@@ -811,6 +811,17 @@ struct SDL_GPUDevice
|
||||
Uint32 *swapchainTextureWidth,
|
||||
Uint32 *swapchainTextureHeight);
|
||||
|
||||
bool (*WaitForSwapchain)(
|
||||
SDL_GPURenderer *driverData,
|
||||
SDL_Window *window);
|
||||
|
||||
bool (*WaitAndAcquireSwapchainTexture)(
|
||||
SDL_GPUCommandBuffer *commandBuffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchainTexture,
|
||||
Uint32 *swapchainTextureWidth,
|
||||
Uint32 *swapchainTextureHeight);
|
||||
|
||||
bool (*Submit)(
|
||||
SDL_GPUCommandBuffer *commandBuffer);
|
||||
|
||||
@@ -937,6 +948,8 @@ struct SDL_GPUDevice
|
||||
ASSIGN_DRIVER_FUNC(GetSwapchainTextureFormat, name) \
|
||||
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
|
||||
ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \
|
||||
ASSIGN_DRIVER_FUNC(WaitForSwapchain, name) \
|
||||
ASSIGN_DRIVER_FUNC(WaitAndAcquireSwapchainTexture, name)\
|
||||
ASSIGN_DRIVER_FUNC(Submit, name) \
|
||||
ASSIGN_DRIVER_FUNC(SubmitAndAcquireFence, name) \
|
||||
ASSIGN_DRIVER_FUNC(Cancel, name) \
|
||||
|
@@ -7124,7 +7124,32 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
|
||||
return (SDL_GPUCommandBuffer *)commandBuffer;
|
||||
}
|
||||
|
||||
static bool D3D12_AcquireSwapchainTexture(
|
||||
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_INTERNAL_AcquireSwapchainTexture(
|
||||
bool block,
|
||||
SDL_GPUCommandBuffer *commandBuffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchainTexture,
|
||||
@@ -7164,7 +7189,7 @@ static bool D3D12_AcquireSwapchainTexture(
|
||||
}
|
||||
|
||||
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
|
||||
if (windowData->present_mode == SDL_GPU_PRESENTMODE_VSYNC) {
|
||||
if (block) {
|
||||
// In VSYNC mode, block until the least recent presented frame is done
|
||||
if (!D3D12_WaitForFences(
|
||||
(SDL_GPURenderer *)renderer,
|
||||
@@ -7174,13 +7199,11 @@ static bool D3D12_AcquireSwapchainTexture(
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// If we are not blocking and the least recent fence is not signaled,
|
||||
// return true to indicate that there is no error but rendering should be skipped.
|
||||
if (!D3D12_QueryFence(
|
||||
(SDL_GPURenderer *)renderer,
|
||||
windowData->inFlightFences[windowData->frameCounter])) {
|
||||
/*
|
||||
* In MAILBOX or IMMEDIATE mode, if the least recent fence is not signaled,
|
||||
* return true to indicate that there is no error but rendering should be skipped
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -7238,6 +7261,38 @@ static bool D3D12_AcquireSwapchainTexture(
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool D3D12_AcquireSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height
|
||||
) {
|
||||
return D3D12_INTERNAL_AcquireSwapchainTexture(
|
||||
false,
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
}
|
||||
|
||||
static bool D3D12_WaitAndAcquireSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height
|
||||
) {
|
||||
return D3D12_INTERNAL_AcquireSwapchainTexture(
|
||||
true,
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
}
|
||||
|
||||
static void D3D12_INTERNAL_PerformPendingDestroys(D3D12Renderer *renderer)
|
||||
{
|
||||
SDL_LockMutex(renderer->disposeLock);
|
||||
|
@@ -3671,7 +3671,34 @@ static void METAL_ReleaseWindow(
|
||||
}
|
||||
}
|
||||
|
||||
static bool METAL_AcquireSwapchainTexture(
|
||||
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_INTERNAL_AcquireSwapchainTexture(
|
||||
bool block,
|
||||
SDL_GPUCommandBuffer *commandBuffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **texture,
|
||||
@@ -3709,8 +3736,8 @@ static bool METAL_AcquireSwapchainTexture(
|
||||
}
|
||||
|
||||
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
|
||||
if (block) {
|
||||
// If we are blocking, just wait for the fence!
|
||||
if (!METAL_WaitForFences(
|
||||
(SDL_GPURenderer *)renderer,
|
||||
true,
|
||||
@@ -3719,13 +3746,11 @@ static bool METAL_AcquireSwapchainTexture(
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// If we are not blocking and the least recent fence is not signaled,
|
||||
// return true to indicate that there is no error but rendering should be skipped.
|
||||
if (!METAL_QueryFence(
|
||||
(SDL_GPURenderer *)metalCommandBuffer->renderer,
|
||||
windowData->inFlightFences[windowData->frameCounter])) {
|
||||
/*
|
||||
* In IMMEDIATE mode, if the least recent fence is not signaled,
|
||||
* return true to indicate that there is no error but rendering should be skipped
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -3757,6 +3782,38 @@ static bool METAL_AcquireSwapchainTexture(
|
||||
}
|
||||
}
|
||||
|
||||
static bool METAL_AcquireSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height
|
||||
) {
|
||||
return METAL_INTERNAL_AcquireSwapchainTexture(
|
||||
false,
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
}
|
||||
|
||||
static bool METAL_WaitAndAcquireSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height
|
||||
) {
|
||||
return METAL_INTERNAL_AcquireSwapchainTexture(
|
||||
true,
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
}
|
||||
|
||||
static SDL_GPUTextureFormat METAL_GetSwapchainTextureFormat(
|
||||
SDL_GPURenderer *driverData,
|
||||
SDL_Window *window)
|
||||
|
@@ -9655,7 +9655,32 @@ static Uint32 VULKAN_INTERNAL_RecreateSwapchain(
|
||||
return VULKAN_INTERNAL_CreateSwapchain(renderer, windowData);
|
||||
}
|
||||
|
||||
static bool VULKAN_AcquireSwapchainTexture(
|
||||
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_INTERNAL_AcquireSwapchainTexture(
|
||||
bool block,
|
||||
SDL_GPUCommandBuffer *commandBuffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchainTexture,
|
||||
@@ -9708,8 +9733,8 @@ static bool VULKAN_AcquireSwapchainTexture(
|
||||
}
|
||||
|
||||
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
|
||||
if (block) {
|
||||
// If we are blocking, just wait for the fence!
|
||||
if (!VULKAN_WaitForFences(
|
||||
(SDL_GPURenderer *)renderer,
|
||||
true,
|
||||
@@ -9718,13 +9743,11 @@ static bool VULKAN_AcquireSwapchainTexture(
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// If we are not blocking and the least recent fence is not signaled,
|
||||
// return true to indicate that there is no error but rendering should be skipped.
|
||||
if (!VULKAN_QueryFence(
|
||||
(SDL_GPURenderer *)renderer,
|
||||
windowData->inFlightFences[windowData->frameCounter])) {
|
||||
/*
|
||||
* In MAILBOX or IMMEDIATE mode, if the least recent fence is not signaled,
|
||||
* return true to indicate that there is no error but rendering should be skipped
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -9843,6 +9866,38 @@ static bool VULKAN_AcquireSwapchainTexture(
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool VULKAN_AcquireSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height
|
||||
) {
|
||||
return VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
false,
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
}
|
||||
|
||||
static bool VULKAN_WaitAndAcquireSwapchainTexture(
|
||||
SDL_GPUCommandBuffer *command_buffer,
|
||||
SDL_Window *window,
|
||||
SDL_GPUTexture **swapchain_texture,
|
||||
Uint32 *swapchain_texture_width,
|
||||
Uint32 *swapchain_texture_height
|
||||
) {
|
||||
return VULKAN_INTERNAL_AcquireSwapchainTexture(
|
||||
true,
|
||||
command_buffer,
|
||||
window,
|
||||
swapchain_texture,
|
||||
swapchain_texture_width,
|
||||
swapchain_texture_height);
|
||||
}
|
||||
|
||||
static SDL_GPUTextureFormat VULKAN_GetSwapchainTextureFormat(
|
||||
SDL_GPURenderer *driverData,
|
||||
SDL_Window *window)
|
||||
|
Reference in New Issue
Block a user