From cb65bb9af1dec79c2d3423385ef15acd17fefc70 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Thu, 9 May 2024 14:01:30 -0700 Subject: [PATCH] track upload and render fence, fix copy pass interrupt --- src/FNA3D_Driver_SDL.c | 148 +++++++++++++++++++++++++++++------------ 1 file changed, 106 insertions(+), 42 deletions(-) diff --git a/src/FNA3D_Driver_SDL.c b/src/FNA3D_Driver_SDL.c index 926a6b2b..b8936683 100644 --- a/src/FNA3D_Driver_SDL.c +++ b/src/FNA3D_Driver_SDL.c @@ -597,7 +597,7 @@ typedef struct SDLGPU_Renderer /* Synchronization */ - SDL_GpuFence *fences[MAX_FRAMES_IN_FLIGHT]; + SDL_GpuFence **fenceGroups[MAX_FRAMES_IN_FLIGHT]; uint8_t frameCounter; /* RT tracking to reduce unnecessary cycling */ @@ -726,23 +726,23 @@ static void SDLGPU_INTERNAL_EndRenderPass( renderer->needNewGraphicsPipeline = 1; } -static SDL_GpuFence* SDLGPU_INTERNAL_FlushCommandsAndAcquireFence( - SDLGPU_Renderer *renderer +static void SDLGPU_INTERNAL_FlushCommandsAndAcquireFence( + SDLGPU_Renderer *renderer, + SDL_GpuFence **uploadFence, + SDL_GpuFence **renderFence ) { - SDL_GpuFence *fence; - SDLGPU_INTERNAL_EndCopyPass(renderer); SDLGPU_INTERNAL_EndRenderPass(renderer); - SDL_GpuSubmit(renderer->uploadCommandBuffer); + *uploadFence = SDL_GpuSubmitAndAcquireFence( + renderer->uploadCommandBuffer + ); - fence = SDL_GpuSubmitAndAcquireFence( + *renderFence = SDL_GpuSubmitAndAcquireFence( renderer->renderCommandBuffer ); SDLGPU_ResetCommandBufferState(renderer); - - return fence; } static void SDLGPU_INTERNAL_FlushCommands( @@ -758,20 +758,29 @@ static void SDLGPU_INTERNAL_FlushCommands( static void SDLGPU_INTERNAL_FlushCommandsAndStall( SDLGPU_Renderer *renderer ) { - SDL_GpuFence *fence = SDLGPU_INTERNAL_FlushCommandsAndAcquireFence( - renderer + SDL_GpuFence* fences[2]; + + SDLGPU_INTERNAL_FlushCommandsAndAcquireFence( + renderer, + &fences[0], + &fences[1] ); SDL_GpuWaitForFences( renderer->device, 1, - 1, - &fence + 2, + fences + ); + + SDL_GpuReleaseFence( + renderer->device, + fences[0] ); SDL_GpuReleaseFence( renderer->device, - fence + fences[1] ); } @@ -791,22 +800,28 @@ static void SDLGPU_SwapBuffers( SDLGPU_INTERNAL_EndCopyPass(renderer); SDLGPU_INTERNAL_EndRenderPass(renderer); - if (renderer->fences[renderer->frameCounter] != NULL) + if (renderer->fenceGroups[renderer->frameCounter][0] != NULL) { /* Wait for the least-recent fence */ SDL_GpuWaitForFences( renderer->device, 1, - 1, - &renderer->fences[renderer->frameCounter] + 2, + renderer->fenceGroups[renderer->frameCounter] + ); + + SDL_GpuReleaseFence( + renderer->device, + renderer->fenceGroups[renderer->frameCounter][0] ); SDL_GpuReleaseFence( renderer->device, - renderer->fences[renderer->frameCounter] + renderer->fenceGroups[renderer->frameCounter][1] ); - renderer->fences[renderer->frameCounter] = NULL; + renderer->fenceGroups[renderer->frameCounter][0] = NULL; + renderer->fenceGroups[renderer->frameCounter][1] = NULL; } swapchainTexture = SDL_GpuAcquireSwapchainTexture( @@ -847,8 +862,11 @@ static void SDLGPU_SwapBuffers( ); } - renderer->fences[renderer->frameCounter] = - SDLGPU_INTERNAL_FlushCommandsAndAcquireFence(renderer); + SDLGPU_INTERNAL_FlushCommandsAndAcquireFence( + renderer, + &renderer->fenceGroups[renderer->frameCounter][0], + &renderer->fenceGroups[renderer->frameCounter][1] + ); renderer->frameCounter = (renderer->frameCounter + 1) % MAX_FRAMES_IN_FLIGHT; @@ -969,6 +987,7 @@ static void SDLGPU_INTERNAL_BeginRenderPass( ) { SDL_GpuColorAttachmentInfo colorAttachmentInfos[MAX_RENDERTARGET_BINDINGS]; SDL_GpuDepthStencilAttachmentInfo depthStencilAttachmentInfo; + SDL_GpuViewport gpuViewport; uint32_t i; if (!renderer->needNewRenderPass) @@ -1070,6 +1089,23 @@ static void SDLGPU_INTERNAL_BeginRenderPass( renderer->nextRenderPassDepthStencilAttachment != NULL ? &depthStencilAttachmentInfo : NULL ); + gpuViewport.x = (float) renderer->viewport.x; + gpuViewport.y = (float) renderer->viewport.y; + gpuViewport.w = (float) renderer->viewport.w; + gpuViewport.h = (float) renderer->viewport.h; + gpuViewport.minDepth = renderer->viewport.minDepth; + gpuViewport.maxDepth = renderer->viewport.maxDepth; + + SDL_GpuSetViewport( + renderer->renderPass, + &gpuViewport + ); + + SDL_GpuSetScissor( + renderer->renderPass, + &renderer->scissorRect + ); + renderer->needNewRenderPass = 0; renderer->shouldClearColorOnBeginPass = 0; @@ -1859,17 +1895,20 @@ static void SDLGPU_SetViewport( { renderer->viewport = *viewport; - gpuViewport.x = (float) viewport->x; - gpuViewport.y = (float) viewport->y; - gpuViewport.w = (float) viewport->w; - gpuViewport.h = (float) viewport->h; - gpuViewport.minDepth = viewport->minDepth; - gpuViewport.maxDepth = viewport->maxDepth; - - SDL_GpuSetViewport( - renderer->renderPass, - &gpuViewport - ); + if (renderer->renderPassInProgress) + { + gpuViewport.x = (float) viewport->x; + gpuViewport.y = (float) viewport->y; + gpuViewport.w = (float) viewport->w; + gpuViewport.h = (float) viewport->h; + gpuViewport.minDepth = viewport->minDepth; + gpuViewport.maxDepth = viewport->maxDepth; + + SDL_GpuSetViewport( + renderer->renderPass, + &gpuViewport + ); + } } } @@ -1884,10 +1923,13 @@ static void SDLGPU_SetScissorRect( renderer->scissorRect.w = scissor->w; renderer->scissorRect.h = scissor->h; - SDL_GpuSetScissor( - renderer->renderPass, - &renderer->scissorRect - ); + if (renderer->renderPassInProgress) + { + SDL_GpuSetScissor( + renderer->renderPass, + &renderer->scissorRect + ); + } } static void SDLGPU_GetBlendFactor( @@ -2040,10 +2082,14 @@ static void SDLGPU_ApplyRasterizerState( if (rasterizerState->scissorTestEnable != renderer->fnaRasterizerState.scissorTestEnable) { renderer->fnaRasterizerState.scissorTestEnable = rasterizerState->scissorTestEnable; - SDL_GpuSetScissor( - renderer->renderPass, - &renderer->scissorRect - ); + + if (renderer->renderPassInProgress) + { + SDL_GpuSetScissor( + renderer->renderPass, + &renderer->scissorRect + ); + } } realDepthBias = rasterizerState->depthBias * XNAToSDL_DepthBiasScale( @@ -2719,6 +2765,7 @@ static void SDLGPU_INTERNAL_SetTextureData( { /* We already cycled too much, time to stall! */ SDLGPU_INTERNAL_FlushCommandsAndStall(renderer); + SDLGPU_INTERNAL_BeginCopyPass(renderer); cycle = SDL_TRUE; transferOffset = 0; } @@ -3897,13 +3944,23 @@ static void SDLGPU_DestroyDevice(FNA3D_Device *device) for (i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) { - if (renderer->fences[i] != NULL) + if (renderer->fenceGroups[i][0] != NULL) + { + SDL_GpuReleaseFence( + renderer->device, + renderer->fenceGroups[i][0] + ); + } + + if (renderer->fenceGroups[i][1] != NULL) { SDL_GpuReleaseFence( renderer->device, - renderer->fences[i] + renderer->fenceGroups[i][1] ); } + + SDL_free(renderer->fenceGroups[i]); } for (i = 0; i < NUM_PIPELINE_HASH_BUCKETS; i += 1) @@ -4249,6 +4306,13 @@ static FNA3D_Device* SDLGPU_CreateDevice( ); } + for (i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) + { + renderer->fenceGroups[i] = SDL_malloc(2 * sizeof(SDL_GpuFence*)); + renderer->fenceGroups[i][0] = NULL; + renderer->fenceGroups[i][1] = NULL; + } + return result; }