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