@@ -85,6 +85,8 @@ enum class VMA_FUNCTION
8585 GetAllocationInfo,
8686 MakePoolAllocationsLost,
8787 ResizeAllocation,
88+ DefragmentationBegin,
89+ DefragmentationEnd,
8890 Count
8991};
9092static const char * VMA_FUNCTION_NAMES[] = {
@@ -108,6 +110,8 @@ static const char* VMA_FUNCTION_NAMES[] = {
108110 " vmaGetAllocationInfo" ,
109111 " vmaMakePoolAllocationsLost" ,
110112 " vmaResizeAllocation" ,
113+ " vmaDefragmentationBegin" ,
114+ " vmaDefragmentationEnd" ,
111115};
112116static_assert (
113117 _countof (VMA_FUNCTION_NAMES) == (size_t )VMA_FUNCTION::Count,
@@ -839,7 +843,7 @@ void ConfigurationParser::CompareMemProps(
839843
840844static const char * const VALIDATION_LAYER_NAME = " VK_LAYER_LUNARG_standard_validation" ;
841845
842- static bool g_MemoryAliasingWarningEnabled = true ;
846+ static const bool g_MemoryAliasingWarningEnabled = false ;
843847
844848static VKAPI_ATTR VkBool32 VKAPI_CALL MyDebugReportCallback (
845849 VkDebugReportFlagsEXT flags,
@@ -973,6 +977,7 @@ class Player
973977 };
974978 std::unordered_map<uint64_t , Pool> m_Pools;
975979 std::unordered_map<uint64_t , Allocation> m_Allocations;
980+ std::unordered_map<uint64_t , VmaDefragmentationContext> m_DefragmentationContexts;
976981
977982 struct Thread
978983 {
@@ -1029,6 +1034,8 @@ class Player
10291034 void ExecuteGetAllocationInfo (size_t lineNumber, const CsvSplit& csvSplit);
10301035 void ExecuteMakePoolAllocationsLost (size_t lineNumber, const CsvSplit& csvSplit);
10311036 void ExecuteResizeAllocation (size_t lineNumber, const CsvSplit& csvSplit);
1037+ void ExecuteDefragmentationBegin (size_t lineNumber, const CsvSplit& csvSplit);
1038+ void ExecuteDefragmentationEnd (size_t lineNumber, const CsvSplit& csvSplit);
10321039
10331040 void DestroyAllocation (size_t lineNumber, const CsvSplit& csvSplit, const char * functionName);
10341041
@@ -1175,6 +1182,10 @@ void Player::ExecuteLine(size_t lineNumber, const StrRange& line)
11751182 ExecuteMakePoolAllocationsLost (lineNumber, csvSplit);
11761183 else if (StrRangeEq (functionName, VMA_FUNCTION_NAMES[(uint32_t )VMA_FUNCTION::ResizeAllocation]))
11771184 ExecuteResizeAllocation (lineNumber, csvSplit);
1185+ else if (StrRangeEq (functionName, VMA_FUNCTION_NAMES[(uint32_t )VMA_FUNCTION::DefragmentationBegin]))
1186+ ExecuteDefragmentationBegin (lineNumber, csvSplit);
1187+ else if (StrRangeEq (functionName, VMA_FUNCTION_NAMES[(uint32_t )VMA_FUNCTION::DefragmentationEnd]))
1188+ ExecuteDefragmentationEnd (lineNumber, csvSplit);
11781189 else
11791190 {
11801191 if (IssueWarning ())
@@ -1611,6 +1622,21 @@ int Player::InitVulkan()
16111622
16121623void Player::FinalizeVulkan ()
16131624{
1625+ if (!m_DefragmentationContexts.empty ())
1626+ {
1627+ printf (" WARNING: Defragmentation contexts not destroyed: %zu.\n " , m_DefragmentationContexts.size ());
1628+
1629+ if (CLEANUP_LEAKED_OBJECTS)
1630+ {
1631+ for (const auto & it : m_DefragmentationContexts)
1632+ {
1633+ vmaDefragmentationEnd (m_Allocator, it.second );
1634+ }
1635+ }
1636+
1637+ m_DefragmentationContexts.clear ();
1638+ }
1639+
16141640 if (!m_Allocations.empty ())
16151641 {
16161642 printf (" WARNING: Allocations not destroyed: %zu.\n " , m_Allocations.size ());
@@ -1744,8 +1770,6 @@ void Player::Defragment()
17441770 return ;
17451771 }
17461772
1747- g_MemoryAliasingWarningEnabled = false ;
1748-
17491773 const time_point timeBeg = std::chrono::high_resolution_clock::now ();
17501774
17511775 VmaDefragmentationInfo2 defragInfo = {};
@@ -1835,8 +1859,6 @@ void Player::Defragment()
18351859 }
18361860
18371861 vkResetCommandPool (m_Device, m_CommandPool, 0 );
1838-
1839- g_MemoryAliasingWarningEnabled = true ;
18401862}
18411863
18421864void Player::PrintStats ()
@@ -2894,6 +2916,198 @@ void Player::ExecuteResizeAllocation(size_t lineNumber, const CsvSplit& csvSplit
28942916 }
28952917}
28962918
2919+ void Player::ExecuteDefragmentationBegin (size_t lineNumber, const CsvSplit& csvSplit)
2920+ {
2921+ m_Stats.RegisterFunctionCall (VMA_FUNCTION::DefragmentationBegin);
2922+
2923+ if (ValidateFunctionParameterCount (lineNumber, csvSplit, 9 , false ))
2924+ {
2925+ VmaDefragmentationInfo2 defragInfo = {};
2926+ std::vector<uint64_t > allocationOrigPtrs;
2927+ std::vector<uint64_t > poolOrigPtrs;
2928+ uint64_t cmdBufOrigPtr = 0 ;
2929+ uint64_t defragCtxOrigPtr = 0 ;
2930+
2931+ if (StrRangeToUint (csvSplit.GetRange (FIRST_PARAM_INDEX), defragInfo.flags ) &&
2932+ StrRangeToPtrList (csvSplit.GetRange (FIRST_PARAM_INDEX + 1 ), allocationOrigPtrs) &&
2933+ StrRangeToPtrList (csvSplit.GetRange (FIRST_PARAM_INDEX + 2 ), poolOrigPtrs) &&
2934+ StrRangeToUint (csvSplit.GetRange (FIRST_PARAM_INDEX + 3 ), defragInfo.maxCpuBytesToMove ) &&
2935+ StrRangeToUint (csvSplit.GetRange (FIRST_PARAM_INDEX + 4 ), defragInfo.maxCpuAllocationsToMove ) &&
2936+ StrRangeToUint (csvSplit.GetRange (FIRST_PARAM_INDEX + 5 ), defragInfo.maxGpuBytesToMove ) &&
2937+ StrRangeToUint (csvSplit.GetRange (FIRST_PARAM_INDEX + 6 ), defragInfo.maxGpuAllocationsToMove ) &&
2938+ StrRangeToPtr (csvSplit.GetRange (FIRST_PARAM_INDEX + 7 ), cmdBufOrigPtr) &&
2939+ StrRangeToPtr (csvSplit.GetRange (FIRST_PARAM_INDEX + 8 ), defragCtxOrigPtr))
2940+ {
2941+ const size_t allocationOrigPtrCount = allocationOrigPtrs.size ();
2942+ std::vector<VmaAllocation> allocations;
2943+ allocations.reserve (allocationOrigPtrCount);
2944+ for (size_t i = 0 ; i < allocationOrigPtrCount; ++i)
2945+ {
2946+ const auto it = m_Allocations.find (allocationOrigPtrs[i]);
2947+ if (it != m_Allocations.end () && it->second .allocation )
2948+ {
2949+ allocations.push_back (it->second .allocation );
2950+ }
2951+ }
2952+ if (!allocations.empty ())
2953+ {
2954+ defragInfo.allocationCount = (uint32_t )allocations.size ();
2955+ defragInfo.pAllocations = allocations.data ();
2956+ }
2957+
2958+ const size_t poolOrigPtrCount = poolOrigPtrs.size ();
2959+ std::vector<VmaPool> pools;
2960+ pools.reserve (poolOrigPtrCount);
2961+ for (size_t i = 0 ; i < poolOrigPtrCount; ++i)
2962+ {
2963+ const auto it = m_Pools.find (poolOrigPtrs[i]);
2964+ if (it != m_Pools.end () && it->second .pool )
2965+ {
2966+ pools.push_back (it->second .pool );
2967+ }
2968+ }
2969+ if (!pools.empty ())
2970+ {
2971+ defragInfo.poolCount = (uint32_t )pools.size ();
2972+ defragInfo.pPools = pools.data ();
2973+ }
2974+
2975+ if (allocations.size () != allocationOrigPtrCount ||
2976+ pools.size () != poolOrigPtrCount)
2977+ {
2978+ if (IssueWarning ())
2979+ {
2980+ printf (" Line %zu: Passing %zu allocations and %zu pools to vmaDefragmentationBegin, while originally %zu allocations and %zu pools were passed.\n " ,
2981+ lineNumber,
2982+ allocations.size (), pools.size (),
2983+ allocationOrigPtrCount, poolOrigPtrCount);
2984+ }
2985+ }
2986+
2987+ if (cmdBufOrigPtr)
2988+ {
2989+ VkCommandBufferBeginInfo cmdBufBeginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
2990+ cmdBufBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
2991+ VkResult res = vkBeginCommandBuffer (m_CommandBuffer, &cmdBufBeginInfo);
2992+ if (res == VK_SUCCESS)
2993+ {
2994+ defragInfo.commandBuffer = m_CommandBuffer;
2995+ }
2996+ else
2997+ {
2998+ printf (" Line %zu: vkBeginCommandBuffer failed (%d)\n " , lineNumber, res);
2999+ }
3000+ }
3001+
3002+ VmaDefragmentationContext defragCtx = nullptr ;
3003+ VkResult res = vmaDefragmentationBegin (m_Allocator, &defragInfo, nullptr , &defragCtx);
3004+
3005+ if (defragInfo.commandBuffer )
3006+ {
3007+ vkEndCommandBuffer (m_CommandBuffer);
3008+
3009+ VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
3010+ submitInfo.commandBufferCount = 1 ;
3011+ submitInfo.pCommandBuffers = &m_CommandBuffer;
3012+ vkQueueSubmit (m_TransferQueue, 1 , &submitInfo, VK_NULL_HANDLE);
3013+ vkQueueWaitIdle (m_TransferQueue);
3014+ }
3015+
3016+ if (res >= VK_SUCCESS)
3017+ {
3018+ if (defragCtx)
3019+ {
3020+ if (defragCtxOrigPtr)
3021+ {
3022+ // We have defragmentation context, originally had defragmentation context: Store it.
3023+ m_DefragmentationContexts[defragCtxOrigPtr] = defragCtx;
3024+ }
3025+ else
3026+ {
3027+ // We have defragmentation context, originally it was null: End immediately.
3028+ vmaDefragmentationEnd (m_Allocator, defragCtx);
3029+ }
3030+ }
3031+ else
3032+ {
3033+ if (defragCtxOrigPtr)
3034+ {
3035+ // We have no defragmentation context, originally there was one: Store null.
3036+ m_DefragmentationContexts[defragCtxOrigPtr] = nullptr ;
3037+ }
3038+ else
3039+ {
3040+ // We have no defragmentation context, originally there wasn't as well - nothing to do.
3041+ }
3042+ }
3043+ }
3044+ else
3045+ {
3046+ if (defragCtxOrigPtr)
3047+ {
3048+ // Currently failed, originally succeeded.
3049+ if (IssueWarning ())
3050+ {
3051+ printf (" Line %zu: vmaDefragmentationBegin failed (%d), while originally succeeded.\n " , lineNumber, res);
3052+ }
3053+ }
3054+ else
3055+ {
3056+ // Currently failed, originally don't know.
3057+ if (IssueWarning ())
3058+ {
3059+ printf (" Line %zu: vmaDefragmentationBegin failed (%d).\n " , lineNumber, res);
3060+ }
3061+ }
3062+ }
3063+ }
3064+ else
3065+ {
3066+ if (IssueWarning ())
3067+ {
3068+ printf (" Line %zu: Invalid parameters for vmaDefragmentationBegin.\n " , lineNumber);
3069+ }
3070+ }
3071+ }
3072+ }
3073+
3074+ void Player::ExecuteDefragmentationEnd (size_t lineNumber, const CsvSplit& csvSplit)
3075+ {
3076+ m_Stats.RegisterFunctionCall (VMA_FUNCTION::DefragmentationEnd);
3077+
3078+ if (ValidateFunctionParameterCount (lineNumber, csvSplit, 1 , false ))
3079+ {
3080+ uint64_t origPtr = 0 ;
3081+
3082+ if (StrRangeToPtr (csvSplit.GetRange (FIRST_PARAM_INDEX), origPtr))
3083+ {
3084+ if (origPtr != 0 )
3085+ {
3086+ const auto it = m_DefragmentationContexts.find (origPtr);
3087+ if (it != m_DefragmentationContexts.end ())
3088+ {
3089+ vmaDefragmentationEnd (m_Allocator, it->second );
3090+ m_DefragmentationContexts.erase (it);
3091+ }
3092+ else
3093+ {
3094+ if (IssueWarning ())
3095+ {
3096+ printf (" Line %zu: Defragmentation context %llX not found.\n " , lineNumber, origPtr);
3097+ }
3098+ }
3099+ }
3100+ }
3101+ else
3102+ {
3103+ if (IssueWarning ())
3104+ {
3105+ printf (" Line %zu: Invalid parameters for vmaDefragmentationEnd.\n " , lineNumber);
3106+ }
3107+ }
3108+ }
3109+ }
3110+
28973111// //////////////////////////////////////////////////////////////////////////////
28983112// Main functions
28993113
0 commit comments