mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-25 14:09:10 +00:00
GPU: Add SetGPUAllowedFramesInFlight (#11599)
This commit is contained in:
parent
47429227ab
commit
fa5f84fb6e
9 changed files with 109 additions and 9 deletions
|
@ -3496,6 +3496,29 @@ extern SDL_DECLSPEC bool SDLCALL SDL_SetGPUSwapchainParameters(
|
||||||
SDL_GPUSwapchainComposition swapchain_composition,
|
SDL_GPUSwapchainComposition swapchain_composition,
|
||||||
SDL_GPUPresentMode present_mode);
|
SDL_GPUPresentMode present_mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the maximum allowed number of frames in flight.
|
||||||
|
*
|
||||||
|
* The default value when the device is created is 2.
|
||||||
|
* This means that after you have submitted 2 frames for presentation, if the GPU has not finished working on the first frame, SDL_AcquireGPUSwapchainTexture() will block or return false depending on the present mode.
|
||||||
|
*
|
||||||
|
* Higher values increase throughput at the expense of visual latency.
|
||||||
|
* Lower values decrease visual latency at the expense of throughput.
|
||||||
|
*
|
||||||
|
* Note that calling this function will stall and flush the command queue to prevent synchronization issues.
|
||||||
|
*
|
||||||
|
* The minimum value of allowed frames in flight is 1, and the maximum is 3.
|
||||||
|
*
|
||||||
|
* \param device a GPU context.
|
||||||
|
* \param allowed_frames_in_flight the maximum number of frames that can be pending on the GPU before AcquireSwapchainTexture blocks or returns false.
|
||||||
|
* \returns true if successful, false on error; call SDL_GetError() for more information.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.2.0.
|
||||||
|
*/
|
||||||
|
extern SDL_DECLSPEC bool SDLCALL SDL_SetGPUAllowedFramesInFlight(
|
||||||
|
SDL_GPUDevice *device,
|
||||||
|
Uint32 allowed_frames_in_flight);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtains the texture format of the swapchain for the given window.
|
* Obtains the texture format of the swapchain for the given window.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1203,6 +1203,7 @@ SDL3_0.0.0 {
|
||||||
SDL_ShowFileDialogWithProperties;
|
SDL_ShowFileDialogWithProperties;
|
||||||
SDL_IsMainThread;
|
SDL_IsMainThread;
|
||||||
SDL_RunOnMainThread;
|
SDL_RunOnMainThread;
|
||||||
|
SDL_SetGPUAllowedFramesInFlight;
|
||||||
# extra symbols go here (don't modify this line)
|
# extra symbols go here (don't modify this line)
|
||||||
local: *;
|
local: *;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1228,3 +1228,4 @@
|
||||||
#define SDL_ShowFileDialogWithProperties SDL_ShowFileDialogWithProperties_REAL
|
#define SDL_ShowFileDialogWithProperties SDL_ShowFileDialogWithProperties_REAL
|
||||||
#define SDL_IsMainThread SDL_IsMainThread_REAL
|
#define SDL_IsMainThread SDL_IsMainThread_REAL
|
||||||
#define SDL_RunOnMainThread SDL_RunOnMainThread_REAL
|
#define SDL_RunOnMainThread SDL_RunOnMainThread_REAL
|
||||||
|
#define SDL_SetGPUAllowedFramesInFlight SDL_SetGPUAllowedFramesInFlight_REAL
|
||||||
|
|
|
@ -1234,3 +1234,4 @@ SDL_DYNAPI_PROC(bool,SDL_LoadFileAsync,(const char *a, SDL_AsyncIOQueue *b, void
|
||||||
SDL_DYNAPI_PROC(void,SDL_ShowFileDialogWithProperties,(SDL_FileDialogType a, SDL_DialogFileCallback b, void *c, SDL_PropertiesID d),(a,b,c,d),)
|
SDL_DYNAPI_PROC(void,SDL_ShowFileDialogWithProperties,(SDL_FileDialogType a, SDL_DialogFileCallback b, void *c, SDL_PropertiesID d),(a,b,c,d),)
|
||||||
SDL_DYNAPI_PROC(bool,SDL_IsMainThread,(void),(),return)
|
SDL_DYNAPI_PROC(bool,SDL_IsMainThread,(void),(),return)
|
||||||
SDL_DYNAPI_PROC(bool,SDL_RunOnMainThread,(SDL_MainThreadCallback a,void *b,bool c),(a,b,c),return)
|
SDL_DYNAPI_PROC(bool,SDL_RunOnMainThread,(SDL_MainThreadCallback a,void *b,bool c),(a,b,c),return)
|
||||||
|
SDL_DYNAPI_PROC(bool,SDL_SetGPUAllowedFramesInFlight,(SDL_GPUDevice *a,Uint32 b),(a,b),return)
|
||||||
|
|
|
@ -2650,6 +2650,25 @@ bool SDL_SetGPUSwapchainParameters(
|
||||||
present_mode);
|
present_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SDL_SetGPUAllowedFramesInFlight(
|
||||||
|
SDL_GPUDevice *device,
|
||||||
|
Uint32 allowed_frames_in_flight)
|
||||||
|
{
|
||||||
|
CHECK_DEVICE_MAGIC(device, false);
|
||||||
|
|
||||||
|
if (device->debug_mode) {
|
||||||
|
if (allowed_frames_in_flight < 1 || allowed_frames_in_flight > 3)
|
||||||
|
{
|
||||||
|
SDL_assert_release(!"allowed_frames_in_flight value must be between 1 and 3!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allowed_frames_in_flight = SDL_clamp(allowed_frames_in_flight, 1, 3);
|
||||||
|
return device->SetAllowedFramesInFlight(
|
||||||
|
device->driverData,
|
||||||
|
allowed_frames_in_flight);
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GPUTextureFormat SDL_GetGPUSwapchainTextureFormat(
|
SDL_GPUTextureFormat SDL_GetGPUSwapchainTextureFormat(
|
||||||
SDL_GPUDevice *device,
|
SDL_GPUDevice *device,
|
||||||
SDL_Window *window)
|
SDL_Window *window)
|
||||||
|
|
|
@ -791,6 +791,10 @@ struct SDL_GPUDevice
|
||||||
SDL_GPUSwapchainComposition swapchainComposition,
|
SDL_GPUSwapchainComposition swapchainComposition,
|
||||||
SDL_GPUPresentMode presentMode);
|
SDL_GPUPresentMode presentMode);
|
||||||
|
|
||||||
|
bool (*SetAllowedFramesInFlight)(
|
||||||
|
SDL_GPURenderer *driverData,
|
||||||
|
Uint32 allowedFramesInFlight);
|
||||||
|
|
||||||
SDL_GPUTextureFormat (*GetSwapchainTextureFormat)(
|
SDL_GPUTextureFormat (*GetSwapchainTextureFormat)(
|
||||||
SDL_GPURenderer *driverData,
|
SDL_GPURenderer *driverData,
|
||||||
SDL_Window *window);
|
SDL_Window *window);
|
||||||
|
@ -927,6 +931,7 @@ struct SDL_GPUDevice
|
||||||
ASSIGN_DRIVER_FUNC(ClaimWindow, name) \
|
ASSIGN_DRIVER_FUNC(ClaimWindow, name) \
|
||||||
ASSIGN_DRIVER_FUNC(ReleaseWindow, name) \
|
ASSIGN_DRIVER_FUNC(ReleaseWindow, name) \
|
||||||
ASSIGN_DRIVER_FUNC(SetSwapchainParameters, name) \
|
ASSIGN_DRIVER_FUNC(SetSwapchainParameters, name) \
|
||||||
|
ASSIGN_DRIVER_FUNC(SetAllowedFramesInFlight, name) \
|
||||||
ASSIGN_DRIVER_FUNC(GetSwapchainTextureFormat, name) \
|
ASSIGN_DRIVER_FUNC(GetSwapchainTextureFormat, name) \
|
||||||
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
|
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
|
||||||
ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \
|
ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \
|
||||||
|
|
|
@ -750,6 +750,7 @@ struct D3D12Renderer
|
||||||
// FIXME: these might not be necessary since we're not using custom heaps
|
// FIXME: these might not be necessary since we're not using custom heaps
|
||||||
bool UMA;
|
bool UMA;
|
||||||
bool UMACacheCoherent;
|
bool UMACacheCoherent;
|
||||||
|
Uint32 allowedFramesInFlight;
|
||||||
|
|
||||||
// Indirect command signatures
|
// Indirect command signatures
|
||||||
ID3D12CommandSignature *indirectDrawCommandSignature;
|
ID3D12CommandSignature *indirectDrawCommandSignature;
|
||||||
|
@ -6809,6 +6810,20 @@ static bool D3D12_SetSwapchainParameters(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool D3D12_SetAllowedFramesInFlight(
|
||||||
|
SDL_GPURenderer *driverData,
|
||||||
|
Uint32 allowedFramesInFlight)
|
||||||
|
{
|
||||||
|
D3D12Renderer *renderer = (D3D12Renderer *)driverData;
|
||||||
|
|
||||||
|
if (!D3D12_Wait(driverData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->allowedFramesInFlight = allowedFramesInFlight;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_GPUTextureFormat D3D12_GetSwapchainTextureFormat(
|
static SDL_GPUTextureFormat D3D12_GetSwapchainTextureFormat(
|
||||||
SDL_GPURenderer *driverData,
|
SDL_GPURenderer *driverData,
|
||||||
SDL_Window *window)
|
SDL_Window *window)
|
||||||
|
@ -7569,7 +7584,7 @@ static bool D3D12_Submit(
|
||||||
|
|
||||||
windowData->inFlightFences[windowData->frameCounter] = (SDL_GPUFence*)d3d12CommandBuffer->inFlightFence;
|
windowData->inFlightFences[windowData->frameCounter] = (SDL_GPUFence*)d3d12CommandBuffer->inFlightFence;
|
||||||
(void)SDL_AtomicIncRef(&d3d12CommandBuffer->inFlightFence->referenceCount);
|
(void)SDL_AtomicIncRef(&d3d12CommandBuffer->inFlightFence->referenceCount);
|
||||||
windowData->frameCounter = (windowData->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT;
|
windowData->frameCounter = (windowData->frameCounter + 1) % renderer->allowedFramesInFlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for cleanups
|
// Check for cleanups
|
||||||
|
@ -8776,6 +8791,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||||
renderer->disposeLock = SDL_CreateMutex();
|
renderer->disposeLock = SDL_CreateMutex();
|
||||||
|
|
||||||
renderer->debug_mode = debugMode;
|
renderer->debug_mode = debugMode;
|
||||||
|
renderer->allowedFramesInFlight = 2;
|
||||||
|
|
||||||
renderer->semantic = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING, "TEXCOORD");
|
renderer->semantic = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_SEMANTIC_NAME_STRING, "TEXCOORD");
|
||||||
|
|
||||||
|
|
|
@ -641,6 +641,7 @@ struct MetalRenderer
|
||||||
id<MTLCommandQueue> queue;
|
id<MTLCommandQueue> queue;
|
||||||
|
|
||||||
bool debugMode;
|
bool debugMode;
|
||||||
|
Uint32 allowedFramesInFlight;
|
||||||
|
|
||||||
MetalWindowData **claimedWindows;
|
MetalWindowData **claimedWindows;
|
||||||
Uint32 claimedWindowCount;
|
Uint32 claimedWindowCount;
|
||||||
|
@ -3817,6 +3818,22 @@ static bool METAL_SetSwapchainParameters(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool METAL_SetAllowedFramesInFlight(
|
||||||
|
SDL_GPURenderer *driverData,
|
||||||
|
Uint32 allowedFramesInFlight)
|
||||||
|
{
|
||||||
|
@autoreleasepool {
|
||||||
|
MetalRenderer *renderer = (MetalRenderer *)driverData;
|
||||||
|
|
||||||
|
if (!METAL_Wait(driverData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->allowedFramesInFlight = allowedFramesInFlight;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Submission
|
// Submission
|
||||||
|
|
||||||
static bool METAL_Submit(
|
static bool METAL_Submit(
|
||||||
|
@ -3843,7 +3860,7 @@ static bool METAL_Submit(
|
||||||
|
|
||||||
(void)SDL_AtomicIncRef(&metalCommandBuffer->fence->referenceCount);
|
(void)SDL_AtomicIncRef(&metalCommandBuffer->fence->referenceCount);
|
||||||
|
|
||||||
windowData->frameCounter = (windowData->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT;
|
windowData->frameCounter = (windowData->frameCounter + 1) % renderer->allowedFramesInFlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the fence when the command buffer has completed
|
// Notify the fence when the command buffer has completed
|
||||||
|
@ -4301,6 +4318,7 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD
|
||||||
|
|
||||||
// Remember debug mode
|
// Remember debug mode
|
||||||
renderer->debugMode = debugMode;
|
renderer->debugMode = debugMode;
|
||||||
|
renderer->allowedFramesInFlight = 2;
|
||||||
|
|
||||||
// Set up colorspace array
|
// Set up colorspace array
|
||||||
SwapchainCompositionToColorSpace[0] = kCGColorSpaceSRGB;
|
SwapchainCompositionToColorSpace[0] = kCGColorSpaceSRGB;
|
||||||
|
|
|
@ -1123,6 +1123,8 @@ struct VulkanRenderer
|
||||||
|
|
||||||
bool debugMode;
|
bool debugMode;
|
||||||
bool preferLowPower;
|
bool preferLowPower;
|
||||||
|
Uint32 allowedFramesInFlight;
|
||||||
|
|
||||||
VulkanExtensions supports;
|
VulkanExtensions supports;
|
||||||
bool supportsDebugUtils;
|
bool supportsDebugUtils;
|
||||||
bool supportsColorspace;
|
bool supportsColorspace;
|
||||||
|
@ -9898,6 +9900,20 @@ static bool VULKAN_SetSwapchainParameters(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool VULKAN_SetAllowedFramesInFlight(
|
||||||
|
SDL_GPURenderer *driverData,
|
||||||
|
Uint32 allowedFramesInFlight)
|
||||||
|
{
|
||||||
|
VulkanRenderer *renderer = (VulkanRenderer *)driverData;
|
||||||
|
|
||||||
|
if (!VULKAN_Wait(driverData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer->allowedFramesInFlight = allowedFramesInFlight;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Submission structure
|
// Submission structure
|
||||||
|
|
||||||
static VulkanFenceHandle *VULKAN_INTERNAL_AcquireFenceFromPool(
|
static VulkanFenceHandle *VULKAN_INTERNAL_AcquireFenceFromPool(
|
||||||
|
@ -10348,8 +10364,7 @@ static bool VULKAN_Submit(
|
||||||
}
|
}
|
||||||
|
|
||||||
presentData->windowData->frameCounter =
|
presentData->windowData->frameCounter =
|
||||||
(presentData->windowData->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT;
|
(presentData->windowData->frameCounter + 1) % renderer->allowedFramesInFlight;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we can perform any cleanups
|
// Check if we can perform any cleanups
|
||||||
|
@ -11438,6 +11453,7 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
|
||||||
SDL_memset(renderer, '\0', sizeof(VulkanRenderer));
|
SDL_memset(renderer, '\0', sizeof(VulkanRenderer));
|
||||||
renderer->debugMode = debugMode;
|
renderer->debugMode = debugMode;
|
||||||
renderer->preferLowPower = preferLowPower;
|
renderer->preferLowPower = preferLowPower;
|
||||||
|
renderer->allowedFramesInFlight = 2;
|
||||||
|
|
||||||
if (!VULKAN_INTERNAL_PrepareVulkan(renderer)) {
|
if (!VULKAN_INTERNAL_PrepareVulkan(renderer)) {
|
||||||
SDL_free(renderer);
|
SDL_free(renderer);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue