diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index df1568c..fbc9f23 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -703,7 +703,6 @@ struct VulkanBuffer VkBufferUsageFlags usage; uint8_t preferDeviceLocal; - uint8_t isTransferBuffer; SDL_atomic_t referenceCount; /* Tracks command buffer usage */ @@ -3115,7 +3114,7 @@ static uint8_t VULKAN_INTERNAL_FindAllocationToDefragment( for (j = 0; j < allocator->allocationCount; j += 1) { - if (allocator->allocations[j]->freeRegionCount > 1) + if (allocator->allocations[j]->availableForAllocation == 1 && allocator->allocations[j]->freeRegionCount > 1) { *allocationIndexToDefrag = j; return 1; @@ -4118,7 +4117,6 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->resourceAccessType = resourceAccessType; buffer->usage = usage; buffer->preferDeviceLocal = preferDeviceLocal; - buffer->isTransferBuffer = isTransferBuffer; bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferCreateInfo.pNext = NULL; @@ -4142,7 +4140,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( buffer->buffer, buffer->size, buffer->preferDeviceLocal, - buffer->isTransferBuffer, + isTransferBuffer, &buffer->usedRegion ); @@ -4157,6 +4155,7 @@ static VulkanBuffer* VULKAN_INTERNAL_CreateBuffer( } buffer->usedRegion->vulkanBuffer = buffer; /* lol */ + buffer->container = NULL; buffer->resourceAccessType = resourceAccessType; @@ -5319,27 +5318,29 @@ static void VULKAN_DestroyDevice( { allocator = &renderer->memoryAllocator->subAllocators[i]; - for (j = 0; j < allocator->allocationCount; j += 1) + for (j = allocator->allocationCount - 1; j >= 0; j -= 1) { - for (k = 0; k < allocator->allocations[j]->freeRegionCount; k += 1) + for (k = allocator->allocations[j]->usedRegionCount - 1; k >= 0; k -= 1) { - SDL_free(allocator->allocations[j]->freeRegions[k]); + VULKAN_INTERNAL_RemoveMemoryUsedRegion( + renderer, + allocator->allocations[j]->usedRegions[k] + ); } - SDL_free(allocator->allocations[j]->freeRegions); - - renderer->vkFreeMemory( - renderer->logicalDevice, - allocator->allocations[j]->memory, - NULL + VULKAN_INTERNAL_DeallocateMemory( + renderer, + allocator, + j ); - - SDL_DestroyMutex(allocator->allocations[j]->memoryLock); - SDL_free(allocator->allocations[j]); } - SDL_free(allocator->allocations); - SDL_free(allocator->sortedFreeRegions); + if (renderer->memoryAllocator->subAllocators[i].allocations != NULL) + { + SDL_free(renderer->memoryAllocator->subAllocators[i].allocations); + } + + SDL_free(renderer->memoryAllocator->subAllocators[i].sortedFreeRegions); } SDL_free(renderer->memoryAllocator); @@ -7118,7 +7119,7 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer( 1 ); - if (transferBuffer == NULL) + if (transferBuffer->buffer == NULL) { Refresh_LogError("Failed to allocate transfer buffer!"); return NULL; @@ -10047,7 +10048,7 @@ static void VULKAN_INTERNAL_CleanCommandBuffer( for (i = 0; i < commandBuffer->transferBufferCount; i += 1) { - VULKAN_INTERNAL_DestroyBuffer(renderer, commandBuffer->transferBuffers[i]->buffer); + VULKAN_INTERNAL_QueueDestroyBuffer(renderer, commandBuffer->transferBuffers[i]->buffer); SDL_free(commandBuffer->transferBuffers[i]); commandBuffer->transferBuffers[i] = NULL; } @@ -10202,6 +10203,8 @@ static void VULKAN_Submit( VulkanCommandBuffer *currentCommandBuffer; VkPipelineStageFlags waitStages[MAX_PRESENT_COUNT]; uint32_t swapchainImageIndex; + uint8_t commandBufferCleaned = 0; + VulkanMemorySubAllocator *allocator; int32_t i, j; SDL_LockMutex(renderer->submitLock); @@ -10322,13 +10325,50 @@ static void VULKAN_Submit( renderer, renderer->submittedCommandBuffers[i] ); + + commandBufferCleaned = 1; } } + if (commandBufferCleaned) + { + SDL_LockMutex(renderer->allocatorLock); + + for (i = 0; i < VK_MAX_MEMORY_TYPES; i += 1) + { + allocator = &renderer->memoryAllocator->subAllocators[i]; + + for (j = allocator->allocationCount - 1; j >= 0; j -= 1) + { + if (allocator->allocations[j]->usedRegionCount == 0) + { + VULKAN_INTERNAL_DeallocateMemory( + renderer, + allocator, + j + ); + } + } + } + + SDL_UnlockMutex(renderer->allocatorLock); + } + /* Check pending destroys */ VULKAN_INTERNAL_PerformPendingDestroys(renderer); + /* Defrag! */ + if (renderer->needDefrag) + { + renderer->defragTimer += 1; + + if (renderer->defragTimer == 1) + { + VULKAN_INTERNAL_DefragmentMemory(renderer); + } + } + SDL_UnlockMutex(renderer->submitLock); } @@ -10343,7 +10383,6 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( VulkanTexture* newTexture; VkBufferCopy bufferCopy; VkImageCopy *imageCopyRegions; - VkImageAspectFlags aspectFlags; VulkanCommandBuffer *commandBuffer; VkCommandBufferBeginInfo beginInfo; VkPipelineStageFlags waitFlags = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; @@ -10393,7 +10432,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( RESOURCE_ACCESS_NONE, currentRegion->vulkanBuffer->usage, currentRegion->vulkanBuffer->preferDeviceLocal, - currentRegion->vulkanBuffer->isTransferBuffer + 0 ); if (newBuffer == NULL) @@ -10441,9 +10480,12 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( VULKAN_INTERNAL_TrackBuffer(renderer, commandBuffer, newBuffer); /* re-point original container to new buffer */ - newBuffer->container = currentRegion->vulkanBuffer->container; - newBuffer->container->vulkanBuffer = newBuffer; - currentRegion->vulkanBuffer->container = NULL; + if (currentRegion->vulkanBuffer->container != NULL) + { + newBuffer->container = currentRegion->vulkanBuffer->container; + newBuffer->container->vulkanBuffer = newBuffer; + currentRegion->vulkanBuffer->container = NULL; + } VULKAN_INTERNAL_QueueDestroyBuffer(renderer, currentRegion->vulkanBuffer); @@ -10476,7 +10518,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( renderer, commandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_READ, - aspectFlags, + currentRegion->vulkanTexture->aspectFlags, 0, currentRegion->vulkanTexture->layerCount, 0, @@ -10490,7 +10532,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( renderer, commandBuffer->commandBuffer, RESOURCE_ACCESS_TRANSFER_WRITE, - aspectFlags, + currentRegion->vulkanTexture->aspectFlags, 0, currentRegion->vulkanTexture->layerCount, 0, @@ -10507,7 +10549,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( imageCopyRegions[level].srcOffset.x = 0; imageCopyRegions[level].srcOffset.y = 0; imageCopyRegions[level].srcOffset.z = 0; - imageCopyRegions[level].srcSubresource.aspectMask = aspectFlags; + imageCopyRegions[level].srcSubresource.aspectMask = currentRegion->vulkanTexture->aspectFlags; imageCopyRegions[level].srcSubresource.baseArrayLayer = 0; imageCopyRegions[level].srcSubresource.layerCount = currentRegion->vulkanTexture->layerCount; imageCopyRegions[level].srcSubresource.mipLevel = level; @@ -10517,7 +10559,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( imageCopyRegions[level].dstOffset.x = 0; imageCopyRegions[level].dstOffset.y = 0; imageCopyRegions[level].dstOffset.z = 0; - imageCopyRegions[level].dstSubresource.aspectMask = aspectFlags; + imageCopyRegions[level].dstSubresource.aspectMask = currentRegion->vulkanTexture->aspectFlags; imageCopyRegions[level].dstSubresource.baseArrayLayer = 0; imageCopyRegions[level].dstSubresource.layerCount = currentRegion->vulkanTexture->layerCount; imageCopyRegions[level].dstSubresource.mipLevel = level; @@ -10537,7 +10579,7 @@ static uint8_t VULKAN_INTERNAL_DefragmentMemory( renderer, commandBuffer->commandBuffer, originalResourceAccessType, - aspectFlags, + currentRegion->vulkanTexture->aspectFlags, 0, currentRegion->vulkanTexture->layerCount, 0,