revise fence usage
parent
4ad948aba4
commit
5df612f7b1
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue