VK_EXT_memory_priority now works on all types of allocations - from default pools, custom pools, and dedicated. Ready to use!
diff --git a/src/VulkanSample.cpp b/src/VulkanSample.cpp
index 593cc76..f1c06bb 100644
--- a/src/VulkanSample.cpp
+++ b/src/VulkanSample.cpp
@@ -741,6 +741,10 @@
 

     VmaAllocationCreateInfo depthImageAllocCreateInfo = {};

     depthImageAllocCreateInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;

+    

+    // TODO DELME testing priority

+    //depthImageAllocCreateInfo.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT;

+    depthImageAllocCreateInfo.priority = VMA_MEMORY_PRIORITY_HIGHEST;

 

     ERR_GUARD_VULKAN( vmaCreateImage(g_hAllocator, &depthImageInfo, &depthImageAllocCreateInfo, &g_hDepthImage, &g_hDepthImageAlloc, nullptr) );

 

diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index c7ca920..dc82d86 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -2076,6 +2076,8 @@
     VMA_MEMORY_PRIORITY_HIGHEST,

 } VmaMemoryPriority;

 

+#define VMA_MEMORY_PRIORITY_COUNT VMA_MEMORY_PRIORITY_HIGHEST

+

 /// Flags to be passed as VmaAllocationCreateInfo::flags.

 typedef enum VmaAllocationCreateFlagBits {

     /** \brief Set this flag if the allocation should have its own memory block.

@@ -3799,6 +3801,21 @@
     }

 }

 

+static inline size_t VmaMemoryPriorityToIndex(VmaMemoryPriority priority)

+{

+    if(priority == VMA_MEMORY_PRIORITY_DEFAULT)

+    {

+        priority = VMA_MEMORY_PRIORITY_NORMAL;

+    }

+    VMA_ASSERT(priority <= VMA_MEMORY_PRIORITY_COUNT);

+    return (size_t)priority - 1;

+}

+static inline VmaMemoryPriority VmaMemoryPriorityIndexToPriority(size_t priorityIndex)

+{

+    VMA_ASSERT(priorityIndex < VMA_MEMORY_PRIORITY_COUNT);

+    return (VmaMemoryPriority)(priorityIndex + 1);

+}

+

 // Helper RAII class to lock a mutex in constructor and unlock it in destructor (at the end of scope).

 struct VmaMutexLock

 {

@@ -5850,7 +5867,8 @@
         VkDeviceMemory newMemory,

         VkDeviceSize newSize,

         uint32_t id,

-        uint32_t algorithm);

+        uint32_t algorithm,

+        VmaMemoryPriority priority);

     // Always call before destruction.

     void Destroy(VmaAllocator allocator);

     

@@ -5859,6 +5877,7 @@
     uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }

     uint32_t GetId() const { return m_Id; }

     void* GetMappedData() const { return m_pMappedData; }

+    VmaMemoryPriority GetPriority() const { return m_Priority; }

 

     // Validates all data structures inside this object. If not valid, returns false.

     bool Validate() const;

@@ -5886,6 +5905,7 @@
     uint32_t m_MemoryTypeIndex;

     uint32_t m_Id;

     VkDeviceMemory m_hMemory;

+    VmaMemoryPriority m_Priority;

 

     /*

     Protects access to m_hMemory so it's not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.

@@ -6524,7 +6544,7 @@
     const uint32_t m_Flags;

     VmaDefragmentationStats* const m_pStats;

     // Owner of these objects.

-    VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES];

+    VmaBlockVectorDefragmentationContext* m_DefaultPoolContexts[VK_MAX_MEMORY_TYPES][VMA_MEMORY_PRIORITY_COUNT];

     // Owner of these objects.

     VmaVector< VmaBlockVectorDefragmentationContext*, VmaStlAllocator<VmaBlockVectorDefragmentationContext*> > m_CustomPoolContexts;

 };

@@ -6702,7 +6722,7 @@
     VkPhysicalDeviceMemoryProperties m_MemProps;

 

     // Default pools.

-    VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES];

+    VmaBlockVector* m_pBlockVectors[VK_MAX_MEMORY_TYPES][VMA_MEMORY_PRIORITY_COUNT];

 

     // Each vector is sorted by memory (handle value).

     typedef VmaVector< VmaAllocation, VmaStlAllocator<VmaAllocation> > AllocationVectorType;

@@ -7482,6 +7502,10 @@
     "IMAGE_OPTIMAL",

 };

 

+// Correspond to values of VmaMemoryPriorityToIndex(VmaMemoryPriority priority).

+static const char* VMA_MEMORY_PRIORITY_NAMES[] = {

+    "LOWEST", "LOW", "NORMAL", "HIGH", "HIGHEST" };

+

 void VmaAllocation_T::PrintParameters(class VmaJsonWriter& json) const

 {

     json.WriteString("Type");

@@ -11198,6 +11222,7 @@
     m_MemoryTypeIndex(UINT32_MAX),

     m_Id(0),

     m_hMemory(VK_NULL_HANDLE),

+    m_Priority(VMA_MEMORY_PRIORITY_DEFAULT),

     m_MapCount(0),

     m_pMappedData(VMA_NULL)

 {

@@ -11210,7 +11235,8 @@
     VkDeviceMemory newMemory,

     VkDeviceSize newSize,

     uint32_t id,

-    uint32_t algorithm)

+    uint32_t algorithm,

+    VmaMemoryPriority priority)

 {

     VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);

 

@@ -11218,6 +11244,7 @@
     m_MemoryTypeIndex = newMemoryTypeIndex;

     m_Id = id;

     m_hMemory = newMemory;

+    m_Priority = priority;

 

     switch(algorithm)

     {

@@ -12183,7 +12210,8 @@
         mem,

         allocInfo.allocationSize,

         m_NextBlockId++,

-        m_Algorithm);

+        m_Algorithm,

+        m_Priority);

 

     m_Blocks.push_back(pBlock);

     if(pNewBlockIndex != VMA_NULL)

@@ -12460,6 +12488,14 @@
             json.WriteString("Algorithm");

             json.WriteString(VmaAlgorithmToStr(m_Algorithm));

         }

+

+        if(m_Priority != VMA_MEMORY_PRIORITY_DEFAULT &&

+            m_Priority != VMA_MEMORY_PRIORITY_NORMAL)

+        {

+            const size_t priorityIndex = VmaMemoryPriorityToIndex(m_Priority);

+            json.WriteString("Priority");

+            json.WriteString(VMA_MEMORY_PRIORITY_NAMES[priorityIndex]);

+        }

     }

     else

     {

@@ -13448,13 +13484,16 @@
         pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_pStats);

         vma_delete(m_hAllocator, pBlockVectorCtx);

     }

-    for(size_t i = m_hAllocator->m_MemProps.memoryTypeCount; i--; )

+    for(size_t memTypeIndex = m_hAllocator->m_MemProps.memoryTypeCount; memTypeIndex--; )

     {

-        VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[i];

-        if(pBlockVectorCtx)

+        for(size_t priorityIndex = VMA_MEMORY_PRIORITY_COUNT; priorityIndex--; )

         {

-            pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_pStats);

-            vma_delete(m_hAllocator, pBlockVectorCtx);

+            VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex][priorityIndex];

+            if(pBlockVectorCtx)

+            {

+                pBlockVectorCtx->GetBlockVector()->DefragmentationEnd(pBlockVectorCtx, m_pStats);

+                vma_delete(m_hAllocator, pBlockVectorCtx);

+            }

         }

     }

 }

@@ -13543,16 +13582,19 @@
             else

             {

                 const uint32_t memTypeIndex = hAlloc->GetMemoryTypeIndex();

-                pBlockVectorDefragCtx = m_DefaultPoolContexts[memTypeIndex];

+                VmaDeviceMemoryBlock* const pBlock = hAlloc->GetBlock();

+                const VmaMemoryPriority priority = pBlock->GetPriority();

+                const size_t priorityIndex = VmaMemoryPriorityToIndex(priority);

+                pBlockVectorDefragCtx = m_DefaultPoolContexts[memTypeIndex][priorityIndex];

                 if(!pBlockVectorDefragCtx)

                 {

                     pBlockVectorDefragCtx = vma_new(m_hAllocator, VmaBlockVectorDefragmentationContext)(

                         m_hAllocator,

                         VMA_NULL, // hCustomPool

-                        m_hAllocator->m_pBlockVectors[memTypeIndex],

+                        m_hAllocator->m_pBlockVectors[memTypeIndex][priorityIndex],

                         m_CurrFrameIndex,

                         m_Flags);

-                    m_DefaultPoolContexts[memTypeIndex] = pBlockVectorDefragCtx;

+                    m_DefaultPoolContexts[memTypeIndex][priorityIndex] = pBlockVectorDefragCtx;

                 }

             }

 

@@ -13589,19 +13631,22 @@
         memTypeIndex < m_hAllocator->GetMemoryTypeCount() && res >= VK_SUCCESS;

         ++memTypeIndex)

     {

-        VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex];

-        if(pBlockVectorCtx)

+        for(size_t priorityIndex = 0; priorityIndex < VMA_MEMORY_PRIORITY_COUNT; ++priorityIndex)

         {

-            VMA_ASSERT(pBlockVectorCtx->GetBlockVector());

-            pBlockVectorCtx->GetBlockVector()->Defragment(

-                pBlockVectorCtx,

-                pStats,

-                maxCpuBytesToMove, maxCpuAllocationsToMove,

-                maxGpuBytesToMove, maxGpuAllocationsToMove,

-                commandBuffer);

-            if(pBlockVectorCtx->res != VK_SUCCESS)

+            VmaBlockVectorDefragmentationContext* pBlockVectorCtx = m_DefaultPoolContexts[memTypeIndex][priorityIndex];

+            if(pBlockVectorCtx)

             {

-                res = pBlockVectorCtx->res;

+                VMA_ASSERT(pBlockVectorCtx->GetBlockVector());

+                pBlockVectorCtx->GetBlockVector()->Defragment(

+                    pBlockVectorCtx,

+                    pStats,

+                    maxCpuBytesToMove, maxCpuAllocationsToMove,

+                    maxGpuBytesToMove, maxGpuAllocationsToMove,

+                    commandBuffer);

+                if(pBlockVectorCtx->res != VK_SUCCESS)

+                {

+                    res = pBlockVectorCtx->res;

+                }

             }

         }

     }

@@ -14311,24 +14356,25 @@
     for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)

     {

         const VkDeviceSize preferredBlockSize = CalcPreferredBlockSize(memTypeIndex);

-

-        m_pBlockVectors[memTypeIndex] = vma_new(this, VmaBlockVector)(

-            this,

-            VK_NULL_HANDLE, // hParentPool

-            memTypeIndex,

-            preferredBlockSize,

-            0,

-            SIZE_MAX,

-            GetBufferImageGranularity(),

-            pCreateInfo->frameInUseCount,

-            false, // isCustomPool

-            false, // explicitBlockSize

-            false, // linearAlgorithm

-            VMA_MEMORY_PRIORITY_DEFAULT); // priority - TODO

-        // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here,

-        // becase minBlockCount is 0.

-        m_pDedicatedAllocations[memTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator<VmaAllocation>(GetAllocationCallbacks()));

-

+        for(size_t priorityIndex = 0; priorityIndex < VMA_MEMORY_PRIORITY_COUNT; ++priorityIndex)

+        {

+            m_pBlockVectors[memTypeIndex][priorityIndex] = vma_new(this, VmaBlockVector)(

+                this,

+                VK_NULL_HANDLE, // hParentPool

+                memTypeIndex,

+                preferredBlockSize,

+                0,

+                SIZE_MAX,

+                GetBufferImageGranularity(),

+                pCreateInfo->frameInUseCount,

+                false, // isCustomPool

+                false, // explicitBlockSize

+                false, // linearAlgorithm

+                VmaMemoryPriorityIndexToPriority(priorityIndex));

+            // No need to call m_pBlockVectors[memTypeIndex][blockVectorTypeIndex]->CreateMinBlocks here,

+            // becase minBlockCount is 0.

+            m_pDedicatedAllocations[memTypeIndex] = vma_new(this, AllocationVectorType)(VmaStlAllocator<VmaAllocation>(GetAllocationCallbacks()));

+        }

     }

 }

 

@@ -14373,15 +14419,20 @@
     

     VMA_ASSERT(m_Pools.empty());

 

-    for(size_t i = GetMemoryTypeCount(); i--; )

+    for(size_t memTypeIndex = GetMemoryTypeCount(); memTypeIndex--; )

     {

-        if(m_pDedicatedAllocations[i] != VMA_NULL && !m_pDedicatedAllocations[i]->empty())

+        for(size_t priorityIndex = VMA_MEMORY_PRIORITY_COUNT; priorityIndex--; )

+        {

+            vma_delete(this, m_pBlockVectors[memTypeIndex][priorityIndex]);

+        }

+

+        if(m_pDedicatedAllocations[memTypeIndex] != VMA_NULL &&

+            !m_pDedicatedAllocations[memTypeIndex]->empty())

         {

             VMA_ASSERT(0 && "Unfreed dedicated allocations found.");

         }

 

-        vma_delete(this, m_pDedicatedAllocations[i]);

-        vma_delete(this, m_pBlockVectors[i]);

+        vma_delete(this, m_pDedicatedAllocations[memTypeIndex]);

     }

 }

 

@@ -14507,7 +14558,9 @@
         finalCreateInfo.flags &= ~VMA_ALLOCATION_CREATE_MAPPED_BIT;

     }

 

-    VmaBlockVector* const blockVector = m_pBlockVectors[memTypeIndex];

+    const size_t priorityIndex = VmaMemoryPriorityToIndex(priority);

+

+    VmaBlockVector* const blockVector = m_pBlockVectors[memTypeIndex][priorityIndex];

     VMA_ASSERT(blockVector);

 

     const VkDeviceSize preferredBlockSize = blockVector->GetPreferredBlockSize();

@@ -14980,15 +15033,18 @@
                 case VmaAllocation_T::ALLOCATION_TYPE_BLOCK:

                     {

                         VmaBlockVector* pBlockVector = VMA_NULL;

-                        VmaPool hPool = allocation->GetBlock()->GetParentPool();

+                        VmaDeviceMemoryBlock* const pBlock = allocation->GetBlock();

+                        VmaPool hPool = pBlock->GetParentPool();

                         if(hPool != VK_NULL_HANDLE)

                         {

                             pBlockVector = &hPool->m_BlockVector;

                         }

                         else

                         {

-                            const uint32_t memTypeIndex = allocation->GetMemoryTypeIndex();

-                            pBlockVector = m_pBlockVectors[memTypeIndex];

+                            const uint32_t memTypeIndex = pBlock->GetMemoryTypeIndex();

+                            const VmaMemoryPriority priority = pBlock->GetPriority();

+                            const size_t priorityIndex = VmaMemoryPriorityToIndex(priority);

+                            pBlockVector = m_pBlockVectors[memTypeIndex][priorityIndex];

                         }

                         pBlockVector->Free(allocation);

                     }

@@ -15054,9 +15110,12 @@
     // Process default pools.

     for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)

     {

-        VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex];

-        VMA_ASSERT(pBlockVector);

-        pBlockVector->AddStats(pStats);

+        for(size_t priorityIndex = 0; priorityIndex < VMA_MEMORY_PRIORITY_COUNT; ++priorityIndex)

+        {

+            VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex][priorityIndex];

+            VMA_ASSERT(pBlockVector);

+            pBlockVector->AddStats(pStats);

+        }

     }

 

     // Process custom pools.

@@ -15339,18 +15398,21 @@
     {

         if(((1u << memTypeIndex) & memoryTypeBits) != 0)

         {

-            VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex];

-            VMA_ASSERT(pBlockVector);

-            VkResult localRes = pBlockVector->CheckCorruption();

-            switch(localRes)

+            for(size_t priorityIndex = 0; priorityIndex < VMA_MEMORY_PRIORITY_COUNT; ++priorityIndex)

             {

-            case VK_ERROR_FEATURE_NOT_PRESENT:

-                break;

-            case VK_SUCCESS:

-                finalRes = VK_SUCCESS;

-                break;

-            default:

-                return localRes;

+                VmaBlockVector* const pBlockVector = m_pBlockVectors[memTypeIndex][priorityIndex];

+                VMA_ASSERT(pBlockVector);

+                VkResult localRes = pBlockVector->CheckCorruption();

+                switch(localRes)

+                {

+                case VK_ERROR_FEATURE_NOT_PRESENT:

+                    break;

+                case VK_SUCCESS:

+                    finalRes = VK_SUCCESS;

+                    break;

+                default:

+                    return localRes;

+                }

             }

         }

     }

@@ -15721,22 +15783,31 @@
 

     {

         bool allocationsStarted = false;

+        const size_t defaultPriorityIndex = VmaMemoryPriorityToIndex(VMA_MEMORY_PRIORITY_DEFAULT);

         for(uint32_t memTypeIndex = 0; memTypeIndex < GetMemoryTypeCount(); ++memTypeIndex)

         {

-            if(m_pBlockVectors[memTypeIndex]->IsEmpty() == false)

+            for(size_t priorityIndex = 0; priorityIndex < VMA_MEMORY_PRIORITY_COUNT; ++priorityIndex)

             {

-                if(allocationsStarted == false)

+                if(m_pBlockVectors[memTypeIndex][priorityIndex]->IsEmpty() == false)

                 {

-                    allocationsStarted = true;

-                    json.WriteString("DefaultPools");

-                    json.BeginObject();

+                    if(allocationsStarted == false)

+                    {

+                        allocationsStarted = true;

+                        json.WriteString("DefaultPools");

+                        json.BeginObject();

+                    }

+

+                    json.BeginString("Type ");

+                    json.ContinueString(memTypeIndex);

+                    if(priorityIndex != defaultPriorityIndex)

+                    {

+                        json.ContinueString(" priority ");

+                        json.ContinueString(VMA_MEMORY_PRIORITY_NAMES[priorityIndex]);

+                    }

+                    json.EndString();

+

+                    m_pBlockVectors[memTypeIndex][priorityIndex]->PrintDetailedMap(json);

                 }

-

-                json.BeginString("Type ");

-                json.ContinueString(memTypeIndex);

-                json.EndString();

-

-                m_pBlockVectors[memTypeIndex]->PrintDetailedMap(json);

             }

         }

         if(allocationsStarted)