From 72541af3bc8973fba0f0e3d1302fcd0fa7fb9f06 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 3 Jan 2021 18:38:15 -0300 Subject: vulkan_memory_allocator: Add "download" memory usage hint Allow users of the allocator to hint memory usage for downloads. This removes the non-descriptive boolean passed for "host visible" or not host visible memory commits, and uses an enum to hint device local, upload and download usages. --- .../vulkan_common/vulkan_memory_allocator.cpp | 24 +++++++++++++++++----- .../vulkan_common/vulkan_memory_allocator.h | 24 +++++++++++++++++----- 2 files changed, 38 insertions(+), 10 deletions(-) (limited to 'src/video_core/vulkan_common') diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index c1cf292af..8bb15794d 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp @@ -156,11 +156,13 @@ MemoryAllocator::MemoryAllocator(const Device& device_) MemoryAllocator::~MemoryAllocator() = default; -MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, bool host_visible) { +MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { const u64 chunk_size = GetAllocationChunkSize(requirements.size); // When a host visible commit is asked, search for host visible and coherent, otherwise search // for a fast device local type. + // TODO: Deduce memory types from usage in a better way + const bool host_visible = IsHostVisible(usage); const VkMemoryPropertyFlags wanted_properties = host_visible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; @@ -176,14 +178,14 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, b return TryAllocCommit(requirements, wanted_properties).value(); } -MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, bool host_visible) { - auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), host_visible); +MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage) { + auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), usage); buffer.BindMemory(commit.Memory(), commit.Offset()); return commit; } -MemoryCommit MemoryAllocator::Commit(const vk::Image& image, bool host_visible) { - auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), host_visible); +MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) { + auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), usage); image.BindMemory(commit.Memory(), commit.Offset()); return commit; } @@ -224,4 +226,16 @@ std::optional MemoryAllocator::TryAllocCommit( return std::nullopt; } +bool IsHostVisible(MemoryUsage usage) noexcept { + switch (usage) { + case MemoryUsage::DeviceLocal: + return false; + case MemoryUsage::Upload: + case MemoryUsage::Download: + return true; + } + UNREACHABLE_MSG("Invalid memory usage={}", usage); + return false; +} + } // namespace Vulkan diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index 69a6341e1..efb32167a 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h @@ -17,7 +17,16 @@ class Device; class MemoryMap; class MemoryAllocation; -class MemoryCommit final { +/// Hints and requirements for the backing memory type of a commit +enum class MemoryUsage { + DeviceLocal, ///< Hints device local usages, fastest memory type to read and write from the GPU + Upload, ///< Requires a host visible memory type optimized for CPU to GPU uploads + Download, ///< Requires a host visible memory type optimized for GPU to CPU readbacks +}; + +/// Ownership handle of a memory commitment. +/// Points to a subregion of a memory allocation. +class MemoryCommit { public: explicit MemoryCommit() noexcept = default; explicit MemoryCommit(const Device& device_, MemoryAllocation* allocation_, @@ -54,7 +63,9 @@ private: std::span span; ///< Host visible memory span. Empty if not queried before. }; -class MemoryAllocator final { +/// Memory allocator container. +/// Allocates and releases memory allocations on demand. +class MemoryAllocator { public: explicit MemoryAllocator(const Device& device_); ~MemoryAllocator(); @@ -71,13 +82,13 @@ public: * * @returns A memory commit. */ - MemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible); + MemoryCommit Commit(const VkMemoryRequirements& requirements, MemoryUsage usage); /// Commits memory required by the buffer and binds it. - MemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); + MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); /// Commits memory required by the image and binds it. - MemoryCommit Commit(const vk::Image& image, bool host_visible); + MemoryCommit Commit(const vk::Image& image, MemoryUsage usage); private: /// Allocates a chunk of memory. @@ -92,4 +103,7 @@ private: std::vector> allocations; ///< Current allocations. }; +/// Returns true when a memory usage is guaranteed to be host visible. +bool IsHostVisible(MemoryUsage usage) noexcept; + } // namespace Vulkan -- cgit v1.2.3