Fence API

d3d11
Caleb Cornett 2024-02-09 00:31:54 -06:00 committed by cosmonaut
parent 105ef1aebb
commit d76d223f68
1 changed files with 104 additions and 28 deletions

View File

@ -465,6 +465,7 @@ typedef struct D3D11CommandBuffer
/* State */ /* State */
SDL_threadID threadID; SDL_threadID threadID;
D3D11Fence *fence; D3D11Fence *fence;
uint8_t autoReleaseFence;
/* Uniforms */ /* Uniforms */
D3D11UniformBuffer *vertexUniformBuffer; D3D11UniformBuffer *vertexUniformBuffer;
@ -2359,6 +2360,7 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
} }
D3D11_INTERNAL_AcquireFence(renderer, commandBuffer); D3D11_INTERNAL_AcquireFence(renderer, commandBuffer);
commandBuffer->autoReleaseFence = 1;
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
@ -3129,6 +3131,26 @@ static void D3D11_SetSwapchainPresentMode(
/* Submission and Fences */ /* Submission and Fences */
static void D3D11_INTERNAL_ReleaseFenceToPool(
D3D11Renderer *renderer,
D3D11Fence *fence
) {
SDL_LockMutex(renderer->fenceLock);
if (renderer->availableFenceCount == renderer->availableFenceCapacity)
{
renderer->availableFenceCapacity *= 2;
renderer->availableFences = SDL_realloc(
renderer->availableFences,
renderer->availableFenceCapacity * sizeof(D3D11Fence*)
);
}
renderer->availableFences[renderer->availableFenceCount] = fence;
renderer->availableFenceCount += 1;
SDL_UnlockMutex(renderer->fenceLock);
}
static void D3D11_INTERNAL_CleanCommandBuffer( static void D3D11_INTERNAL_CleanCommandBuffer(
D3D11Renderer *renderer, D3D11Renderer *renderer,
D3D11CommandBuffer *commandBuffer D3D11CommandBuffer *commandBuffer
@ -3153,20 +3175,11 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
commandBuffer->boundUniformBufferCount = 0; commandBuffer->boundUniformBufferCount = 0;
/* The fence is now available */ /* The fence is now available (unless SubmitAndAcquireFence was called) */
/* FIXME: Not if auto-release is false! */ if (commandBuffer->autoReleaseFence)
SDL_LockMutex(renderer->fenceLock);
if (renderer->availableFenceCount == renderer->availableFenceCapacity)
{ {
renderer->availableFenceCapacity *= 2; D3D11_INTERNAL_ReleaseFenceToPool(renderer, commandBuffer->fence);
renderer->availableFences = SDL_realloc(
renderer->availableFences,
renderer->availableFenceCapacity * sizeof(D3D11Fence*)
);
} }
renderer->availableFences[renderer->availableFenceCount] = commandBuffer->fence;
renderer->availableFenceCount += 1;
SDL_UnlockMutex(renderer->fenceLock);
/* Return command buffer to pool */ /* Return command buffer to pool */
SDL_LockMutex(renderer->acquireCommandBufferLock); SDL_LockMutex(renderer->acquireCommandBufferLock);
@ -3193,6 +3206,23 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
} }
} }
static void D3D11_INTERNAL_WaitForFence(
D3D11Renderer *renderer,
D3D11Fence *fence
) {
BOOL queryData;
while (S_OK != ID3D11DeviceContext_GetData(
renderer->immediateContext,
(ID3D11Asynchronous*) fence->handle,
&queryData,
sizeof(queryData),
0
)) {
/* Spin until we get a result back... */
}
}
static void D3D11_Submit( static void D3D11_Submit(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer Refresh_CommandBuffer *commandBuffer
@ -3280,8 +3310,13 @@ static Refresh_Fence* D3D11_SubmitAndAcquireFence(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_CommandBuffer *commandBuffer Refresh_CommandBuffer *commandBuffer
) { ) {
NOT_IMPLEMENTED D3D11CommandBuffer *d3d11CommandBuffer = (D3D11CommandBuffer*) commandBuffer;
return NULL; D3D11Fence *fence = d3d11CommandBuffer->fence;
d3d11CommandBuffer->autoReleaseFence = 0;
D3D11_Submit(driverData, commandBuffer);
return (Refresh_Fence*) fence;
} }
static void D3D11_Wait( static void D3D11_Wait(
@ -3289,7 +3324,6 @@ static void D3D11_Wait(
) { ) {
D3D11Renderer *renderer = (D3D11Renderer*) driverData; D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11CommandBuffer *commandBuffer; D3D11CommandBuffer *commandBuffer;
BOOL queryData;
/* /*
* Wait for all submitted command buffers to complete. * Wait for all submitted command buffers to complete.
@ -3297,15 +3331,10 @@ static void D3D11_Wait(
*/ */
for (uint32_t i = 0; i < renderer->submittedCommandBufferCount; i += 1) for (uint32_t i = 0; i < renderer->submittedCommandBufferCount; i += 1)
{ {
while (S_OK != ID3D11DeviceContext_GetData( D3D11_INTERNAL_WaitForFence(
renderer->immediateContext, renderer,
(ID3D11Asynchronous*) renderer->submittedCommandBuffers[i]->fence->handle, renderer->submittedCommandBuffers[i]->fence
&queryData, );
sizeof(queryData),
0
)) {
/* Spin until we get a result back... */
}
} }
SDL_LockMutex(renderer->contextLock); SDL_LockMutex(renderer->contextLock);
@ -3325,22 +3354,69 @@ static void D3D11_WaitForFences(
uint32_t fenceCount, uint32_t fenceCount,
Refresh_Fence **pFences Refresh_Fence **pFences
) { ) {
NOT_IMPLEMENTED D3D11Renderer *renderer = (D3D11Renderer*) driverData;
D3D11Fence *fence;
BOOL queryData;
HRESULT res = S_FALSE;
if (waitAll)
{
for (uint32_t i = 0; i < fenceCount; i += 1)
{
fence = (D3D11Fence*) pFences[i];
D3D11_INTERNAL_WaitForFence(renderer, fence);
}
}
else
{
while (res != S_OK)
{
for (uint32_t i = 0; i < fenceCount; i += 1)
{
fence = (D3D11Fence*) pFences[i];
res = ID3D11DeviceContext_GetData(
renderer->immediateContext,
(ID3D11Asynchronous*) fence->handle,
&queryData,
sizeof(queryData),
0
);
if (res == S_OK)
{
break;
}
}
}
}
} }
static int D3D11_QueryFence( static int D3D11_QueryFence(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Fence *fence Refresh_Fence *fence
) { ) {
NOT_IMPLEMENTED D3D11Renderer *renderer = (D3D11Renderer*) driverData;
return 0; D3D11Fence *d3d11Fence = (D3D11Fence*) fence;
BOOL queryData;
HRESULT res = ID3D11DeviceContext_GetData(
renderer->immediateContext,
(ID3D11Asynchronous*) d3d11Fence->handle,
&queryData,
sizeof(queryData),
0
);
return res == S_OK;
} }
static void D3D11_ReleaseFence( static void D3D11_ReleaseFence(
Refresh_Renderer *driverData, Refresh_Renderer *driverData,
Refresh_Fence *fence Refresh_Fence *fence
) { ) {
NOT_IMPLEMENTED D3D11_INTERNAL_ReleaseFenceToPool(
(D3D11Renderer*) driverData,
(D3D11Fence*) fence
);
} }
/* Device Creation */ /* Device Creation */