summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-03-19 07:32:11 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-03-19 07:32:11 +0000
commit236f3717c76bf02fb94c6c5dc45e3dcb71ed48e3 (patch)
tree5d511b59a37f5962c9842a0d061a0395f4794752 /Graphics/GraphicsEngineVulkan
parentImproved messages about descriptor allocation failures in D3D12 backend (fixe... (diff)
downloadDiligentCore-236f3717c76bf02fb94c6c5dc45e3dcb71ed48e3.tar.gz
DiligentCore-236f3717c76bf02fb94c6c5dc45e3dcb71ed48e3.zip
Fixed issue with staging allocations in Vulkan backend on Integrated GPUs
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h28
-rw-r--r--Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp12
2 files changed, 37 insertions, 3 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h
index 45806642..4092db05 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanMemoryManager.h
@@ -33,6 +33,7 @@
#include "VulkanUtilities/VulkanPhysicalDevice.h"
#include "VulkanUtilities/VulkanLogicalDevice.h"
#include "VulkanUtilities/VulkanObjectWrappers.h"
+#include "HashUtils.h"
namespace VulkanUtilities
{
@@ -199,7 +200,32 @@ protected:
Diligent::IMemoryAllocator& m_Allocator;
std::mutex m_PagesMtx;
- std::unordered_multimap<uint32_t, VulkanMemoryPage> m_Pages;
+ struct MemoryPageIndex
+ {
+ const uint32_t MemoryTypeIndex;
+ const bool IsHostVisible;
+
+ MemoryPageIndex(uint32_t _MemoryTypeIndex,
+ bool _IsHostVisible) :
+ MemoryTypeIndex(_MemoryTypeIndex),
+ IsHostVisible (_IsHostVisible)
+ {}
+
+ bool operator == (const MemoryPageIndex& rhs)const
+ {
+ return MemoryTypeIndex == rhs.MemoryTypeIndex &&
+ IsHostVisible == rhs.IsHostVisible;
+ }
+
+ struct Hasher
+ {
+ size_t operator()(const MemoryPageIndex& PageIndex)const
+ {
+ return Diligent::ComputeHash(PageIndex.MemoryTypeIndex, PageIndex.IsHostVisible);
+ }
+ };
+ };
+ std::unordered_multimap<MemoryPageIndex, VulkanMemoryPage, MemoryPageIndex::Hasher> m_Pages;
const VkDeviceSize m_DeviceLocalPageSize;
const VkDeviceSize m_HostVisiblePageSize;
diff --git a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp
index fd597327..870b00cb 100644
--- a/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/VulkanUtilities/VulkanMemoryManager.cpp
@@ -135,8 +135,16 @@ VulkanMemoryAllocation VulkanMemoryManager::Allocate(VkDeviceSize Size, VkDevice
{
VulkanMemoryAllocation Allocation;
+ // On integrated GPUs, there is no difference between host-visible and GPU-only
+ // memory, so MemoryTypeIndex is the same. As GPU-only pages do not have CPU address,
+ // we need to use HostVisible flag to differentiate the two.
+ // It is likely a good idea to always keep staging pages separate to reduce fragmenation
+ // even though on integrated GPUs same pages can be used for both GPU-only and staging
+ // allocations. Staging allocations are short-living and will be released when upload is
+ // complete, while GPU-only allocations are expected to be long-living.
+ MemoryPageIndex PageIdx{MemoryTypeIndex, HostVisible};
std::lock_guard<std::mutex> Lock(m_PagesMtx);
- auto range = m_Pages.equal_range(MemoryTypeIndex);
+ auto range = m_Pages.equal_range(PageIdx);
for(auto page_it = range.first; page_it != range.second; ++page_it)
{
Allocation = page_it->second.Allocate(Size, Alignment);
@@ -154,7 +162,7 @@ VulkanMemoryAllocation VulkanMemoryManager::Allocate(VkDeviceSize Size, VkDevice
m_CurrAllocatedSize[stat_ind] += PageSize;
m_PeakAllocatedSize[stat_ind] = std::max(m_PeakAllocatedSize[stat_ind], m_CurrAllocatedSize[stat_ind]);
- auto it = m_Pages.emplace(MemoryTypeIndex, VulkanMemoryPage{*this, PageSize, MemoryTypeIndex, HostVisible});
+ auto it = m_Pages.emplace(PageIdx, VulkanMemoryPage{*this, PageSize, MemoryTypeIndex, HostVisible});
LOG_INFO_MESSAGE("VulkanMemoryManager '", m_MgrName, "': created new ", (HostVisible ? "host-visible" : "device-local"),
" page. (", Diligent::FormatMemorySize(PageSize, 2), ", type idx: ", MemoryTypeIndex,
"). Current allocated size: ", Diligent::FormatMemorySize(m_CurrAllocatedSize[stat_ind], 2));