From 7f11d209410c64b7dc54686c58222ffb605fcb17 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 18 Sep 2023 23:07:18 -0700 Subject: [PATCH] fence autorelease during command buffer clean --- src/Refresh_Driver_Vulkan.c | 176 ++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 90 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 5855c69..a3864b1 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -9934,6 +9934,77 @@ static void VULKAN_SetSwapchainPresentMode( /* Submission structure */ +static VkFence VULKAN_INTERNAL_AcquireFenceFromPool( + VulkanRenderer *renderer +) { + VkFenceCreateInfo fenceCreateInfo; + VkFence fence; + VkResult vulkanResult; + + if (renderer->fencePool.availableFenceCount == 0) + { + /* Create fence */ + fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceCreateInfo.pNext = NULL; + fenceCreateInfo.flags = 0; + + vulkanResult = renderer->vkCreateFence( + renderer->logicalDevice, + &fenceCreateInfo, + NULL, + &fence + ); + + if (vulkanResult != VK_SUCCESS) + { + LogVulkanResultAsError("vkCreateFence", vulkanResult); + return NULL; + } + + return fence; + } + + SDL_LockMutex(renderer->fencePool.lock); + + fence = renderer->fencePool.availableFences[renderer->fencePool.availableFenceCount - 1]; + renderer->fencePool.availableFenceCount -= 1; + + vulkanResult = renderer->vkResetFences( + renderer->logicalDevice, + 1, + &fence + ); + + if (vulkanResult != VK_SUCCESS) + { + LogVulkanResultAsError("vkResetFences", vulkanResult); + } + + SDL_UnlockMutex(renderer->fencePool.lock); + + return fence; +} + +static void VULKAN_INTERNAL_ReturnFenceToPool( + VulkanRenderer *renderer, + VkFence fence +) { + SDL_LockMutex(renderer->fencePool.lock); + + EXPAND_ARRAY_IF_NEEDED( + renderer->fencePool.availableFences, + VkFence, + renderer->fencePool.availableFenceCount + 1, + renderer->fencePool.availableFenceCapacity, + renderer->fencePool.availableFenceCapacity * 2 + ); + + renderer->fencePool.availableFences[renderer->fencePool.availableFenceCount] = fence; + renderer->fencePool.availableFenceCount += 1; + + SDL_UnlockMutex(renderer->fencePool.lock); +} + static void VULKAN_INTERNAL_PerformPendingDestroys( VulkanRenderer *renderer ) { @@ -10049,6 +10120,16 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( VulkanUniformBuffer *uniformBuffer; DescriptorSetData *descriptorSetData; + if (commandBuffer->autoReleaseFence) + { + VULKAN_INTERNAL_ReturnFenceToPool( + renderer, + commandBuffer->inFlightFence + ); + + commandBuffer->inFlightFence = VK_NULL_HANDLE; + } + /* Bound uniform buffers are now available */ for (i = 0; i < commandBuffer->boundUniformBufferCount; i += 1) @@ -10204,27 +10285,15 @@ static void VULKAN_Wait( VkResult result; int32_t i; - SDL_LockMutex(renderer->submitLock); + result = renderer->vkDeviceWaitIdle(renderer->logicalDevice); - for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) + if (result != VK_SUCCESS) { - commandBuffer = renderer->submittedCommandBuffers[i]; - - result = renderer->vkWaitForFences( - renderer->logicalDevice, - 1, - &commandBuffer->inFlightFence, - VK_TRUE, - UINT64_MAX - ); - - if (result != VK_SUCCESS) - { - LogVulkanResultAsError("vkWaitForFences", result); - } + LogVulkanResultAsError("vkDeviceWaitIdle", result); + return; } - /* TODO: consider if it's not a good idea to do cleanup here */ + SDL_LockMutex(renderer->submitLock); for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) { @@ -10237,69 +10306,6 @@ static void VULKAN_Wait( SDL_UnlockMutex(renderer->submitLock); } -static VkFence VULKAN_INTERNAL_AcquireFenceFromPool( - VulkanRenderer *renderer -) { - VkFenceCreateInfo fenceCreateInfo; - VkFence fence; - VkResult vulkanResult; - - if (renderer->fencePool.availableFenceCount == 0) - { - /* Create fence */ - fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fenceCreateInfo.pNext = NULL; - fenceCreateInfo.flags = 0; - - vulkanResult = renderer->vkCreateFence( - renderer->logicalDevice, - &fenceCreateInfo, - NULL, - &fence - ); - - if (vulkanResult != VK_SUCCESS) - { - LogVulkanResultAsError("vkCreateFence", vulkanResult); - return NULL; - } - - return fence; - } - - fence = renderer->fencePool.availableFences[renderer->fencePool.availableFenceCount - 1]; - renderer->fencePool.availableFenceCount -= 1; - - vulkanResult = renderer->vkResetFences( - renderer->logicalDevice, - 1, - &fence - ); - - if (vulkanResult != VK_SUCCESS) - { - LogVulkanResultAsError("vkResetFences", vulkanResult); - } - - return fence; -} - -static void VULKAN_INTERNAL_ReturnFenceToPool( - VulkanRenderer *renderer, - VkFence fence -) { - EXPAND_ARRAY_IF_NEEDED( - renderer->fencePool.availableFences, - VkFence, - renderer->fencePool.availableFenceCount + 1, - renderer->fencePool.availableFenceCapacity, - renderer->fencePool.availableFenceCapacity * 2 - ); - - renderer->fencePool.availableFences[renderer->fencePool.availableFenceCount] = fence; - renderer->fencePool.availableFenceCount += 1; -} - static Refresh_Fence* VULKAN_SubmitAndAcquireFence( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer @@ -10442,16 +10448,6 @@ static void VULKAN_Submit( if (vulkanResult == VK_SUCCESS) { - if (renderer->submittedCommandBuffers[i]->autoReleaseFence) - { - VULKAN_INTERNAL_ReturnFenceToPool( - renderer, - renderer->submittedCommandBuffers[i]->inFlightFence - ); - - renderer->submittedCommandBuffers[i]->inFlightFence = VK_NULL_HANDLE; - } - VULKAN_INTERNAL_CleanCommandBuffer( renderer, renderer->submittedCommandBuffers[i]