1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-02 10:24:12 +01:00

[dxvk] Add detailed allocation statistics

This commit is contained in:
Philip Rebohle 2024-09-19 01:05:10 +02:00 committed by Philip Rebohle
parent b46ef2ceff
commit f679d7d90f
4 changed files with 108 additions and 2 deletions

View File

@ -235,6 +235,11 @@ namespace dxvk {
}
void DxvkDevice::getMemoryAllocationStats(DxvkMemoryAllocationStats& stats) {
return m_objects.memoryManager().getAllocationStats(stats);
}
uint32_t DxvkDevice::getCurrentFrameId() const {
return m_statCounters.getCtr(DxvkStatCounter::QueuePresentCount);
}

View File

@ -396,13 +396,21 @@ namespace dxvk {
DxvkStatCounters getStatCounters();
/**
* \brief Retrieves memors statistics
* \brief Queries memory statistics
*
* \param [in] heap Memory heap index
* \returns Memory stats for this heap
* \returns Memory usage for this heap
*/
DxvkMemoryStats getMemoryStats(uint32_t heap);
/**
* \brief Queries detailed memory allocation statistics
*
* Expensive, should be used with caution.
* \param [out] stats Allocation statistics
*/
void getMemoryAllocationStats(DxvkMemoryAllocationStats& stats);
/**
* \brief Retreves current frame ID
* \returns Current frame ID

View File

@ -135,6 +135,18 @@ namespace dxvk {
}
void DxvkMemoryChunk::getAllocationStats(DxvkMemoryAllocationStats& stats) const {
auto& chunkStats = stats.chunks.emplace_back();
chunkStats.capacity = uint64_t(m_pageAllocator.pageCount()) * DxvkPageAllocator::PageSize;
chunkStats.used = uint64_t(m_pageAllocator.pagesUsed()) * DxvkPageAllocator::PageSize;
chunkStats.pageMaskOffset = stats.pageMasks.size();
chunkStats.pageCount = m_pageAllocator.pageCount();
stats.pageMasks.resize(chunkStats.pageMaskOffset + (chunkStats.pageCount + 31u) / 32u);
m_pageAllocator.getPageAllocationMask(&stats.pageMasks.at(chunkStats.pageMaskOffset));
}
void DxvkMemoryChunk::mapChunk() {
if (m_memory.memPointer)
return;
@ -734,6 +746,27 @@ namespace dxvk {
}
void DxvkMemoryAllocator::getAllocationStats(DxvkMemoryAllocationStats& stats) {
std::lock_guard<dxvk::mutex> lock(m_mutex);
stats.chunks.clear();
stats.pageMasks.clear();
for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) {
const auto& type = m_memTypes[i];
stats.memoryTypes[i].properties = type.memType;
stats.memoryTypes[i].allocated = type.stats.memoryAllocated;
stats.memoryTypes[i].used = type.stats.memoryUsed;
stats.memoryTypes[i].chunkIndex = stats.chunks.size();
stats.memoryTypes[i].chunkCount = type.chunks.size();
for (const auto& chunk : type.chunks)
chunk->getAllocationStats(stats);
}
}
bool DxvkMemoryAllocator::getBufferMemoryRequirements(
const VkBufferCreateInfo& createInfo,
VkMemoryRequirements2& memoryRequirements) const {

View File

@ -91,6 +91,49 @@ namespace dxvk {
};
/**
* \brief Memory type statistics
*/
struct DxvkMemoryTypeStats {
/// Memory type properties
VkMemoryType properties = { };
/// Amount of memory allocated
VkDeviceSize allocated = 0u;
/// Amount of memory used
VkDeviceSize used = 0u;
/// First chunk in the array
size_t chunkIndex = 0u;
/// Number of chunks allocated
size_t chunkCount = 0u;
};
/**
* \brief Chunk statistics
*/
struct DxvkMemoryChunkStats {
/// Chunk size, in bytes
VkDeviceSize capacity = 0u;
/// Used memory, in bytes
VkDeviceSize used = 0u;
/// Index of first page mask belonging to this
/// chunk in the page mask array
size_t pageMaskOffset = 0u;
/// Number of pages in this chunk.
size_t pageCount = 0u;
};
/**
* \brief Detailed memory allocation statistics
*/
struct DxvkMemoryAllocationStats {
std::array<DxvkMemoryTypeStats, VK_MAX_MEMORY_TYPES> memoryTypes = { };
std::vector<DxvkMemoryChunkStats> chunks;
std::vector<uint32_t> pageMasks;
};
/**
* \brief Memory slice
*
@ -260,6 +303,14 @@ namespace dxvk {
*/
bool isEmpty() const;
/**
* \brief Retrieves allocation stats for this chunk
*
* Adds overall stats and the page mask to the given structure.
* \param [out] stats Allocation stats
*/
void getAllocationStats(DxvkMemoryAllocationStats& stats) const;
private:
DxvkMemoryAllocator* m_alloc;
@ -349,6 +400,15 @@ namespace dxvk {
*/
DxvkMemoryStats getMemoryStats(uint32_t heap) const;
/**
* \brief Retrieves detailed memory statistics
*
* Queries statistics for each memory type and each allocated chunk.
* Can be useful to determine the degree of memory fragmentation.
* \param [out] stats Memory statistics
*/
void getAllocationStats(DxvkMemoryAllocationStats& stats);
/**
* \brief Queries buffer memory requirements
*