diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index f18a4a36..1c57fbfb 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -12,7 +12,6 @@ namespace dxvk { VkPhysicalDevice handle) : m_vki (vki), m_handle (handle) { - this->initHeapAllocInfo(); this->queryExtensions(); this->queryDeviceInfo(); this->queryDeviceFeatures(); @@ -42,11 +41,16 @@ namespace dxvk { info.heaps[i].heapSize = memProps.memoryProperties.memoryHeaps[i].size; if (m_hasMemoryBudget) { + // Handle DXVK's memory allocations separately so that + // freeing resources actually is visible to applications. + VkDeviceSize allocated = m_memoryAllocated[i].load(); + VkDeviceSize used = m_memoryUsed[i].load(); + info.heaps[i].memoryBudget = memBudget.heapBudget[i]; - info.heaps[i].memoryAllocated = memBudget.heapUsage[i]; + info.heaps[i].memoryAllocated = std::max(memBudget.heapUsage[i], allocated) - allocated + used; } else { info.heaps[i].memoryBudget = memProps.memoryProperties.memoryHeaps[i].size; - info.heaps[i].memoryAllocated = m_heapAlloc[i].load(); + info.heaps[i].memoryAllocated = m_memoryUsed[i].load(); } } @@ -657,19 +661,19 @@ namespace dxvk { } - void DxvkAdapter::notifyHeapMemoryAlloc( + void DxvkAdapter::notifyMemoryAlloc( uint32_t heap, - VkDeviceSize bytes) { - if (!m_hasMemoryBudget) - m_heapAlloc[heap] += bytes; + int64_t bytes) { + if (heap < m_memoryAllocated.size()) + m_memoryAllocated[heap] += bytes; } - - void DxvkAdapter::notifyHeapMemoryFree( + + void DxvkAdapter::notifyMemoryUse( uint32_t heap, - VkDeviceSize bytes) { - if (!m_hasMemoryBudget) - m_heapAlloc[heap] -= bytes; + int64_t bytes) { + if (heap < m_memoryUsed.size()) + m_memoryUsed[heap] += bytes; } @@ -729,12 +733,6 @@ 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 e70cecd6..3dcdec2a 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -197,26 +197,26 @@ namespace dxvk { DxvkDeviceFeatures enabledFeatures); /** - * \brief Registers memory allocation + * \brief Registers heap memory allocation * * Updates memory alloc info accordingly. * \param [in] heap Memory heap index * \param [in] bytes Allocation size */ - void notifyHeapMemoryAlloc( + void notifyMemoryAlloc( uint32_t heap, - VkDeviceSize bytes); + int64_t bytes); /** - * \brief Registers memory deallocation + * \brief Registers memory suballocation * * Updates memory alloc info accordingly. * \param [in] heap Memory heap index * \param [in] bytes Allocation size */ - void notifyHeapMemoryFree( + void notifyMemoryUse( uint32_t heap, - VkDeviceSize bytes); + int64_t bytes); /** * \brief Tests if the driver matches certain criteria @@ -262,9 +262,9 @@ namespace dxvk { std::vector m_queueFamilies; - std::array, VK_MAX_MEMORY_HEAPS> m_heapAlloc; + std::array, VK_MAX_MEMORY_HEAPS> m_memoryAllocated = { }; + std::array, VK_MAX_MEMORY_HEAPS> m_memoryUsed = { }; - void initHeapAllocInfo(); void queryExtensions(); void queryDeviceInfo(); void queryDeviceFeatures(); diff --git a/src/dxvk/dxvk_device.h b/src/dxvk/dxvk_device.h index 659353d5..b252a843 100644 --- a/src/dxvk/dxvk_device.h +++ b/src/dxvk/dxvk_device.h @@ -393,6 +393,30 @@ namespace dxvk { */ uint32_t getCurrentFrameId() const; + /** + * \brief Notifies adapter about memory allocation + * + * \param [in] heap Memory heap index + * \param [in] bytes Allocation size + */ + void notifyMemoryAlloc( + uint32_t heap, + int64_t bytes) { + m_adapter->notifyMemoryUse(heap, bytes); + } + + /** + * \brief Notifies adapter about memory suballocation + * + * \param [in] heap Memory heap index + * \param [in] bytes Allocation size + */ + void notifyMemoryUse( + uint32_t heap, + int64_t bytes) { + m_adapter->notifyMemoryUse(heap, bytes); + } + /** * \brief Registers a shader * \param [in] shader Newly compiled shader diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 5091f09b..0105bca8 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -366,8 +366,10 @@ namespace dxvk { memory = DxvkMemory(this, nullptr, type, devMem.memHandle, 0, size, devMem.memPointer); } - if (memory) + if (memory) { type->heap->stats.memoryUsed += memory.m_length; + m_device->notifyMemoryUse(type->heapId, memory.m_length); + } return memory; } @@ -431,7 +433,7 @@ namespace dxvk { } type->heap->stats.memoryAllocated += size; - m_device->adapter()->notifyHeapMemoryAlloc(type->heapId, size); + m_device->notifyMemoryAlloc(type->heapId, size); return result; } @@ -454,6 +456,8 @@ namespace dxvk { devMem.memSize = memory.m_length; this->freeDeviceMemory(memory.m_type, devMem); } + + m_device->notifyMemoryUse(memory.m_type->heapId, -memory.m_length); } @@ -485,7 +489,7 @@ namespace dxvk { vk->vkFreeMemory(vk->device(), memory.memHandle, nullptr); type->heap->stats.memoryAllocated -= memory.memSize; - m_device->adapter()->notifyHeapMemoryFree(type->heapId, memory.memSize); + m_device->notifyMemoryAlloc(type->heapId, memory.memSize); }