summaryrefslogtreecommitdiff
path: root/src/video_core/vulkan_common
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-01-03 18:38:15 -0300
committerGravatar ReinUsesLisp2021-01-15 16:19:39 -0300
commit72541af3bc8973fba0f0e3d1302fcd0fa7fb9f06 (patch)
tree4fc56ddc8b3e1dfe06a4980696025247b5f9d24a /src/video_core/vulkan_common
parentvulkan_common: Move allocator to the common directory (diff)
downloadyuzu-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.cpp24
-rw-r--r--src/video_core/vulkan_common/vulkan_memory_allocator.h24
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
157MemoryAllocator::~MemoryAllocator() = default; 157MemoryAllocator::~MemoryAllocator() = default;
158 158
159MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, bool host_visible) { 159MemoryCommit 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
179MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, bool host_visible) { 181MemoryCommit 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
185MemoryCommit MemoryAllocator::Commit(const vk::Image& image, bool host_visible) { 187MemoryCommit 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
229bool 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;
17class MemoryMap; 17class MemoryMap;
18class MemoryAllocation; 18class MemoryAllocation;
19 19
20class MemoryCommit final { 20/// Hints and requirements for the backing memory type of a commit
21enum 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.
29class MemoryCommit {
21public: 30public:
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
57class MemoryAllocator final { 66/// Memory allocator container.
67/// Allocates and releases memory allocations on demand.
68class MemoryAllocator {
58public: 69public:
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
82private: 93private:
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.
107bool IsHostVisible(MemoryUsage usage) noexcept;
108
95} // namespace Vulkan 109} // namespace Vulkan