Add prototype function vmaGetName, vmaSetName, change JSON format and VmaDumpVis.py to use that
diff --git a/src/Tests.cpp b/src/Tests.cpp
index bdde63b..3481028 100644
--- a/src/Tests.cpp
+++ b/src/Tests.cpp
@@ -3104,6 +3104,20 @@
     res = vmaCreatePool(g_hAllocator, &poolCreateInfo, &pool);

     TEST(res == VK_SUCCESS);

 

+    // Test pool name

+    {

+        static const char* const POOL_NAME = "Pool name";

+        vmaSetPoolName(g_hAllocator, pool, POOL_NAME);

+

+        const char* fetchedPoolName = nullptr;

+        vmaGetPoolName(g_hAllocator, pool, &fetchedPoolName);

+        TEST(strcmp(fetchedPoolName, POOL_NAME) == 0);

+

+        SaveAllocatorStatsToFile(L"TEST.json");//DELME

+

+        vmaSetPoolName(g_hAllocator, pool, nullptr);

+    }

+

     vmaSetCurrentFrameIndex(g_hAllocator, 1);

 

     VmaAllocationCreateInfo allocInfo = {};

diff --git a/src/vk_mem_alloc.h b/src/vk_mem_alloc.h
index c3d999e..e6ceda2 100644
--- a/src/vk_mem_alloc.h
+++ b/src/vk_mem_alloc.h
@@ -2512,6 +2512,20 @@
 */

 VMA_CALL_PRE VkResult VMA_CALL_POST vmaCheckPoolCorruption(VmaAllocator allocator, VmaPool pool);

 

+/** TODO

+*/

+VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char** ppName);

+

+/* TODO

+*/

+VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char* pName);

