diff --git a/src/dxvk/dxvk_device.cpp b/src/dxvk/dxvk_device.cpp index 5dc8627a6..57d6b34cc 100644 --- a/src/dxvk/dxvk_device.cpp +++ b/src/dxvk/dxvk_device.cpp @@ -179,8 +179,11 @@ namespace dxvk { DxvkStatCounters DxvkDevice::getStatCounters() { - // TODO Add memory info + DxvkMemoryStats mem = m_memory->getMemoryStats(); + DxvkStatCounters result; + result.setCtr(DxvkStatCounter::MemoryAllocated, mem.memoryAllocated); + result.setCtr(DxvkStatCounter::MemoryUsed, mem.memoryUsed); { std::lock_guard lock(m_statLock); result.merge(m_statCounters); diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 3036ef637..605b41f04 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -19,7 +19,10 @@ namespace dxvk { m_memory (memory), m_offset (offset), m_length (length), - m_mapPtr (mapPtr) { } + m_mapPtr (mapPtr) { + if (m_memory != VK_NULL_HANDLE) + m_heap->m_memoryUsed += length; + } DxvkMemory::DxvkMemory(DxvkMemory&& other) @@ -32,6 +35,7 @@ namespace dxvk { DxvkMemory& DxvkMemory::operator = (DxvkMemory&& other) { + this->free(); m_chunk = std::exchange(other.m_chunk, nullptr); m_heap = std::exchange(other.m_heap, nullptr); m_memory = std::exchange(other.m_memory, VkDeviceMemory(VK_NULL_HANDLE)); @@ -43,10 +47,18 @@ namespace dxvk { DxvkMemory::~DxvkMemory() { - if (m_chunk != nullptr) + this->free(); + } + + + void DxvkMemory::free() { + if (m_chunk != nullptr) { m_heap->free(m_chunk, m_offset, m_length); - else if (m_heap != nullptr) - m_heap->freeDeviceMemory(m_memory); + m_heap->m_memoryUsed -= m_length; + } else if (m_memory != VK_NULL_HANDLE) { + m_heap->freeDeviceMemory(m_memory, m_length); + m_heap->m_memoryUsed -= m_length; + } } @@ -65,7 +77,7 @@ namespace dxvk { DxvkMemoryChunk::~DxvkMemoryChunk() { - m_heap->freeDeviceMemory(m_memory); + m_heap->freeDeviceMemory(m_memory, m_size); } @@ -194,6 +206,14 @@ namespace dxvk { } + DxvkMemoryStats DxvkMemoryHeap::getMemoryStats() const { + DxvkMemoryStats result; + result.memoryAllocated = m_memoryAllocated.load(); + result.memoryUsed = m_memoryUsed.load(); + return result; + } + + VkDeviceMemory DxvkMemoryHeap::allocDeviceMemory(VkDeviceSize memorySize) { VkMemoryAllocateInfo info; info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; @@ -207,12 +227,14 @@ namespace dxvk { &info, nullptr, &memory) != VK_SUCCESS) return VK_NULL_HANDLE; + m_memoryAllocated += memorySize; return memory; } - void DxvkMemoryHeap::freeDeviceMemory(VkDeviceMemory memory) { + void DxvkMemoryHeap::freeDeviceMemory(VkDeviceMemory memory, VkDeviceSize memorySize) { m_vkd->vkFreeMemory(m_vkd->device(), memory, nullptr); + m_memoryAllocated -= memorySize; } @@ -275,6 +297,22 @@ namespace dxvk { } + DxvkMemoryStats DxvkMemoryAllocator::getMemoryStats() const { + DxvkMemoryStats totalStats; + + for (size_t i = 0; i < m_heaps.size(); i++) { + if (m_heaps[i] != nullptr) { + DxvkMemoryStats heapStats = m_heaps[i]->getMemoryStats(); + + totalStats.memoryAllocated += heapStats.memoryAllocated; + totalStats.memoryUsed += heapStats.memoryUsed; + } + } + + return totalStats; + } + + DxvkMemory DxvkMemoryAllocator::tryAlloc( const VkMemoryRequirements& req, const VkMemoryPropertyFlags flags) { diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 436dcb954..264170b02 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -8,6 +8,17 @@ namespace dxvk { class DxvkMemoryChunk; class DxvkMemoryAllocator; + /** + * \brief Memory stats + * + * Reports the amount of device memory + * allocated and used by the application. + */ + struct DxvkMemoryStats { + VkDeviceSize memoryAllocated = 0; + VkDeviceSize memoryUsed = 0; + }; + /** * \brief Memory slice @@ -72,6 +83,8 @@ namespace dxvk { VkDeviceSize m_length = 0; void* m_mapPtr = nullptr; + void free(); + }; @@ -172,6 +185,15 @@ namespace dxvk { VkDeviceSize size, VkDeviceSize align); + /** + * \brief Queries memory stats + * + * Returns the amount of memory + * allocated and used on this heap. + * \returns Global memory stats + */ + DxvkMemoryStats getMemoryStats() const; + private: const Rc m_vkd; @@ -182,11 +204,15 @@ namespace dxvk { std::mutex m_mutex; std::vector> m_chunks; + std::atomic m_memoryAllocated = { 0ull }; + std::atomic m_memoryUsed = { 0ull }; + VkDeviceMemory allocDeviceMemory( VkDeviceSize memorySize); void freeDeviceMemory( - VkDeviceMemory memory); + VkDeviceMemory memory, + VkDeviceSize memorySize); void* mapDeviceMemory( VkDeviceMemory memory); @@ -237,6 +263,15 @@ namespace dxvk { const VkMemoryRequirements& req, const VkMemoryPropertyFlags flags); + /** + * \brief Queries memory stats + * + * Returns the total amount of device memory + * allocated and used by all available heaps. + * \returns Global memory stats + */ + DxvkMemoryStats getMemoryStats() const; + private: const Rc m_vkd;