From bb948846c01376f99111154cdbfb8f9a796f3877 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Fri, 18 Feb 2022 22:22:45 -0800 Subject: [PATCH] memory fixes --- src/Refresh_Driver_Vulkan.c | 114 ++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 49 deletions(-) diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index a2e1a74..b69fb9c 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -1447,6 +1447,7 @@ typedef struct VulkanRenderer /* Forward declarations */ static void VULKAN_INTERNAL_BeginCommandBuffer(VulkanRenderer *renderer, VulkanCommandBuffer *commandBuffer); +static void VULKAN_Wait(Refresh_Renderer *driverData); static void VULKAN_Submit(Refresh_Renderer *driverData, uint32_t commandBufferCount, Refresh_CommandBuffer **pCommandBuffers); /* Error Handling */ @@ -3617,6 +3618,7 @@ static void VULKAN_INTERNAL_DeactivateUnusedImageDescriptorSets( } } +/* FIXME: get rid of descriptor set caching */ static void VULKAN_INTERNAL_ResetDescriptorSetData(VulkanRenderer* renderer) { uint32_t i, j; @@ -3665,18 +3667,13 @@ static void VULKAN_INTERNAL_ResetDescriptorSetData(VulkanRenderer* renderer) } } -static void VULKAN_INTERNAL_PostWorkCleanup(VulkanRenderer* renderer) -{ - /* Reset descriptor set data */ - VULKAN_INTERNAL_ResetDescriptorSetData(renderer); -} - /* Swapchain */ static uint8_t VULKAN_INTERNAL_QuerySwapChainSupport( VulkanRenderer *renderer, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, + uint32_t graphicsFamilyIndex, SwapChainSupportDetails *outputDetails ) { VkResult result; @@ -3684,17 +3681,20 @@ static uint8_t VULKAN_INTERNAL_QuerySwapChainSupport( uint32_t presentModeCount; VkBool32 supportsPresent; - renderer->vkGetPhysicalDeviceSurfaceSupportKHR( - physicalDevice, - renderer->queueFamilyIndices.graphicsFamily, - surface, - &supportsPresent - ); - - if (!supportsPresent) + if (graphicsFamilyIndex != UINT32_MAX) { - Refresh_LogWarn("This surface does not support presenting!"); - return 0; + renderer->vkGetPhysicalDeviceSurfaceSupportKHR( + physicalDevice, + graphicsFamilyIndex, + surface, + &supportsPresent + ); + + if (!supportsPresent) + { + Refresh_LogWarn("This surface does not support presenting!"); + return 0; + } } result = renderer->vkGetPhysicalDeviceSurfaceCapabilitiesKHR( @@ -3899,6 +3899,7 @@ static CreateSwapchainResult VULKAN_INTERNAL_CreateSwapchain( renderer, renderer->physicalDevice, swapchainData->surface, + renderer->queueFamilyIndices.graphicsFamily, &swapchainSupportDetails )) { renderer->vkDestroySurfaceKHR( @@ -4335,23 +4336,13 @@ static void VULKAN_DestroyDevice( Refresh_Device *device ) { VulkanRenderer* renderer = (VulkanRenderer*) device->driverData; - VkResult waitResult; CommandPoolHashArray commandPoolHashArray; GraphicsPipelineLayoutHashArray graphicsPipelineLayoutHashArray; ComputePipelineLayoutHashArray computePipelineLayoutHashArray; VulkanMemorySubAllocator *allocator; uint32_t i, j, k; - waitResult = renderer->vkDeviceWaitIdle(renderer->logicalDevice); - - if (waitResult != VK_SUCCESS) - { - LogVulkanResultAsError("vkDeviceWaitIdle", waitResult); - } - - /* We have to do this twice so the rotation happens correctly */ - VULKAN_INTERNAL_PostWorkCleanup(renderer); - VULKAN_INTERNAL_PostWorkCleanup(renderer); + VULKAN_Wait(device->driverData); VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyVertexUniformBuffer->vulkanBuffer); VULKAN_INTERNAL_DestroyBuffer(renderer, renderer->dummyFragmentUniformBuffer->vulkanBuffer); @@ -8617,6 +8608,29 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( SDL_UnlockMutex(renderer->acquireFenceLock); commandBuffer->inFlightFence = VK_NULL_HANDLE; + + /* Return this command buffer to its pool */ + for (i = 0; i < renderer->submittedCommandBufferCount; i += 1) + { + if (renderer->submittedCommandBuffers[i] == commandBuffer) + { + renderer->submittedCommandBuffers[i] = renderer->submittedCommandBuffers[renderer->submittedCommandBufferCount - 1]; + renderer->submittedCommandBufferCount -= 1; + + if (commandBuffer->commandPool->inactiveCommandBufferCount == commandBuffer->commandPool->inactiveCommandBufferCapacity) + { + commandBuffer->commandPool->inactiveCommandBufferCapacity += 1; + + commandBuffer->commandPool->inactiveCommandBuffers = SDL_realloc( + commandBuffer->commandPool->inactiveCommandBuffers, + commandBuffer->commandPool->inactiveCommandBufferCapacity * sizeof(VulkanCommandBuffer*) + ); + } + + commandBuffer->commandPool->inactiveCommandBuffers[commandBuffer->commandPool->inactiveCommandBufferCount] = commandBuffer; + commandBuffer->commandPool->inactiveCommandBufferCount += 1; + } + } } static void VULKAN_Wait( @@ -8669,27 +8683,6 @@ static void VULKAN_Submit( SDL_LockMutex(renderer->submitLock); - /* Check if we can perform any cleanups */ - for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) - { - /* If we set a timeout of 0, we can query the command buffer state */ - vulkanResult = renderer->vkWaitForFences( - renderer->logicalDevice, - 1, - &renderer->submittedCommandBuffers[i]->inFlightFence, - VK_TRUE, - 0 - ); - - if (vulkanResult == VK_SUCCESS) - { - VULKAN_INTERNAL_CleanCommandBuffer( - renderer, - renderer->submittedCommandBuffers[i] - ); - } - } - commandBuffers = SDL_stack_alloc(VkCommandBuffer, commandBufferCount); submitInfos = SDL_stack_alloc(VkSubmitInfo, commandBufferCount); @@ -8744,6 +8737,7 @@ static void VULKAN_Submit( } } + /* Wait for any previous submissions on swapchains */ for (i = 0; i < commandBufferCount; i += 1) { currentCommandBuffer = (VulkanCommandBuffer*)pCommandBuffers[i]; @@ -8754,7 +8748,7 @@ static void VULKAN_Submit( if (swapchainData->inFlightFence != VK_NULL_HANDLE) { - renderer->vkWaitForFences( + vulkanResult = renderer->vkWaitForFences( renderer->logicalDevice, 1, &swapchainData->inFlightFence, @@ -8774,6 +8768,27 @@ static void VULKAN_Submit( } } + /* Check if we can perform any cleanups */ + for (i = renderer->submittedCommandBufferCount - 1; i >= 0; i -= 1) + { + /* If we set a timeout of 0, we can query the command buffer state */ + vulkanResult = renderer->vkWaitForFences( + renderer->logicalDevice, + 1, + &renderer->submittedCommandBuffers[i]->inFlightFence, + VK_TRUE, + 0 + ); + + if (vulkanResult == VK_SUCCESS) + { + VULKAN_INTERNAL_CleanCommandBuffer( + renderer, + renderer->submittedCommandBuffers[i] + ); + } + } + /* Acquire a fence */ fence = VULKAN_INTERNAL_AcquireFence(renderer); @@ -9169,6 +9184,7 @@ static uint8_t VULKAN_INTERNAL_IsDeviceSuitable( renderer, physicalDevice, surface, + UINT32_MAX, &swapChainSupportDetails );