diff options
| author | 2021-01-03 18:38:15 -0300 | |
|---|---|---|
| committer | 2021-01-15 16:19:39 -0300 | |
| commit | 72541af3bc8973fba0f0e3d1302fcd0fa7fb9f06 (patch) | |
| tree | 4fc56ddc8b3e1dfe06a4980696025247b5f9d24a /src/video_core/vulkan_common | |
| parent | vulkan_common: Move allocator to the common directory (diff) | |
| download | yuzu-72541af3bc8973fba0f0e3d1302fcd0fa7fb9f06.tar.gz yuzu-72541af3bc8973fba0f0e3d1302fcd0fa7fb9f06.tar.xz yuzu-72541af3bc8973fba0f0e3d1302fcd0fa7fb9f06.zip | |
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.
Diffstat (limited to 'src/video_core/vulkan_common')
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 24 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.h | 24 |
2 files changed, 38 insertions, 10 deletions
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_) | |||
| 156 | 156 | ||
| 157 | MemoryAllocator::~MemoryAllocator() = default; | 157 | MemoryAllocator::~MemoryAllocator() = default; |
| 158 | 158 | ||
| 159 | MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, bool host_visible) { | 159 | MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) { |
| 160 | const u64 chunk_size = GetAllocationChunkSize(requirements.size); | 160 | const u64 chunk_size = GetAllocationChunkSize(requirements.size); |
| 161 | 161 | ||
| 162 | // When a host visible commit is asked, search for host visible and coherent, otherwise search | 162 | // When a host visible commit is asked, search for host visible and coherent, otherwise search |
| 163 | // for a fast device local type. | 163 | // for a fast device local type. |
| 164 | // TODO: Deduce memory types from usage in a better way | ||
| 165 | const bool host_visible = IsHostVisible(usage); | ||
| 164 | const VkMemoryPropertyFlags wanted_properties = | 166 | const VkMemoryPropertyFlags wanted_properties = |
| 165 | host_visible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | 167 | host_visible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
| 166 | : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; | 168 | : VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; |
| @@ -176,14 +178,14 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, b | |||
| 176 | return TryAllocCommit(requirements, wanted_properties).value(); | 178 | return TryAllocCommit(requirements, wanted_properties).value(); |
| 177 | } | 179 | } |
| 178 | 180 | ||
| 179 | MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, bool host_visible) { | 181 | MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage) { |
| 180 | auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), host_visible); | 182 | auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), usage); |
| 181 | buffer.BindMemory(commit.Memory(), commit.Offset()); | 183 | buffer.BindMemory(commit.Memory(), commit.Offset()); |
| 182 | return commit; | 184 | return commit; |
| 183 | } | 185 | } |
| 184 | 186 | ||
| 185 | MemoryCommit MemoryAllocator::Commit(const vk::Image& image, bool host_visible) { | 187 | MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) { |
| 186 | auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), host_visible); | 188 | auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), usage); |
| 187 | image.BindMemory(commit.Memory(), commit.Offset()); | 189 | image.BindMemory(commit.Memory(), commit.Offset()); |
| 188 | return commit; | 190 | return commit; |
| 189 | } | 191 | } |
| @@ -224,4 +226,16 @@ std::optional<MemoryCommit> MemoryAllocator::TryAllocCommit( | |||
| 224 | return std::nullopt; | 226 | return std::nullopt; |
| 225 | } | 227 | } |
| 226 | 228 | ||
| 229 | bool IsHostVisible(MemoryUsage usage) noexcept { | ||
| 230 | switch (usage) { | ||
| 231 | case MemoryUsage::DeviceLocal: | ||
| 232 | return false; | ||
| 233 | case MemoryUsage::Upload: | ||
| 234 | case MemoryUsage::Download: | ||
| 235 | return true; | ||
| 236 | } | ||
| 237 | UNREACHABLE_MSG("Invalid memory usage={}", usage); | ||
| 238 | return false; | ||
| 239 | } | ||
| 240 | |||
| 227 | } // namespace Vulkan | 241 | } // 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; | |||
| 17 | class MemoryMap; | 17 | class MemoryMap; |
| 18 | class MemoryAllocation; | 18 | class MemoryAllocation; |
| 19 | 19 | ||
| 20 | class MemoryCommit final { | 20 | /// Hints and requirements for the backing memory type of a commit |
| 21 | enum class MemoryUsage { | ||
| 22 | DeviceLocal, ///< Hints device local usages, fastest memory type to read and write from the GPU | ||
| 23 | Upload, ///< Requires a host visible memory type optimized for CPU to GPU uploads | ||
| 24 | Download, ///< Requires a host visible memory type optimized for GPU to CPU readbacks | ||
| 25 | }; | ||
| 26 | |||
| 27 | /// Ownership handle of a memory commitment. | ||
| 28 | /// Points to a subregion of a memory allocation. | ||
| 29 | class MemoryCommit { | ||
| 21 | public: | 30 | public: |
| 22 | explicit MemoryCommit() noexcept = default; | 31 | explicit MemoryCommit() noexcept = default; |
| 23 | explicit MemoryCommit(const Device& device_, MemoryAllocation* allocation_, | 32 | explicit MemoryCommit(const Device& device_, MemoryAllocation* allocation_, |
| @@ -54,7 +63,9 @@ private: | |||
| 54 | std::span<u8> span; ///< Host visible memory span. Empty if not queried before. | 63 | std::span<u8> span; ///< Host visible memory span. Empty if not queried before. |
| 55 | }; | 64 | }; |
| 56 | 65 | ||
| 57 | class MemoryAllocator final { | 66 | /// Memory allocator container. |
| 67 | /// Allocates and releases memory allocations on demand. | ||
| 68 | class MemoryAllocator { | ||
| 58 | public: | 69 | public: |
| 59 | explicit MemoryAllocator(const Device& device_); | 70 | explicit MemoryAllocator(const Device& device_); |
| 60 | ~MemoryAllocator(); | 71 | ~MemoryAllocator(); |
| @@ -71,13 +82,13 @@ public: | |||
| 71 | * | 82 | * |
| 72 | * @returns A memory commit. | 83 | * @returns A memory commit. |
| 73 | */ | 84 | */ |
| 74 | MemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible); | 85 | MemoryCommit Commit(const VkMemoryRequirements& requirements, MemoryUsage usage); |
| 75 | 86 | ||
| 76 | /// Commits memory required by the buffer and binds it. | 87 | /// Commits memory required by the buffer and binds it. |
| 77 | MemoryCommit Commit(const vk::Buffer& buffer, bool host_visible); | 88 | MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage); |
| 78 | 89 | ||
| 79 | /// Commits memory required by the image and binds it. | 90 | /// Commits memory required by the image and binds it. |
| 80 | MemoryCommit Commit(const vk::Image& image, bool host_visible); | 91 | MemoryCommit Commit(const vk::Image& image, MemoryUsage usage); |
| 81 | 92 | ||
| 82 | private: | 93 | private: |
| 83 | /// Allocates a chunk of memory. | 94 | /// Allocates a chunk of memory. |
| @@ -92,4 +103,7 @@ private: | |||
| 92 | std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations. | 103 | std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations. |
| 93 | }; | 104 | }; |
| 94 | 105 | ||
| 106 | /// Returns true when a memory usage is guaranteed to be host visible. | ||
| 107 | bool IsHostVisible(MemoryUsage usage) noexcept; | ||
| 108 | |||
| 95 | } // namespace Vulkan | 109 | } // namespace Vulkan |