diff options
author | Joshua Ashton <joshua@froggi.es> | 2020-02-24 10:47:09 +0300 |
---|---|---|
committer | Joshua Ashton <joshua@froggi.es> | 2020-02-25 04:19:24 +0300 |
commit | cf1a446d5720aab8c42953b8616f7a4f6210a3d2 (patch) | |
tree | 5b2a1318a430573b5f686520b2145ab93329a0c3 | |
parent | d1dc217d3165f2f49dc1939e4bab7e329fa2d297 (diff) |
[dxvk] Unmap free memory chunksdxvk-unmap-empty-chunks
-rw-r--r-- | src/dxvk/dxvk_memory.cpp | 32 | ||||
-rw-r--r-- | src/dxvk/dxvk_memory.h | 11 |
2 files changed, 39 insertions, 4 deletions
diff --git a/src/dxvk/dxvk_memory.cpp b/src/dxvk/dxvk_memory.cpp index 11f2dfa1..35a3e567 100644 --- a/src/dxvk/dxvk_memory.cpp +++ b/src/dxvk/dxvk_memory.cpp @@ -119,6 +119,14 @@ namespace dxvk { if (allocEnd != sliceEnd) m_freeList.push_back({ allocEnd, sliceEnd - allocEnd }); + + const bool shouldMap = m_memory.memFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT && + m_memory.memPointer == nullptr; + + if (!isEmpty() && shouldMap) { + if (m_alloc->mapMemory(&m_memory) != VK_SUCCESS) + return DxvkMemory(); + } // Create the memory object with the aligned slice return DxvkMemory(m_alloc, this, m_type, @@ -149,6 +157,9 @@ namespace dxvk { } m_freeList.push_back({ offset, length }); + + if (isEmpty() && m_memory.memPointer != nullptr) + m_alloc->unmapMemory(&m_memory); } @@ -334,10 +345,7 @@ namespace dxvk { return DxvkDeviceMemory(); if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { - VkResult status = m_vkd->vkMapMemory(m_vkd->device(), result.memHandle, 0, VK_WHOLE_SIZE, 0, &result.memPointer); - - if (status != VK_SUCCESS) { - Logger::err(str::format("DxvkMemoryAllocator: Mapping memory failed with ", status)); + if (mapMemory(&result) != VK_SUCCESS) { m_vkd->vkFreeMemory(m_vkd->device(), result.memHandle, nullptr); return DxvkDeviceMemory(); } @@ -409,5 +417,21 @@ namespace dxvk { return chunkSize; } + + + VkResult DxvkMemoryAllocator::mapMemory(DxvkDeviceMemory* memory) { + VkResult status = m_vkd->vkMapMemory(m_vkd->device(), memory->memHandle, 0, VK_WHOLE_SIZE, 0, &memory->memPointer); + + if (status != VK_SUCCESS) + Logger::err(str::format("DxvkMemoryAllocator: Mapping memory failed with ", status)); + + return status; + } + + + void DxvkMemoryAllocator::unmapMemory(DxvkDeviceMemory* memory) { + memory->memPointer = nullptr; + m_vkd->vkUnmapMemory(m_vkd->device(), memory->memHandle); + } }
\ No newline at end of file diff --git a/src/dxvk/dxvk_memory.h b/src/dxvk/dxvk_memory.h index 92719501..859c7a5a 100644 --- a/src/dxvk/dxvk_memory.h +++ b/src/dxvk/dxvk_memory.h @@ -202,6 +202,13 @@ namespace dxvk { void free( VkDeviceSize offset, VkDeviceSize length); + + bool isEmpty() const { + if (m_freeList.size() == 0) + return false; + + return m_freeList[0].length == m_memory.memSize; + } private: @@ -324,6 +331,10 @@ namespace dxvk { VkDeviceSize pickChunkSize( uint32_t memTypeId) const; + VkResult mapMemory(DxvkDeviceMemory* memory); + + void unmapMemory(DxvkDeviceMemory* memory); + }; }
\ No newline at end of file |