diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index 43314c991..9c1668259 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -13,6 +13,7 @@ namespace dxvk { : m_instance (instance), m_vki (instance->vki()), m_handle (handle) { + this->initHeapAllocInfo(); this->queryExtensions(); this->queryDeviceInfo(); this->queryDeviceFeatures(); @@ -30,6 +31,22 @@ namespace dxvk { } + DxvkAdapterMemoryInfo DxvkAdapter::getMemoryHeapInfo() const { + VkPhysicalDeviceMemoryProperties props = memoryProperties(); + + DxvkAdapterMemoryInfo info = { }; + info.heapCount = props.memoryHeapCount; + + for (uint32_t i = 0; i < info.heapCount; i++) { + info.heaps[i].heapFlags = props.memoryHeaps[i].flags; + info.heaps[i].memoryAvailable = props.memoryHeaps[i].size; + info.heaps[i].memoryAllocated = m_heapAlloc[i].load(); + } + + return info; + } + + VkPhysicalDeviceMemoryProperties DxvkAdapter::memoryProperties() const { VkPhysicalDeviceMemoryProperties memoryProperties; m_vki->vkGetPhysicalDeviceMemoryProperties(m_handle, &memoryProperties); @@ -288,6 +305,20 @@ namespace dxvk { Rc DxvkAdapter::createSurface(HINSTANCE instance, HWND window) { return new DxvkSurface(this, instance, window); } + + + void DxvkAdapter::notifyHeapMemoryAlloc( + uint32_t heap, + VkDeviceSize bytes) { + m_heapAlloc[heap] += bytes; + } + + + void DxvkAdapter::notifyHeapMemoryFree( + uint32_t heap, + VkDeviceSize bytes) { + m_heapAlloc[heap] -= bytes; + } void DxvkAdapter::logAdapterInfo() const { @@ -322,6 +353,12 @@ namespace dxvk { } + void DxvkAdapter::initHeapAllocInfo() { + for (uint32_t i = 0; i < m_heapAlloc.size(); i++) + m_heapAlloc[i] = 0; + } + + void DxvkAdapter::queryExtensions() { m_deviceExtensions = DxvkNameSet::enumDeviceExtensions(m_vki, m_handle); } diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index 571da2744..53ad83c00 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -19,6 +19,29 @@ namespace dxvk { Nvidia = 0x10de, Intel = 0x8086, }; + + /** + * \brief Adapter memory heap info + * + * Stores info about a heap, and the amount + * of memory allocated from it by the app. + */ + struct DxvkAdapterMemoryHeapInfo { + VkMemoryHeapFlags heapFlags; + VkDeviceSize memoryAvailable; + VkDeviceSize memoryAllocated; + }; + + /** + * \brief Adapter memory info + * + * Stores properties and allocation + * info of each available heap. + */ + struct DxvkAdapterMemoryInfo { + uint32_t heapCount; + DxvkAdapterMemoryHeapInfo heaps[VK_MAX_MEMORY_HEAPS]; + }; /** * \brief DXVK adapter @@ -91,6 +114,17 @@ namespace dxvk { return m_deviceFeatures; } + /** + * \brief Retrieves memory heap info + * + * Returns properties of all available memory heaps, + * both device-local and non-local heaps, and the + * amount of memory allocated from those heaps by + * logical devices. + * \returns Memory heap info + */ + DxvkAdapterMemoryInfo getMemoryHeapInfo() const; + /** * \brief Memory properties * @@ -99,7 +133,7 @@ namespace dxvk { * \returns Device memory properties */ VkPhysicalDeviceMemoryProperties memoryProperties() const; - + /** * \brief Queries format support * @@ -170,6 +204,28 @@ namespace dxvk { HINSTANCE instance, HWND window); + /** + * \brief Registers memory allocation + * + * Updates memory alloc info accordingly. + * \param [in] heap Memory heap index + * \param [in] bytes Allocation size + */ + void notifyHeapMemoryAlloc( + uint32_t heap, + VkDeviceSize bytes); + + /** + * \brief Registers memory deallocation + * + * Updates memory alloc info accordingly. + * \param [in] heap Memory heap index + * \param [in] bytes Allocation size + */ + void notifyHeapMemoryFree( + uint32_t heap, + VkDeviceSize bytes); + /** * \brief Logs DXVK adapter info * @@ -190,6 +246,9 @@ namespace dxvk { std::vector m_queueFamilies; + std::array, VK_MAX_MEMORY_HEAPS> m_heapAlloc; + + void initHeapAllocInfo(); void queryExtensions(); void queryDeviceInfo(); void queryDeviceFeatures(); diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index fdfaa70ed..5fb271a6a 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -152,8 +152,9 @@ namespace dxvk { DxvkMemoryAllocator::DxvkMemoryAllocator(const DxvkDevice* device) : m_vkd (device->vkd()), - m_devProps (device->adapter()->deviceProperties()), - m_memProps (device->adapter()->memoryProperties()), + m_adapter (device->adapter()), + m_devProps (m_adapter->deviceProperties()), + m_memProps (m_adapter->memoryProperties()), m_allowOvercommit (device->config().allowMemoryOvercommit) { for (uint32_t i = 0; i < m_memProps.memoryHeapCount; i++) { VkDeviceSize heapSize = m_memProps.memoryHeaps[i].size; @@ -165,6 +166,7 @@ namespace dxvk { for (uint32_t i = 0; i < m_memProps.memoryTypeCount; i++) { m_memTypes[i].heap = &m_memHeaps[m_memProps.memoryTypes[i].heapIndex]; + m_memTypes[i].heapId = m_memProps.memoryTypes[i].heapIndex; m_memTypes[i].memType = m_memProps.memoryTypes[i]; m_memTypes[i].memTypeId = i; } @@ -307,6 +309,7 @@ namespace dxvk { } type->heap->stats.memoryAllocated += size; + m_adapter->notifyHeapMemoryAlloc(type->heapId, size); return result; } @@ -346,6 +349,7 @@ namespace dxvk { DxvkDeviceMemory memory) { m_vkd->vkFreeMemory(m_vkd->device(), memory.memHandle, nullptr); type->heap->stats.memoryAllocated -= memory.memSize; + m_adapter->notifyHeapMemoryFree(type->heapId, memory.memSize); } diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 540a1a331..0287ba932 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -56,6 +56,7 @@ namespace dxvk { */ struct DxvkMemoryType { DxvkMemoryHeap* heap; + uint32_t heapId; VkMemoryType memType; uint32_t memTypeId; @@ -255,6 +256,7 @@ namespace dxvk { private: const Rc m_vkd; + const Rc m_adapter; const VkPhysicalDeviceProperties m_devProps; const VkPhysicalDeviceMemoryProperties m_memProps; const bool m_allowOvercommit;