From fb00cc9ea83fb1736db4e702cf32a685205638bb Mon Sep 17 00:00:00 2001 From: Adam Sawicki Date: Thu, 22 Nov 2018 17:10:07 +0100 Subject: [PATCH] Removed VMA_DEFRAGMENTATION_* flags. VmaDefragmentationInfo2::flags is now reserved for future use and should be 0. Research various options and chosen some parameters as default. --- src/VmaReplay/VmaReplay.cpp | 3 +- src/vk_mem_alloc.h | 91 ++++++++++++++----------------------- 2 files changed, 34 insertions(+), 60 deletions(-) diff --git a/src/VmaReplay/VmaReplay.cpp b/src/VmaReplay/VmaReplay.cpp index dd5f9b3..1c94841 100644 --- a/src/VmaReplay/VmaReplay.cpp +++ b/src/VmaReplay/VmaReplay.cpp @@ -1785,7 +1785,7 @@ void Player::Defragment() const duration defragDurationEnd = timeAfterDefragEnd - timeAfterGpu; // If anything changed. - if(defragStats.allocationsLost > 0 || defragStats.allocationsMoved > 0) + if(defragStats.allocationsMoved > 0) { // Go over allocation that changed and destroy their buffers and images. size_t i = 0; @@ -1825,7 +1825,6 @@ void Player::Defragment() printf(" bytesFreed: %llu\n", defragStats.bytesFreed); printf(" allocationsMoved: %u\n", defragStats.allocationsMoved); printf(" deviceMemoryBlocksFreed: %u\n", defragStats.deviceMemoryBlocksFreed); - printf(" allocationsLost: %u\n", defragStats.allocationsLost); vmaCalculateStats(m_Allocator, &stats); PrintStats(stats, "after defragmentation"); diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h index de01504..a984d22 100644 --- a/src/vk_mem_alloc.h +++ b/src/vk_mem_alloc.h @@ -2578,25 +2578,8 @@ Call function vmaDefragmentationEnd() to destroy it. */ VK_DEFINE_HANDLE(VmaDefragmentationContext) -/// Flags to be used in vmaDefragmentationBegin(). +/// Flags to be used in vmaDefragmentationBegin(). None at the moment. Reserved for future use. typedef enum VmaDefragmentationFlagBits { - /** Add this flag to change defragmentation algorithm to fast rather than default (balanced). - This algorithm will favor speed over quality of defragmentation. - Defragmentation will be done as fast and move as little allocations and bytes as possible while - still providing some benefits. - */ - VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT = 0x00000001, - /** Add this flag to change defragmentation algorithm to optimal rather than default (balanced). - This algorithm will favor quality of defragmentation over speed. - Allocations will be as perfectly compacted as possible. - */ - VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT = 0x00000002, - /** \brief A bit mask to extract only `ALGORITHM` bits from entire set of flags. - */ - VMA_DEFRAGMENTATION_ALGORITHM_MASK = - VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT | - VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT, - VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF } VmaDefragmentationFlagBits; typedef VkFlags VmaDefragmentationFlags; @@ -2606,7 +2589,7 @@ typedef VkFlags VmaDefragmentationFlags; To be used with function vmaDefragmentationBegin(). */ typedef struct VmaDefragmentationInfo2 { - /** \brief Flags for defragmentation. Use #VmaDefragmentationFlagBits enum. + /** \brief Reserved for future use. Should be 0. */ VmaDefragmentationFlags flags; /** \brief Number of allocations in `pAllocations` array. @@ -5737,8 +5720,7 @@ public: VmaDefragmentationAlgorithm( VmaAllocator hAllocator, VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex, - uint32_t algorithmFlags); // Zero or one of VMA_DEFRAGMENTATION_*_ALGORITHM_BIT. + uint32_t currentFrameIndex); virtual ~VmaDefragmentationAlgorithm(); void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged); @@ -5756,7 +5738,6 @@ private: VmaAllocator const m_hAllocator; VmaBlockVector* const m_pBlockVector; const uint32_t m_CurrentFrameIndex; - const uint32_t m_AlgorithmFlags; uint32_t m_AllocationCount; bool m_AllAllocations; @@ -5819,7 +5800,7 @@ private: m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount; } - void SortAllocationsBySizeDescecnding() + void SortAllocationsBySizeDescending() { VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater()); } @@ -5911,7 +5892,7 @@ public: VmaPool hCustomPool, // Optional. VmaBlockVector* pBlockVector, uint32_t currFrameIndex, - uint32_t algorithmFlags); // Zero or one of VMA_DEFRAGMENTATION_*_ALGORITHM_BIT. + uint32_t flags); ~VmaBlockVectorDefragmentationContext(); VmaPool GetCustomPool() const { return m_hCustomPool; } @@ -5952,7 +5933,7 @@ public: VmaDefragmentationContext_T( VmaAllocator hAllocator, uint32_t currFrameIndex, - uint32_t algorithmFlags, + uint32_t flags, VmaDefragmentationStats* pStats); ~VmaDefragmentationContext_T(); @@ -5976,7 +5957,7 @@ public: private: const VmaAllocator m_hAllocator; const uint32_t m_CurrFrameIndex; - const uint32_t m_AlgorithmFlags; + const uint32_t m_Flags; VmaDefragmentationStats* const m_pStats; // Owner of these objects. VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES]; @@ -11896,12 +11877,10 @@ void VmaBlockVector::AddStats(VmaStats* pStats) VmaDefragmentationAlgorithm::VmaDefragmentationAlgorithm( VmaAllocator hAllocator, VmaBlockVector* pBlockVector, - uint32_t currentFrameIndex, - uint32_t algorithmFlags) : + uint32_t currentFrameIndex) : m_hAllocator(hAllocator), m_pBlockVector(pBlockVector), m_CurrentFrameIndex(currentFrameIndex), - m_AlgorithmFlags(algorithmFlags), m_AllAllocations(false), m_AllocationCount(0), m_BytesMoved(0), @@ -11961,21 +11940,17 @@ VkResult VmaDefragmentationAlgorithm::DefragmentRound( return VK_SUCCESS; } - uint32_t strategy = UINT32_MAX; - switch(m_AlgorithmFlags) - { - case VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT: - strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT; - break; - case VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT: - strategy = VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET; - break; - default: - strategy = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT; - } + // This is a choice based on research. + // Option 1: + uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT; + // Option 2: + //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT; + // Option 3: + //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT; size_t srcBlockMinIndex = 0; // When FAST_ALGORITHM, move allocations from only last out of blocks that contain non-movable allocations. + /* if(m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) { const size_t blocksWithNonMovableCount = CalcBlocksWithNonMovableCount(); @@ -11984,6 +11959,7 @@ VkResult VmaDefragmentationAlgorithm::DefragmentRound( srcBlockMinIndex = blocksWithNonMovableCount - 1; } } + */ size_t srcBlockIndex = m_Blocks.size() - 1; size_t srcAllocIndex = SIZE_MAX; @@ -12146,21 +12122,21 @@ VkResult VmaDefragmentationAlgorithm::Defragment( } pBlockInfo->CalcHasNonMovableAllocations(); - if((m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) != 0) - { - pBlockInfo->SortAllocationsByOffsetDescending(); - } - else - { - pBlockInfo->SortAllocationsBySizeDescecnding(); - } + + // This is a choice based on research. + // Option 1: + pBlockInfo->SortAllocationsByOffsetDescending(); + // Option 2: + //pBlockInfo->SortAllocationsBySizeDescending(); } // Sort m_Blocks this time by the main criterium, from most "destination" to most "source" blocks. VMA_SORT(m_Blocks.begin(), m_Blocks.end(), BlockInfoCompareMoveDestination()); + // This is a choice based on research. + const uint32_t roundCount = 2; + // Execute defragmentation rounds (the main part). - const uint32_t roundCount = (m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) ? 1 : 2; VkResult result = VK_SUCCESS; for(uint32_t round = 0; (round < roundCount) && (result == VK_SUCCESS); ++round) { @@ -12229,7 +12205,7 @@ void VmaBlockVectorDefragmentationContext::Begin() m_Allocations.size() == m_pBlockVector->CalcAllocationCount(); m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm)( - m_hAllocator, m_pBlockVector, m_CurrFrameIndex, m_AlgorithmFlags); + m_hAllocator, m_pBlockVector, m_CurrFrameIndex); if(allAllocations) { @@ -12250,11 +12226,11 @@ void VmaBlockVectorDefragmentationContext::Begin() VmaDefragmentationContext_T::VmaDefragmentationContext_T( VmaAllocator hAllocator, uint32_t currFrameIndex, - uint32_t algorithmFlags, + uint32_t flags, VmaDefragmentationStats* pStats) : m_hAllocator(hAllocator), m_CurrFrameIndex(currFrameIndex), - m_AlgorithmFlags(algorithmFlags), + m_Flags(flags), m_pStats(pStats), m_CustomPoolContexts(VmaStlAllocator(hAllocator->GetAllocationCallbacks())) { @@ -12307,7 +12283,7 @@ void VmaDefragmentationContext_T::AddPools(uint32_t poolCount, VmaPool* pPools) pool, &pool->m_BlockVector, m_CurrFrameIndex, - m_AlgorithmFlags); + m_Flags); m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); } @@ -12355,7 +12331,7 @@ void VmaDefragmentationContext_T::AddAllocations( hAllocPool, &hAllocPool->m_BlockVector, m_CurrFrameIndex, - m_AlgorithmFlags); + m_Flags); m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); } } @@ -12372,7 +12348,7 @@ void VmaDefragmentationContext_T::AddAllocations( VMA_NULL, // hCustomPool m_hAllocator->m_pBlockVectors[memTypeIndex], m_CurrFrameIndex, - m_AlgorithmFlags); + m_Flags); m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx; } } @@ -13713,9 +13689,8 @@ VkResult VmaAllocator_T::DefragmentationBegin( memset(info.pAllocationsChanged, 0, info.allocationCount * sizeof(VkBool32)); } - const uint32_t algorithmFlags = info.flags & VMA_DEFRAGMENTATION_ALGORITHM_MASK; *pContext = vma_new(this, VmaDefragmentationContext_T)( - this, m_CurrentFrameIndex.load(), algorithmFlags, pStats); + this, m_CurrentFrameIndex.load(), info.flags, pStats); (*pContext)->AddPools(info.poolCount, info.pPools); (*pContext)->AddAllocations(