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.

This commit is contained in:
Adam Sawicki 2018-11-22 17:10:07 +01:00
parent 434ac86781
commit fb00cc9ea8
2 changed files with 34 additions and 60 deletions

View File

@ -1785,7 +1785,7 @@ void Player::Defragment()
const duration defragDurationEnd = timeAfterDefragEnd - timeAfterGpu; const duration defragDurationEnd = timeAfterDefragEnd - timeAfterGpu;
// If anything changed. // 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. // Go over allocation that changed and destroy their buffers and images.
size_t i = 0; size_t i = 0;
@ -1825,7 +1825,6 @@ void Player::Defragment()
printf(" bytesFreed: %llu\n", defragStats.bytesFreed); printf(" bytesFreed: %llu\n", defragStats.bytesFreed);
printf(" allocationsMoved: %u\n", defragStats.allocationsMoved); printf(" allocationsMoved: %u\n", defragStats.allocationsMoved);
printf(" deviceMemoryBlocksFreed: %u\n", defragStats.deviceMemoryBlocksFreed); printf(" deviceMemoryBlocksFreed: %u\n", defragStats.deviceMemoryBlocksFreed);
printf(" allocationsLost: %u\n", defragStats.allocationsLost);
vmaCalculateStats(m_Allocator, &stats); vmaCalculateStats(m_Allocator, &stats);
PrintStats(stats, "after defragmentation"); PrintStats(stats, "after defragmentation");

View File

