revise fence usage
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/pr Build is passing Details

pull/1/head
cosmonaut 2022-01-12 14:22:50 -08:00
parent 4ad948aba4
commit 5df612f7b1
1 changed files with 154 additions and 48 deletions

View File

@ -1352,11 +1352,18 @@ typedef struct VulkanRenderer
VkQueue computeQueue;
VkQueue transferQueue;
VkFence inFlightFence;
VkSemaphore transferFinishedSemaphore;
VkSemaphore imageAvailableSemaphore;
VkSemaphore renderFinishedSemaphore;
VkFence *availableFences;
uint32_t availableFenceCount;
uint32_t availableFenceCapacity;
VkFence *usedFences;
uint32_t usedFenceCount;
uint32_t usedFenceCapacity;
VulkanCommandBuffer **submittedCommandBuffers;
uint32_t submittedCommandBufferCount;
uint32_t submittedCommandBufferCapacity;
@ -1403,6 +1410,7 @@ typedef struct VulkanRenderer
SDL_mutex *allocatorLock;
SDL_mutex *disposeLock;
SDL_mutex *boundBufferLock;
SDL_mutex *submitLock;
/* Deferred destroy storage */
@ -4522,11 +4530,23 @@ static void VULKAN_DestroyDevice(
NULL
);
renderer->vkDestroyFence(
renderer->logicalDevice,
renderer->inFlightFence,
NULL
);
for (i = 0; i < renderer->availableFenceCount; i += 1)
{
renderer->vkDestroyFence(
renderer->logicalDevice,
renderer->availableFences[i],
NULL
);
}
for (i = 0; i < renderer->usedFenceCount; i += 1)
{
renderer->vkDestroyFence(
renderer->logicalDevice,
renderer->usedFences[i],
NULL
);
}
for (i = 0; i < NUM_COMMAND_POOL_BUCKETS; i += 1)
{
@ -4707,6 +4727,7 @@ static void VULKAN_DestroyDevice(
SDL_DestroyMutex(renderer->allocatorLock);
SDL_DestroyMutex(renderer->disposeLock);
SDL_DestroyMutex(renderer->boundBufferLock);
SDL_DestroyMutex(renderer->submitLock);
SDL_free(renderer->buffersInUse);
@ -8436,6 +8457,103 @@ static void VULKAN_INTERNAL_ResetCommandBuffer(
commandPool->inactiveCommandBufferCount += 1;
}
/* Fence management */
static VkFence VULKAN_INTERNAL_AcquireFence(
VulkanRenderer *renderer
) {
VkFenceCreateInfo fenceCreateInfo;
VkFence fence;
VkResult fenceCreateResult;
if (renderer->availableFenceCount == 0)
{
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceCreateInfo.pNext = NULL;
fenceCreateInfo.flags = 0;
fenceCreateResult = renderer->vkCreateFence(
renderer->logicalDevice,
&fenceCreateInfo,
NULL,
&renderer->availableFences[0]
);
if (fenceCreateResult != VK_SUCCESS)
{
LogVulkanResultAsError("vkCreateFence", fenceCreateResult);
return VK_NULL_HANDLE;
}
renderer->availableFenceCount += 1;
}
fence = renderer->availableFences[renderer->availableFenceCount - 1];
renderer->availableFenceCount -= 1;
if (renderer->usedFenceCount >= renderer->usedFenceCapacity)
{
renderer->usedFenceCapacity *= 2;
renderer->usedFences = SDL_realloc(
renderer->usedFences,
renderer->usedFenceCapacity * sizeof(VkFence)
);
}
renderer->usedFences[renderer->usedFenceCount] = fence;
renderer->usedFenceCount += 1;
return fence;
}
static void VULKAN_INTERNAL_ResetUsedFences(
VulkanRenderer *renderer
) {
uint32_t i;
/* Prepare the command buffer fence for submission */
renderer->vkResetFences(
renderer->logicalDevice,
renderer->usedFenceCount,
renderer->usedFences
);
/* Used fences are now available */
if (renderer->usedFenceCount + renderer->availableFenceCount >= renderer->availableFenceCapacity)
{
renderer->availableFenceCapacity = renderer->usedFenceCount + renderer->availableFenceCount;
renderer->availableFences = SDL_realloc(
renderer->availableFences,
renderer->availableFenceCapacity * sizeof(VkFence)
);
}
for (i = 0; i < renderer->usedFenceCount; i += 1)
{
renderer->availableFences[renderer->availableFenceCount] = renderer->usedFences[i];
renderer->availableFenceCount += 1;
}
renderer->usedFenceCount = 0;
}
/* Submission structure */
static void VULKAN_Wait(
Refresh_Renderer *driverData
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
renderer->vkWaitForFences(
renderer->logicalDevice,
renderer->usedFenceCount,
renderer->usedFences,
VK_TRUE,
UINT64_MAX
);
VULKAN_INTERNAL_ResetUsedFences(renderer);
}
static void VULKAN_Submit(
Refresh_Renderer *driverData,
uint32_t commandBufferCount,
@ -8448,12 +8566,15 @@ static void VULKAN_Submit(
VkCommandBuffer *commandBuffers;
uint32_t i;
uint8_t present = 0;
VkFence fence;
VkPipelineStageFlags waitStages[2];
VkSemaphore waitSemaphores[2];
uint32_t waitSemaphoreCount = 0;
VkPresentInfoKHR presentInfo;
SDL_LockMutex(renderer->submitLock);
commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount);
for (i = 0; i < commandBufferCount; i += 1)
@ -8496,8 +8617,8 @@ static void VULKAN_Submit(
/* Wait for the previous submission to complete */
vulkanResult = renderer->vkWaitForFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence,
renderer->usedFenceCount,
renderer->usedFences,
VK_TRUE,
UINT64_MAX
);
@ -8523,12 +8644,16 @@ static void VULKAN_Submit(
}
renderer->submittedCommandBufferCount = 0;
/* Prepare the command buffer fence for submission */
renderer->vkResetFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence
);
VULKAN_INTERNAL_ResetUsedFences(renderer);
}
/* Acquire a fence */
fence = VULKAN_INTERNAL_AcquireFence(renderer);
if (fence == VK_NULL_HANDLE)
{
Refresh_LogError("Failed to acquire fence!");
return;
}
/* Submit the commands, finally. */
@ -8536,7 +8661,7 @@ static void VULKAN_Submit(
renderer->graphicsQueue,
1,
&submitInfo,
present ? renderer->inFlightFence : VK_NULL_HANDLE
fence
);
if (vulkanResult != VK_SUCCESS)
@ -8590,20 +8715,8 @@ static void VULKAN_Submit(
renderer->swapChainImageAcquired = 0;
SDL_stack_free(commandBuffers);
}
static void VULKAN_Wait(
Refresh_Renderer *driverData
) {
VulkanRenderer *renderer = (VulkanRenderer*) driverData;
renderer->vkWaitForFences(
renderer->logicalDevice,
1,
&renderer->inFlightFence,
VK_TRUE,
UINT64_MAX
);
SDL_UnlockMutex(renderer->submitLock);
}
/* External interop */
@ -9291,8 +9404,7 @@ static Refresh_Device* VULKAN_INTERNAL_CreateDevice(
VkResult vulkanResult;
uint32_t i;
/* Variables: Create fence and semaphores */
VkFenceCreateInfo fenceInfo;
/* Variables: Create semaphores */
VkSemaphoreCreateInfo semaphoreInfo;
/* Variables: Descriptor set layouts */
@ -9333,13 +9445,9 @@ static Refresh_Device* VULKAN_INTERNAL_CreateDevice(
renderer->swapChainImageAcquired = 0;
/*
* Create fence and semaphores
* Create semaphores
*/
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.pNext = NULL;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
semaphoreInfo.pNext = NULL;
semaphoreInfo.flags = 0;
@ -9383,24 +9491,22 @@ static Refresh_Device* VULKAN_INTERNAL_CreateDevice(
return NULL;
}
vulkanResult = renderer->vkCreateFence(
renderer->logicalDevice,
&fenceInfo,
NULL,
&renderer->inFlightFence
);
if (vulkanResult != VK_SUCCESS)
{
LogVulkanResultAsError("vkCreateFence", vulkanResult);
return NULL;
}
/* Threading */
renderer->allocatorLock = SDL_CreateMutex();
renderer->disposeLock = SDL_CreateMutex();
renderer->boundBufferLock = SDL_CreateMutex();
renderer->submitLock = SDL_CreateMutex();
/* Create fence lists */
renderer->availableFenceCount = 0;
renderer->availableFenceCapacity = 4;
renderer->availableFences = SDL_malloc(renderer->availableFenceCapacity * sizeof(VkFence));
renderer->usedFenceCount = 0;
renderer->usedFenceCapacity = 4;
renderer->usedFences = SDL_malloc(renderer->usedFenceCapacity * sizeof(VkFence));
/*
* Create submitted command buffer list