Skip to content

Commit

Permalink
track upload and render fence, fix copy pass interrupt
Browse files Browse the repository at this point in the history
  • Loading branch information
thatcosmonaut committed May 9, 2024
1 parent 33dee20 commit cb65bb9
Showing 1 changed file with 106 additions and 42 deletions.
148 changes: 106 additions & 42 deletions src/FNA3D_Driver_SDL.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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(
Expand All @@ -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]
);
}

Expand All @@ -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(
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
);
}
}
}

Expand All @@ -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(
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit cb65bb9

Please sign in to comment.