+

 /** \struct VmaAllocation

 \brief Represents single memory allocation.

 

@@ -4038,6 +4052,30 @@
     }

 }

 

+static char* VmaCreateStringCopy(const VkAllocationCallbacks* allocs, const char* srcStr)

+{

+    if(srcStr != VMA_NULL)

+    {

+        const size_t len = strlen(srcStr);

+        char* const result = vma_new_array(allocs, char, len + 1);

+        memcpy(result, srcStr, len + 1);

+        return result;

+    }

+    else

+    {

+        return VMA_NULL;

+    }

+}

+

+static void VmaFreeString(const VkAllocationCallbacks* allocs, char* str)

+{

+    if(str != VMA_NULL)

+    {

+        const size_t len = strlen(str);

+        vma_delete_array(allocs, str, len + 1);

+    }

+}

+

 // STL-compatible allocator.

 template<typename T>

 class VmaStlAllocator

@@ -5994,6 +6032,7 @@
 

     VkResult CreateMinBlocks();

 

+    VmaAllocator GetAllocator() const { return m_hAllocator; }

     VmaPool GetParentPool() const { return m_hParentPool; }

     uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }

     VkDeviceSize GetPreferredBlockSize() const { return m_PreferredBlockSize; }

@@ -6135,12 +6174,16 @@
     uint32_t GetId() const { return m_Id; }

     void SetId(uint32_t id) { VMA_ASSERT(m_Id == 0); m_Id = id; }

 

+    const char* GetName() const { return m_Name; }

+    void SetName(const char* pName);

+

 #if VMA_STATS_STRING_ENABLED

     //void PrintDetailedMap(class VmaStringBuilder& sb);

 #endif

 

 private:

     uint32_t m_Id;

+    char* m_Name;

 };

 

 /*

@@ -7388,11 +7431,7 @@
 

         if(pUserData != VMA_NULL)

         {

-            const char* const newStrSrc = (char*)pUserData;

-            const size_t newStrLen = strlen(newStrSrc);

-            char* const newStrDst = vma_new_array(hAllocator, char, newStrLen + 1);

-            memcpy(newStrDst, newStrSrc, newStrLen + 1);

-            m_pUserData = newStrDst;

+            m_pUserData = VmaCreateStringCopy(hAllocator->GetAllocationCallbacks(), (const char*)pUserData);

         }

     }

     else

@@ -7595,13 +7634,8 @@
 void VmaAllocation_T::FreeUserDataString(VmaAllocator hAllocator)

 {

     VMA_ASSERT(IsUserDataString());

-    if(m_pUserData != VMA_NULL)

-    {

-        char* const oldStr = (char*)m_pUserData;

-        const size_t oldStrLen = strlen(oldStr);

-        vma_delete_array(hAllocator, oldStr, oldStrLen + 1);

-        m_pUserData = VMA_NULL;

-    }

+    VmaFreeString(hAllocator->GetAllocationCallbacks(), (char*)m_pUserData);

+    m_pUserData = VMA_NULL;

 }

 

 void VmaAllocation_T::BlockAllocMap()

@@ -11407,7 +11441,8 @@
         true, // isCustomPool

         createInfo.blockSize != 0, // explicitBlockSize

         createInfo.flags & VMA_POOL_CREATE_ALGORITHM_MASK), // algorithm

-    m_Id(0)

+    m_Id(0),

+    m_Name(VMA_NULL)

 {

 }

 

@@ -11415,6 +11450,21 @@
 {

 }

 

+void VmaPool_T::SetName(const char* pName)

+{

+    const VkAllocationCallbacks* allocs = m_BlockVector.GetAllocator()->GetAllocationCallbacks();

+    VmaFreeString(allocs, m_Name);

+    

+    if(pName != VMA_NULL)

+    {

+        m_Name = VmaCreateStringCopy(allocs, pName);

+    }

+    else

+    {

+        m_Name = VMA_NULL;

+    }

+}

+

 #if VMA_STATS_STRING_ENABLED

 

 #endif // #if VMA_STATS_STRING_ENABLED

@@ -15769,6 +15819,15 @@
             {

                 json.BeginString();

                 json.ContinueString(m_Pools[poolIndex]->GetId());

+                const char* poolName = m_Pools[poolIndex]->GetName();

+                if(poolName != VMA_NULL && poolName[0] != '\0')

+                {

+                    json.ContinueString(" ");

+                    json.ContinueString(poolName);

+                }

+                else

+                {

+                }

                 json.EndString();

 

                 m_Pools[poolIndex]->m_BlockVector.PrintDetailedMap(json);

@@ -16213,6 +16272,34 @@
     return allocator->CheckPoolCorruption(pool);

 }

 

+VMA_CALL_PRE void VMA_CALL_POST vmaGetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char** ppName)

+{

+    VMA_ASSERT(allocator && pool);

+    

+    VMA_DEBUG_LOG("vmaGetPoolName");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    *ppName = pool->GetName();

+}

+

+VMA_CALL_PRE void VMA_CALL_POST vmaSetPoolName(

+    VmaAllocator allocator,

+    VmaPool pool,

+    const char* pName)

+{

+    VMA_ASSERT(allocator && pool);

+

+    VMA_DEBUG_LOG("vmaSetPoolName");

+

+    VMA_DEBUG_GLOBAL_MUTEX_LOCK

+

+    pool->SetName(pName);

+}

+

 VMA_CALL_PRE VkResult VMA_CALL_POST vmaAllocateMemory(

     VmaAllocator allocator,

     const VkMemoryRequirements* pVkMemoryRequirements,

diff --git a/tools/VmaDumpVis/VmaDumpVis.py b/tools/VmaDumpVis/VmaDumpVis.py
index 9b6298b..6bec3ee 100644
--- a/tools/VmaDumpVis/VmaDumpVis.py
+++ b/tools/VmaDumpVis/VmaDumpVis.py
@@ -189,13 +189,13 @@
             ProcessBlock(typeData['DefaultPoolBlocks'], int(sBlockId), objBlock, '')

 if 'Pools' in jsonSrc:

     objPools = jsonSrc['Pools']

-    for sPoolId, objPool in objPools.items():

+    for sPoolName, objPool in objPools.items():

         iType = int(objPool['MemoryTypeIndex'])

         typeData = GetDataForMemoryType(iType)

         objBlocks = objPool['Blocks']

         sAlgorithm = objPool.get('Algorithm', '')

         dstBlockArray = []

-        typeData['CustomPools'][int(sPoolId)] = dstBlockArray

+        typeData['CustomPools'][sPoolName] = dstBlockArray

         for sBlockId, objBlock in objBlocks.items():

             ProcessBlock(dstBlockArray, int(sBlockId), objBlock, sAlgorithm)

 

@@ -249,13 +249,13 @@
         DrawBlock(draw, y, objBlock)

         y += MAP_SIZE + IMG_MARGIN

     index = 0

-    for iPoolId, listPool in dictMemType['CustomPools'].items():

+    for sPoolName, listPool in dictMemType['CustomPools'].items():

         for objBlock in listPool:

             if 'Algorithm' in objBlock and objBlock['Algorithm']:

                 sAlgorithm = ' (Algorithm: %s)' % (objBlock['Algorithm'])

             else:

                 sAlgorithm = ''

-            draw.text((IMG_MARGIN, y), "Custom pool %d%s block %d" % (iPoolId, sAlgorithm, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)

+            draw.text((IMG_MARGIN, y), "Custom pool \"%s\"%s block %d" % (sPoolName, sAlgorithm, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)

             y += FONT_SIZE + IMG_MARGIN

             DrawBlock(draw, y, objBlock)

             y += MAP_SIZE + IMG_MARGIN

@@ -274,7 +274,7 @@
     - Fixed key 'Size'. Value is int.

     - Fixed key 'Suballocations'. Value is list of tuples as above.

 - Fixed key 'CustomPools'. Value is dictionary.

-  - Key is integer pool ID. Value is list of objects representing memory blocks, each containing dictionary with:

+  - Key is string with pool name. Value is list of objects representing memory blocks, each containing dictionary with:

     - Fixed key 'ID'. Value is int.

     - Fixed key 'Size'. Value is int.

     - Fixed key 'Algorithm'. Optional. Value is string.