mirror of
https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
synced 2024-09-20 06:32:16 +00:00
Added subsequent, unique, numeric IDs to memory blocks and custom pools. They are dumped in JSON. JSON format changed: "Pools" and "Blocks" arrays are now objects, where key is pool/block ID, and value is as before. Applied appropriate changes in VmaDumpVis.py - it now shows pool and block ID from the dump.
This commit is contained in:
parent
31695cf349
commit
6a0a85a5c0
@ -4147,12 +4147,14 @@ public:
|
|||||||
void Init(
|
void Init(
|
||||||
uint32_t newMemoryTypeIndex,
|
uint32_t newMemoryTypeIndex,
|
||||||
VkDeviceMemory newMemory,
|
VkDeviceMemory newMemory,
|
||||||
VkDeviceSize newSize);
|
VkDeviceSize newSize,
|
||||||
|
uint32_t id);
|
||||||
// Always call before destruction.
|
// Always call before destruction.
|
||||||
void Destroy(VmaAllocator allocator);
|
void Destroy(VmaAllocator allocator);
|
||||||
|
|
||||||
VkDeviceMemory GetDeviceMemory() const { return m_hMemory; }
|
VkDeviceMemory GetDeviceMemory() const { return m_hMemory; }
|
||||||
uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
|
uint32_t GetMemoryTypeIndex() const { return m_MemoryTypeIndex; }
|
||||||
|
uint32_t GetId() const { return m_Id; }
|
||||||
void* GetMappedData() const { return m_pMappedData; }
|
void* GetMappedData() const { return m_pMappedData; }
|
||||||
|
|
||||||
// Validates all data structures inside this object. If not valid, returns false.
|
// Validates all data structures inside this object. If not valid, returns false.
|
||||||
@ -4173,6 +4175,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_MemoryTypeIndex;
|
uint32_t m_MemoryTypeIndex;
|
||||||
|
uint32_t m_Id;
|
||||||
VkDeviceMemory m_hMemory;
|
VkDeviceMemory m_hMemory;
|
||||||
|
|
||||||
// Protects access to m_hMemory so it's not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.
|
// Protects access to m_hMemory so it's not used by multiple threads simultaneously, e.g. vkMapMemory, vkBindBufferMemory.
|
||||||
@ -4276,6 +4279,7 @@ private:
|
|||||||
of a VkDeviceMemory. */
|
of a VkDeviceMemory. */
|
||||||
bool m_HasEmptyBlock;
|
bool m_HasEmptyBlock;
|
||||||
VmaDefragmentator* m_pDefragmentator;
|
VmaDefragmentator* m_pDefragmentator;
|
||||||
|
uint32_t m_NextBlockId;
|
||||||
|
|
||||||
VkDeviceSize CalcMaxBlockSize() const;
|
VkDeviceSize CalcMaxBlockSize() const;
|
||||||
|
|
||||||
@ -4295,17 +4299,21 @@ struct VmaPool_T
|
|||||||
public:
|
public:
|
||||||
VmaBlockVector m_BlockVector;
|
VmaBlockVector m_BlockVector;
|
||||||
|
|
||||||
// Takes ownership.
|
|
||||||
VmaPool_T(
|
VmaPool_T(
|
||||||
VmaAllocator hAllocator,
|
VmaAllocator hAllocator,
|
||||||
const VmaPoolCreateInfo& createInfo);
|
const VmaPoolCreateInfo& createInfo);
|
||||||
~VmaPool_T();
|
~VmaPool_T();
|
||||||
|
|
||||||
VmaBlockVector& GetBlockVector() { return m_BlockVector; }
|
VmaBlockVector& GetBlockVector() { return m_BlockVector; }
|
||||||
|
uint32_t GetId() const { return m_Id; }
|
||||||
|
void SetId(uint32_t id) { VMA_ASSERT(m_Id == 0); m_Id = id; }
|
||||||
|
|
||||||
#if VMA_STATS_STRING_ENABLED
|
#if VMA_STATS_STRING_ENABLED
|
||||||
//void PrintDetailedMap(class VmaStringBuilder& sb);
|
//void PrintDetailedMap(class VmaStringBuilder& sb);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t m_Id;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VmaDefragmentator
|
class VmaDefragmentator
|
||||||
@ -4569,6 +4577,7 @@ private:
|
|||||||
VMA_MUTEX m_PoolsMutex;
|
VMA_MUTEX m_PoolsMutex;
|
||||||
// Protected by m_PoolsMutex. Sorted by pointer value.
|
// Protected by m_PoolsMutex. Sorted by pointer value.
|
||||||
VmaVector<VmaPool, VmaStlAllocator<VmaPool> > m_Pools;
|
VmaVector<VmaPool, VmaStlAllocator<VmaPool> > m_Pools;
|
||||||
|
uint32_t m_NextPoolId;
|
||||||
|
|
||||||
VmaVulkanFunctions m_VulkanFunctions;
|
VmaVulkanFunctions m_VulkanFunctions;
|
||||||
|
|
||||||
@ -6366,6 +6375,7 @@ void VmaBlockMetadata::UnregisterFreeSuballocation(VmaSuballocationList::iterato
|
|||||||
VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) :
|
VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) :
|
||||||
m_Metadata(hAllocator),
|
m_Metadata(hAllocator),
|
||||||
m_MemoryTypeIndex(UINT32_MAX),
|
m_MemoryTypeIndex(UINT32_MAX),
|
||||||
|
m_Id(0),
|
||||||
m_hMemory(VK_NULL_HANDLE),
|
m_hMemory(VK_NULL_HANDLE),
|
||||||
m_MapCount(0),
|
m_MapCount(0),
|
||||||
m_pMappedData(VMA_NULL)
|
m_pMappedData(VMA_NULL)
|
||||||
@ -6375,11 +6385,13 @@ VmaDeviceMemoryBlock::VmaDeviceMemoryBlock(VmaAllocator hAllocator) :
|
|||||||
void VmaDeviceMemoryBlock::Init(
|
void VmaDeviceMemoryBlock::Init(
|
||||||
uint32_t newMemoryTypeIndex,
|
uint32_t newMemoryTypeIndex,
|
||||||
VkDeviceMemory newMemory,
|
VkDeviceMemory newMemory,
|
||||||
VkDeviceSize newSize)
|
VkDeviceSize newSize,
|
||||||
|
uint32_t id)
|
||||||
{
|
{
|
||||||
VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
|
VMA_ASSERT(m_hMemory == VK_NULL_HANDLE);
|
||||||
|
|
||||||
m_MemoryTypeIndex = newMemoryTypeIndex;
|
m_MemoryTypeIndex = newMemoryTypeIndex;
|
||||||
|
m_Id = id;
|
||||||
m_hMemory = newMemory;
|
m_hMemory = newMemory;
|
||||||
|
|
||||||
m_Metadata.Init(newSize);
|
m_Metadata.Init(newSize);
|
||||||
@ -6572,7 +6584,8 @@ VmaBlockVector::VmaBlockVector(
|
|||||||
m_IsCustomPool(isCustomPool),
|
m_IsCustomPool(isCustomPool),
|
||||||
m_Blocks(VmaStlAllocator<VmaDeviceMemoryBlock*>(hAllocator->GetAllocationCallbacks())),
|
m_Blocks(VmaStlAllocator<VmaDeviceMemoryBlock*>(hAllocator->GetAllocationCallbacks())),
|
||||||
m_HasEmptyBlock(false),
|
m_HasEmptyBlock(false),
|
||||||
m_pDefragmentator(VMA_NULL)
|
m_pDefragmentator(VMA_NULL),
|
||||||
|
m_NextBlockId(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7000,7 +7013,8 @@ VkResult VmaBlockVector::CreateBlock(VkDeviceSize blockSize, size_t* pNewBlockIn
|
|||||||
pBlock->Init(
|
pBlock->Init(
|
||||||
m_MemoryTypeIndex,
|
m_MemoryTypeIndex,
|
||||||
mem,
|
mem,
|
||||||
allocInfo.allocationSize);
|
allocInfo.allocationSize,
|
||||||
|
m_NextBlockId++);
|
||||||
|
|
||||||
m_Blocks.push_back(pBlock);
|
m_Blocks.push_back(pBlock);
|
||||||
if(pNewBlockIndex != VMA_NULL)
|
if(pNewBlockIndex != VMA_NULL)
|
||||||
@ -7056,12 +7070,16 @@ void VmaBlockVector::PrintDetailedMap(class VmaJsonWriter& json)
|
|||||||
}
|
}
|
||||||
|
|
||||||
json.WriteString("Blocks");
|
json.WriteString("Blocks");
|
||||||
json.BeginArray();
|
json.BeginObject();
|
||||||
for(size_t i = 0; i < m_Blocks.size(); ++i)
|
for(size_t i = 0; i < m_Blocks.size(); ++i)
|
||||||
{
|
{
|
||||||
|
json.BeginString();
|
||||||
|
json.ContinueString(m_Blocks[i]->GetId());
|
||||||
|
json.EndString();
|
||||||
|
|
||||||
m_Blocks[i]->m_Metadata.PrintDetailedMap(json);
|
m_Blocks[i]->m_Metadata.PrintDetailedMap(json);
|
||||||
}
|
}
|
||||||
json.EndArray();
|
json.EndObject();
|
||||||
|
|
||||||
json.EndObject();
|
json.EndObject();
|
||||||
}
|
}
|
||||||
@ -7481,7 +7499,8 @@ VmaAllocator_T::VmaAllocator_T(const VmaAllocatorCreateInfo* pCreateInfo) :
|
|||||||
m_PreferredLargeHeapBlockSize(0),
|
m_PreferredLargeHeapBlockSize(0),
|
||||||
m_PhysicalDevice(pCreateInfo->physicalDevice),
|
m_PhysicalDevice(pCreateInfo->physicalDevice),
|
||||||
m_CurrentFrameIndex(0),
|
m_CurrentFrameIndex(0),
|
||||||
m_Pools(VmaStlAllocator<VmaPool>(GetAllocationCallbacks()))
|
m_Pools(VmaStlAllocator<VmaPool>(GetAllocationCallbacks())),
|
||||||
|
m_NextPoolId(0)
|
||||||
{
|
{
|
||||||
VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device);
|
VMA_ASSERT(pCreateInfo->physicalDevice && pCreateInfo->device);
|
||||||
|
|
||||||
@ -8372,6 +8391,7 @@ VkResult VmaAllocator_T::CreatePool(const VmaPoolCreateInfo* pCreateInfo, VmaPoo
|
|||||||
// Add to m_Pools.
|
// Add to m_Pools.
|
||||||
{
|
{
|
||||||
VmaMutexLock lock(m_PoolsMutex, m_UseMutex);
|
VmaMutexLock lock(m_PoolsMutex, m_UseMutex);
|
||||||
|
(*pPool)->SetId(m_NextPoolId++);
|
||||||
VmaVectorInsertSorted<VmaPointerLess>(m_Pools, *pPool);
|
VmaVectorInsertSorted<VmaPointerLess>(m_Pools, *pPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8662,12 +8682,16 @@ void VmaAllocator_T::PrintDetailedMap(VmaJsonWriter& json)
|
|||||||
if(poolCount > 0)
|
if(poolCount > 0)
|
||||||
{
|
{
|
||||||
json.WriteString("Pools");
|
json.WriteString("Pools");
|
||||||
json.BeginArray();
|
json.BeginObject();
|
||||||
for(size_t poolIndex = 0; poolIndex < poolCount; ++poolIndex)
|
for(size_t poolIndex = 0; poolIndex < poolCount; ++poolIndex)
|
||||||
{
|
{
|
||||||
|
json.BeginString();
|
||||||
|
json.ContinueString(m_Pools[poolIndex]->GetId());
|
||||||
|
json.EndString();
|
||||||
|
|
||||||
m_Pools[poolIndex]->m_BlockVector.PrintDetailedMap(json);
|
m_Pools[poolIndex]->m_BlockVector.PrintDetailedMap(json);
|
||||||
}
|
}
|
||||||
json.EndArray();
|
json.EndObject();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,10 +46,10 @@ args = argParser.parse_args()
|
|||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
|
|
||||||
def ProcessBlock(dstBlockList, objBlock):
|
def ProcessBlock(dstBlockList, iBlockId, objBlock):
|
||||||
iBlockSize = int(objBlock['TotalBytes'])
|
iBlockSize = int(objBlock['TotalBytes'])
|
||||||
arrSuballocs = objBlock['Suballocations']
|
arrSuballocs = objBlock['Suballocations']
|
||||||
dstBlockObj = {'Size':iBlockSize, 'Suballocations':[]}
|
dstBlockObj = {'ID': iBlockId, 'Size':iBlockSize, 'Suballocations':[]}
|
||||||
dstBlockList.append(dstBlockObj)
|
dstBlockList.append(dstBlockObj)
|
||||||
for objSuballoc in arrSuballocs:
|
for objSuballoc in arrSuballocs:
|
||||||
dstBlockObj['Suballocations'].append((objSuballoc['Type'], int(objSuballoc['Size']), int(objSuballoc['Usage']) if ('Usage' in objSuballoc) else 0))
|
dstBlockObj['Suballocations'].append((objSuballoc['Type'], int(objSuballoc['Size']), int(objSuballoc['Usage']) if ('Usage' in objSuballoc) else 0))
|
||||||
@ -60,7 +60,7 @@ def GetDataForMemoryType(iMemTypeIndex):
|
|||||||
if iMemTypeIndex in data:
|
if iMemTypeIndex in data:
|
||||||
return data[iMemTypeIndex]
|
return data[iMemTypeIndex]
|
||||||
else:
|
else:
|
||||||
newMemTypeData = {'DedicatedAllocations':[], 'DefaultPoolBlocks':[], 'CustomPoolBlocks':[]}
|
newMemTypeData = {'DedicatedAllocations':[], 'DefaultPoolBlocks':[], 'CustomPools':{}}
|
||||||
data[iMemTypeIndex] = newMemTypeData
|
data[iMemTypeIndex] = newMemTypeData
|
||||||
return newMemTypeData
|
return newMemTypeData
|
||||||
|
|
||||||
@ -81,9 +81,10 @@ def CalcParams():
|
|||||||
iImgSizeY += len(dictMemType['DefaultPoolBlocks']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
iImgSizeY += len(dictMemType['DefaultPoolBlocks']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||||
for objBlock in dictMemType['DefaultPoolBlocks']:
|
for objBlock in dictMemType['DefaultPoolBlocks']:
|
||||||
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
||||||
iImgSizeY += len(dictMemType['CustomPoolBlocks']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
iImgSizeY += len(dictMemType['CustomPools']) * (IMG_MARGIN * 2 + FONT_SIZE + MAP_SIZE)
|
||||||
for objBlock in dictMemType['CustomPoolBlocks']:
|
for listPool in dictMemType['CustomPools'].values():
|
||||||
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
for objBlock in listPool:
|
||||||
|
iMaxBlockSize = max(iMaxBlockSize, objBlock['Size'])
|
||||||
fPixelsPerByte = (IMG_SIZE_X - IMG_MARGIN * 2) / float(iMaxBlockSize)
|
fPixelsPerByte = (IMG_SIZE_X - IMG_MARGIN * 2) / float(iMaxBlockSize)
|
||||||
return iImgSizeY, fPixelsPerByte
|
return iImgSizeY, fPixelsPerByte
|
||||||
|
|
||||||
@ -180,16 +181,17 @@ if 'DefaultPools' in jsonSrc:
|
|||||||
assert sType[:5] == 'Type '
|
assert sType[:5] == 'Type '
|
||||||
iType = int(sType[5:])
|
iType = int(sType[5:])
|
||||||
typeData = GetDataForMemoryType(iType)
|
typeData = GetDataForMemoryType(iType)
|
||||||
for objBlock in tType[1]['Blocks']:
|
for sBlockId, objBlock in tType[1]['Blocks'].items():
|
||||||
ProcessBlock(typeData['DefaultPoolBlocks'], objBlock)
|
ProcessBlock(typeData['DefaultPoolBlocks'], int(sBlockId), objBlock)
|
||||||
if 'Pools' in jsonSrc:
|
if 'Pools' in jsonSrc:
|
||||||
arrPools = jsonSrc['Pools']
|
objPools = jsonSrc['Pools']
|
||||||
for objPool in arrPools:
|
for sPoolId, objPool in objPools.items():
|
||||||
iType = int(objPool['MemoryTypeIndex'])
|
iType = int(objPool['MemoryTypeIndex'])
|
||||||
typeData = GetDataForMemoryType(iType)
|
typeData = GetDataForMemoryType(iType)
|
||||||
arrBlocks = objPool['Blocks']
|
objBlocks = objPool['Blocks']
|
||||||
for objBlock in arrBlocks:
|
for sBlockId, objBlock in objBlocks.items():
|
||||||
ProcessBlock(typeData['CustomPoolBlocks'], objBlock)
|
typeData['CustomPools'][int(sPoolId)] = []
|
||||||
|
ProcessBlock(typeData['CustomPools'][int(sPoolId)], int(sBlockId), objBlock)
|
||||||
|
|
||||||
iImgSizeY, fPixelsPerByte = CalcParams()
|
iImgSizeY, fPixelsPerByte = CalcParams()
|
||||||
|
|
||||||
@ -230,20 +232,19 @@ for iMemTypeIndex in sorted(data.keys()):
|
|||||||
DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc)
|
DrawDedicatedAllocationBlock(draw, y, tDedicatedAlloc)
|
||||||
y += MAP_SIZE + IMG_MARGIN
|
y += MAP_SIZE + IMG_MARGIN
|
||||||
index += 1
|
index += 1
|
||||||
index = 0
|
|
||||||
for objBlock in dictMemType['DefaultPoolBlocks']:
|
for objBlock in dictMemType['DefaultPoolBlocks']:
|
||||||
draw.text((IMG_MARGIN, y), "Default pool block %d" % index, fill=COLOR_TEXT_H2, font=font)
|
draw.text((IMG_MARGIN, y), "Default pool block %d" % objBlock['ID'], fill=COLOR_TEXT_H2, font=font)
|
||||||
y += FONT_SIZE + IMG_MARGIN
|
y += FONT_SIZE + IMG_MARGIN
|
||||||
DrawBlock(draw, y, objBlock)
|
DrawBlock(draw, y, objBlock)
|
||||||
y += MAP_SIZE + IMG_MARGIN
|
y += MAP_SIZE + IMG_MARGIN
|
||||||
index += 1
|
|
||||||
index = 0
|
index = 0
|
||||||
for objBlock in dictMemType['CustomPoolBlocks']:
|
for iPoolId, listPool in dictMemType['CustomPools'].items():
|
||||||
draw.text((IMG_MARGIN, y), "Custom pool block %d" % index, fill=COLOR_TEXT_H2, font=font)
|
for objBlock in listPool:
|
||||||
y += FONT_SIZE + IMG_MARGIN
|
draw.text((IMG_MARGIN, y), "Custom pool %d block %d" % (iPoolId, objBlock['ID']), fill=COLOR_TEXT_H2, font=font)
|
||||||
DrawBlock(draw, y, objBlock)
|
y += FONT_SIZE + IMG_MARGIN
|
||||||
y += MAP_SIZE + IMG_MARGIN
|
DrawBlock(draw, y, objBlock)
|
||||||
index += 1
|
y += MAP_SIZE + IMG_MARGIN
|
||||||
|
index += 1
|
||||||
del draw
|
del draw
|
||||||
img.save(args.output)
|
img.save(args.output)
|
||||||
|
|
||||||
@ -254,9 +255,12 @@ Main data structure - variable `data` - is a dictionary. Key is integer - memory
|
|||||||
- [1]: Size : integer
|
- [1]: Size : integer
|
||||||
- [2]: Usage : integer (0 if unknown)
|
- [2]: Usage : integer (0 if unknown)
|
||||||
- Fixed key 'DefaultPoolBlocks'. Value is list of objects, each containing dictionary with:
|
- Fixed key 'DefaultPoolBlocks'. Value is list of objects, each containing dictionary with:
|
||||||
|
- Fixed key 'ID'. Value is int.
|
||||||
- Fixed key 'Size'. Value is int.
|
- Fixed key 'Size'. Value is int.
|
||||||
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
||||||
- Fixed key 'CustomPoolBlocks'. Value is list of objects, each containing dictionary with:
|
- Fixed key 'CustomPools'. Value is dictionary.
|
||||||
|
- Key is integer pool ID. Value is list of objects, each containing dictionary with:
|
||||||
|
- Fixed key 'ID'. Value is int.
|
||||||
- Fixed key 'Size'. Value is int.
|
- Fixed key 'Size'. Value is int.
|
||||||
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
- Fixed key 'Suballocations'. Value is list of tuples as above.
|
||||||
"""
|
"""
|
||||||
|
Loading…
Reference in New Issue
Block a user