@ -2578,25 +2578,8 @@ Call function vmaDefragmentationEnd() to destroy it.
*/ */
VK_DEFINE_HANDLE(VmaDefragmentationContext) 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 { 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 VMA_DEFRAGMENTATION_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VmaDefragmentationFlagBits; } VmaDefragmentationFlagBits;
typedef VkFlags VmaDefragmentationFlags; typedef VkFlags VmaDefragmentationFlags;
@ -2606,7 +2589,7 @@ typedef VkFlags VmaDefragmentationFlags;
To be used with function vmaDefragmentationBegin(). To be used with function vmaDefragmentationBegin().
*/ */
typedef struct VmaDefragmentationInfo2 { typedef struct VmaDefragmentationInfo2 {
/** \brief Flags for defragmentation. Use #VmaDefragmentationFlagBits enum. /** \brief Reserved for future use. Should be 0.
*/ */
VmaDefragmentationFlags flags; VmaDefragmentationFlags flags;
/** \brief Number of allocations in `pAllocations` array. /** \brief Number of allocations in `pAllocations` array.
@ -5737,8 +5720,7 @@ public:
VmaDefragmentationAlgorithm( VmaDefragmentationAlgorithm(
VmaAllocator hAllocator, VmaAllocator hAllocator,
VmaBlockVector* pBlockVector, VmaBlockVector* pBlockVector,
uint32_t currentFrameIndex, uint32_t currentFrameIndex);
uint32_t algorithmFlags); // Zero or one of VMA_DEFRAGMENTATION_*_ALGORITHM_BIT.
virtual ~VmaDefragmentationAlgorithm(); virtual ~VmaDefragmentationAlgorithm();
void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged); void AddAllocation(VmaAllocation hAlloc, VkBool32* pChanged);
@ -5756,7 +5738,6 @@ private:
VmaAllocator const m_hAllocator; VmaAllocator const m_hAllocator;
VmaBlockVector* const m_pBlockVector; VmaBlockVector* const m_pBlockVector;
const uint32_t m_CurrentFrameIndex; const uint32_t m_CurrentFrameIndex;
const uint32_t m_AlgorithmFlags;
uint32_t m_AllocationCount; uint32_t m_AllocationCount;
bool m_AllAllocations; bool m_AllAllocations;
@ -5819,7 +5800,7 @@ private:
m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount; m_HasNonMovableAllocations = blockAllocCount != defragmentAllocCount;
} }
void SortAllocationsBySizeDescecnding() void SortAllocationsBySizeDescending()
{ {
VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater()); VMA_SORT(m_Allocations.begin(), m_Allocations.end(), AllocationInfoSizeGreater());
} }
@ -5911,7 +5892,7 @@ public:
VmaPool hCustomPool, // Optional. VmaPool hCustomPool, // Optional.
VmaBlockVector* pBlockVector, VmaBlockVector* pBlockVector,
uint32_t currFrameIndex, uint32_t currFrameIndex,
uint32_t algorithmFlags); // Zero or one of VMA_DEFRAGMENTATION_*_ALGORITHM_BIT. uint32_t flags);
~VmaBlockVectorDefragmentationContext(); ~VmaBlockVectorDefragmentationContext();
VmaPool GetCustomPool() const { return m_hCustomPool; } VmaPool GetCustomPool() const { return m_hCustomPool; }
@ -5952,7 +5933,7 @@ public:
VmaDefragmentationContext_T( VmaDefragmentationContext_T(
VmaAllocator hAllocator, VmaAllocator hAllocator,
uint32_t currFrameIndex, uint32_t currFrameIndex,
uint32_t algorithmFlags, uint32_t flags,
VmaDefragmentationStats* pStats); VmaDefragmentationStats* pStats);
~VmaDefragmentationContext_T(); ~VmaDefragmentationContext_T();
@ -5976,7 +5957,7 @@ public:
private: private:
const VmaAllocator m_hAllocator; const VmaAllocator m_hAllocator;
const uint32_t m_CurrFrameIndex; const uint32_t m_CurrFrameIndex;
const uint32_t m_AlgorithmFlags; const uint32_t m_Flags;
VmaDefragmentationStats* const m_pStats; VmaDefragmentationStats* const m_pStats;
// Owner of these objects. // Owner of these objects.
VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES]; VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES];
@ -11896,12 +11877,10 @@ void VmaBlockVector::AddStats(VmaStats* pStats)
VmaDefragmentationAlgorithm::VmaDefragmentationAlgorithm( VmaDefragmentationAlgorithm::VmaDefragmentationAlgorithm(
VmaAllocator hAllocator, VmaAllocator hAllocator,
VmaBlockVector* pBlockVector, VmaBlockVector* pBlockVector,
uint32_t currentFrameIndex, uint32_t currentFrameIndex) :
uint32_t algorithmFlags) :
m_hAllocator(hAllocator), m_hAllocator(hAllocator),
m_pBlockVector(pBlockVector), m_pBlockVector(pBlockVector),
m_CurrentFrameIndex(currentFrameIndex), m_CurrentFrameIndex(currentFrameIndex),
m_AlgorithmFlags(algorithmFlags),
m_AllAllocations(false), m_AllAllocations(false),
m_AllocationCount(0), m_AllocationCount(0),
m_BytesMoved(0), m_BytesMoved(0),
@ -11961,21 +11940,17 @@ VkResult VmaDefragmentationAlgorithm::DefragmentRound(
return VK_SUCCESS; return VK_SUCCESS;
} }
uint32_t strategy = UINT32_MAX; // This is a choice based on research.
switch(m_AlgorithmFlags) // Option 1:
{ uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT;
case VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT: // Option 2:
strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_TIME_BIT; //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_MEMORY_BIT;
break; // Option 3:
case VMA_DEFRAGMENTATION_OPTIMAL_ALGORITHM_BIT: //uint32_t strategy = VMA_ALLOCATION_CREATE_STRATEGY_MIN_FRAGMENTATION_BIT;
strategy = VMA_ALLOCATION_INTERNAL_STRATEGY_MIN_OFFSET;
break;
default:
strategy = VMA_ALLOCATION_CREATE_STRATEGY_BEST_FIT_BIT;
}
size_t srcBlockMinIndex = 0; size_t srcBlockMinIndex = 0;
// When FAST_ALGORITHM, move allocations from only last out of blocks that contain non-movable allocations. // When FAST_ALGORITHM, move allocations from only last out of blocks that contain non-movable allocations.
/*
if(m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) if(m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT)
{ {
const size_t blocksWithNonMovableCount = CalcBlocksWithNonMovableCount(); const size_t blocksWithNonMovableCount = CalcBlocksWithNonMovableCount();
@ -11984,6 +11959,7 @@ VkResult VmaDefragmentationAlgorithm::DefragmentRound(
srcBlockMinIndex = blocksWithNonMovableCount - 1; srcBlockMinIndex = blocksWithNonMovableCount - 1;
} }
} }
*/
size_t srcBlockIndex = m_Blocks.size() - 1; size_t srcBlockIndex = m_Blocks.size() - 1;
size_t srcAllocIndex = SIZE_MAX; size_t srcAllocIndex = SIZE_MAX;
@ -12146,21 +12122,21 @@ VkResult VmaDefragmentationAlgorithm::Defragment(
} }
pBlockInfo->CalcHasNonMovableAllocations(); pBlockInfo->CalcHasNonMovableAllocations();
if((m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) != 0)
{ // This is a choice based on research.
// Option 1:
pBlockInfo->SortAllocationsByOffsetDescending(); pBlockInfo->SortAllocationsByOffsetDescending();
} // Option 2:
else //pBlockInfo->SortAllocationsBySizeDescending();
{
pBlockInfo->SortAllocationsBySizeDescecnding();
}
} }
// Sort m_Blocks this time by the main criterium, from most "destination" to most "source" blocks. // 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()); 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). // Execute defragmentation rounds (the main part).
const uint32_t roundCount = (m_AlgorithmFlags & VMA_DEFRAGMENTATION_FAST_ALGORITHM_BIT) ? 1 : 2;
VkResult result = VK_SUCCESS; VkResult result = VK_SUCCESS;
for(uint32_t round = 0; (round < roundCount) && (result == VK_SUCCESS); ++round) 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_Allocations.size() == m_pBlockVector->CalcAllocationCount();
m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm)( m_pAlgorithm = vma_new(m_hAllocator, VmaDefragmentationAlgorithm)(
m_hAllocator, m_pBlockVector, m_CurrFrameIndex, m_AlgorithmFlags); m_hAllocator, m_pBlockVector, m_CurrFrameIndex);
if(allAllocations) if(allAllocations)
{ {
@ -12250,11 +12226,11 @@ void VmaBlockVectorDefragmentationContext::Begin()
VmaDefragmentationContext_T::VmaDefragmentationContext_T( VmaDefragmentationContext_T::VmaDefragmentationContext_T(
VmaAllocator hAllocator, VmaAllocator hAllocator,
uint32_t currFrameIndex, uint32_t currFrameIndex,
uint32_t algorithmFlags, uint32_t flags,
VmaDefragmentationStats* pStats) : VmaDefragmentationStats* pStats) :
m_hAllocator(hAllocator), m_hAllocator(hAllocator),
m_CurrFrameIndex(currFrameIndex), m_CurrFrameIndex(currFrameIndex),
m_AlgorithmFlags(algorithmFlags), m_Flags(flags),
m_pStats(pStats), m_pStats(pStats),
m_CustomPoolContexts(VmaStlAllocator<VmaBlockVectorDefragmentationContext*>(hAllocator->GetAllocationCallbacks())) m_CustomPoolContexts(VmaStlAllocator<VmaBlockVectorDefragmentationContext*>(hAllocator->GetAllocationCallbacks()))
{ {
@ -12307,7 +12283,7 @@ void VmaDefragmentationContext_T::AddPools(uint32_t poolCount, VmaPool* pPools)
pool, pool,
&pool->m_BlockVector, &pool->m_BlockVector,
m_CurrFrameIndex, m_CurrFrameIndex,
m_AlgorithmFlags); m_Flags);
m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); m_CustomPoolContexts.push_back(pBlockVectorDefragCtx);
} }
@ -12355,7 +12331,7 @@ void VmaDefragmentationContext_T::AddAllocations(
hAllocPool, hAllocPool,
&hAllocPool->m_BlockVector, &hAllocPool->m_BlockVector,
m_CurrFrameIndex, m_CurrFrameIndex,
m_AlgorithmFlags); m_Flags);
m_CustomPoolContexts.push_back(pBlockVectorDefragCtx); m_CustomPoolContexts.push_back(pBlockVectorDefragCtx);
} }
} }
@ -12372,7 +12348,7 @@ void VmaDefragmentationContext_T::AddAllocations(
VMA_NULL, // hCustomPool VMA_NULL, // hCustomPool
m_hAllocator->m_pBlockVectors[memTypeIndex], m_hAllocator->m_pBlockVectors[memTypeIndex],
m_CurrFrameIndex, m_CurrFrameIndex,
m_AlgorithmFlags); m_Flags);
m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx; m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx;
} }
} }
@ -13713,9 +13689,8 @@ VkResult VmaAllocator_T::DefragmentationBegin(
memset(info.pAllocationsChanged, 0, info.allocationCount * sizeof(VkBool32)); memset(info.pAllocationsChanged, 0, info.allocationCount * sizeof(VkBool32));
} }
const uint32_t algorithmFlags = info.flags & VMA_DEFRAGMENTATION_ALGORITHM_MASK;
*pContext = vma_new(this, VmaDefragmentationContext_T)( *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)->AddPools(info.poolCount, info.pPools);
(*pContext)->AddAllocations( (*pContext)->AddAllocations(