Clean up fence logic

d3d11
Caleb Cornett 2024-02-08 23:59:13 -06:00 committed by cosmonaut
parent 155d01ed92
commit 105ef1aebb
1 changed files with 49 additions and 42 deletions

View File

@ -521,7 +521,7 @@ typedef struct D3D11Renderer
SDL_mutex *contextLock; SDL_mutex *contextLock;
SDL_mutex *acquireCommandBufferLock; SDL_mutex *acquireCommandBufferLock;
SDL_mutex *uniformBufferLock; SDL_mutex *uniformBufferLock;
SDL_mutex *acquireFenceLock; SDL_mutex *fenceLock;
} D3D11Renderer; } D3D11Renderer;
/* Logging */ /* Logging */
@ -652,7 +652,7 @@ static void D3D11_DestroyDevice(
SDL_DestroyMutex(renderer->acquireCommandBufferLock); SDL_DestroyMutex(renderer->acquireCommandBufferLock);
SDL_DestroyMutex(renderer->contextLock); SDL_DestroyMutex(renderer->contextLock);
SDL_DestroyMutex(renderer->uniformBufferLock); SDL_DestroyMutex(renderer->uniformBufferLock);
SDL_DestroyMutex(renderer->acquireFenceLock); SDL_DestroyMutex(renderer->fenceLock);
/* Release the device and associated objects */ /* Release the device and associated objects */
ID3D11DeviceContext_Release(renderer->immediateContext); ID3D11DeviceContext_Release(renderer->immediateContext);
@ -2267,57 +2267,71 @@ static D3D11CommandBuffer* D3D11_INTERNAL_GetInactiveCommandBufferFromPool(
return commandBuffer; return commandBuffer;
} }
static void D3D11_INTERNAL_AllocateFences( static uint8_t D3D11_INTERNAL_CreateFence(
D3D11Renderer *renderer, D3D11Renderer *renderer
uint32_t allocateCount
) { ) {
D3D11Fence *fence;
D3D11_QUERY_DESC queryDesc; D3D11_QUERY_DESC queryDesc;
ID3D11Query *queryHandle;
D3D11Fence* fence;
HRESULT res; HRESULT res;
renderer->availableFenceCapacity += allocateCount; queryDesc.Query = D3D11_QUERY_EVENT;
queryDesc.MiscFlags = 0;
renderer->availableFences = SDL_realloc( res = ID3D11Device_CreateQuery(
renderer->availableFences, renderer->device,
sizeof(D3D11Fence*) * renderer->availableFenceCapacity &queryDesc,
&queryHandle
); );
ERROR_CHECK_RETURN("Could not create query", 0);
for (uint32_t i = 0; i < allocateCount; i += 1) fence = SDL_malloc(sizeof(D3D11Fence));
fence->handle = queryHandle;
/* Add it to the available pool */
if (renderer->availableFenceCount >= renderer->availableFenceCapacity)
{ {
fence = SDL_malloc(sizeof(D3D11Fence)); renderer->availableFenceCapacity *= 2;
queryDesc.Query = D3D11_QUERY_EVENT; renderer->availableFences = SDL_realloc(
queryDesc.MiscFlags = 0; renderer->availableFences,
res = ID3D11Device_CreateQuery( sizeof(D3D11Fence*) * renderer->availableFenceCapacity
renderer->device,
&queryDesc,
&fence->handle
); );
ERROR_CHECK("Could not create query"); /* FIXME: Should this return an error code? */
renderer->availableFences[renderer->availableFenceCount] = fence;
renderer->availableFenceCount += 1;
} }
renderer->availableFences[renderer->availableFenceCount] = fence;
renderer->availableFenceCount += 1;
return 1;
} }
static D3D11Fence* D3D11_INTERNAL_GetFenceFromPool( static uint8_t D3D11_INTERNAL_AcquireFence(
D3D11Renderer* renderer D3D11Renderer *renderer,
D3D11CommandBuffer *commandBuffer
) { ) {
D3D11Fence *fence; D3D11Fence *fence;
SDL_LockMutex(renderer->acquireFenceLock); /* Acquire a fence from the pool */
SDL_LockMutex(renderer->fenceLock);
if (renderer->availableFenceCount == 0) if (renderer->availableFenceCount == 0)
{ {
D3D11_INTERNAL_AllocateFences(renderer, renderer->availableFenceCapacity); if (!D3D11_INTERNAL_CreateFence(renderer))
{
SDL_UnlockMutex(renderer->fenceLock);
Refresh_LogError("Failed to create fence!");
return 0;
}
} }
fence = renderer->availableFences[renderer->availableFenceCount - 1]; fence = renderer->availableFences[renderer->availableFenceCount - 1];
renderer->availableFenceCount -= 1; renderer->availableFenceCount -= 1;
SDL_UnlockMutex(renderer->acquireFenceLock); SDL_UnlockMutex(renderer->fenceLock);
return fence; /* Associate the fence with the command buffer */
commandBuffer->fence = fence;
return 1;
} }
static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer( static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
@ -2344,9 +2358,7 @@ static Refresh_CommandBuffer* D3D11_AcquireCommandBuffer(
commandBuffer->rtViews[i] = NULL; commandBuffer->rtViews[i] = NULL;
} }
SDL_LockMutex(renderer->acquireFenceLock); D3D11_INTERNAL_AcquireFence(renderer, commandBuffer);
commandBuffer->fence = D3D11_INTERNAL_GetFenceFromPool(renderer);
SDL_UnlockMutex(renderer->acquireFenceLock);
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
@ -3121,8 +3133,6 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
D3D11Renderer *renderer, D3D11Renderer *renderer,
D3D11CommandBuffer *commandBuffer D3D11CommandBuffer *commandBuffer
) { ) {
/* FIXME: All kinds of stuff should go here... */
/* Bound uniform buffers are now available */ /* Bound uniform buffers are now available */
SDL_LockMutex(renderer->uniformBufferLock); SDL_LockMutex(renderer->uniformBufferLock);
for (uint32_t i = 0; i < commandBuffer->boundUniformBufferCount; i += 1) for (uint32_t i = 0; i < commandBuffer->boundUniformBufferCount; i += 1)
@ -3145,7 +3155,7 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
/* The fence is now available */ /* The fence is now available */
/* FIXME: Not if auto-release is false! */ /* FIXME: Not if auto-release is false! */
SDL_LockMutex(renderer->acquireFenceLock); SDL_LockMutex(renderer->fenceLock);
if (renderer->availableFenceCount == renderer->availableFenceCapacity) if (renderer->availableFenceCount == renderer->availableFenceCapacity)
{ {
renderer->availableFenceCapacity *= 2; renderer->availableFenceCapacity *= 2;
@ -3154,14 +3164,12 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
renderer->availableFenceCapacity * sizeof(D3D11Fence*) renderer->availableFenceCapacity * sizeof(D3D11Fence*)
); );
} }
renderer->availableFences[renderer->availableFenceCount] = commandBuffer->fence; renderer->availableFences[renderer->availableFenceCount] = commandBuffer->fence;
renderer->availableFenceCount += 1; renderer->availableFenceCount += 1;
SDL_UnlockMutex(renderer->acquireFenceLock); SDL_UnlockMutex(renderer->fenceLock);
/* Return command buffer to pool */ /* Return command buffer to pool */
SDL_LockMutex(renderer->acquireCommandBufferLock); SDL_LockMutex(renderer->acquireCommandBufferLock);
if (renderer->availableCommandBufferCount == renderer->availableCommandBufferCapacity) if (renderer->availableCommandBufferCount == renderer->availableCommandBufferCapacity)
{ {
renderer->availableCommandBufferCapacity += 1; renderer->availableCommandBufferCapacity += 1;
@ -3170,10 +3178,8 @@ static void D3D11_INTERNAL_CleanCommandBuffer(
renderer->availableCommandBufferCapacity * sizeof(D3D11CommandBuffer*) renderer->availableCommandBufferCapacity * sizeof(D3D11CommandBuffer*)
); );
} }
renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer; renderer->availableCommandBuffers[renderer->availableCommandBufferCount] = commandBuffer;
renderer->availableCommandBufferCount += 1; renderer->availableCommandBufferCount += 1;
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
/* Remove this command buffer from the submitted list */ /* Remove this command buffer from the submitted list */
@ -3661,7 +3667,7 @@ tryCreateDevice:
renderer->contextLock = SDL_CreateMutex(); renderer->contextLock = SDL_CreateMutex();
renderer->acquireCommandBufferLock = SDL_CreateMutex(); renderer->acquireCommandBufferLock = SDL_CreateMutex();
renderer->uniformBufferLock = SDL_CreateMutex(); renderer->uniformBufferLock = SDL_CreateMutex();
renderer->acquireFenceLock = SDL_CreateMutex(); renderer->fenceLock = SDL_CreateMutex();
/* Initialize miscellaneous renderer members */ /* Initialize miscellaneous renderer members */
renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG); renderer->debugMode = (flags & D3D11_CREATE_DEVICE_DEBUG);
@ -3674,7 +3680,8 @@ tryCreateDevice:
renderer->availableUniformBuffers = SDL_malloc(sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity); renderer->availableUniformBuffers = SDL_malloc(sizeof(D3D11UniformBuffer*) * renderer->availableUniformBufferCapacity);
/* Create fence pool */ /* Create fence pool */
D3D11_INTERNAL_AllocateFences(renderer, 2); renderer->availableFenceCapacity = 2;
renderer->availableFences = SDL_malloc(sizeof(D3D11Fence*) * renderer->availableFenceCapacity);
/* Create the Refresh Device */ /* Create the Refresh Device */
result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device)); result = (Refresh_Device*) SDL_malloc(sizeof(Refresh_Device));