summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ameerj2023-05-27 21:46:15 -0400
committerGravatar ameerj2023-05-28 00:38:46 -0400
commit642c14f0c7ee71f1f4daa50cee84ec9143697af6 (patch)
tree864fae9c9389790e87f8f63341c89e09f6fed5bc
parentMerge pull request #10414 from liamwhite/anv-push-descriptor (diff)
downloadyuzu-642c14f0c7ee71f1f4daa50cee84ec9143697af6.tar.gz
yuzu-642c14f0c7ee71f1f4daa50cee84ec9143697af6.tar.xz
yuzu-642c14f0c7ee71f1f4daa50cee84ec9143697af6.zip
OpenGL: Make use of persistent buffer maps in buffer cache downloads
Persistent buffer maps were already used by the texture cache, this extends their usage for the buffer cache. In my testing, using the memory maps for uploads was slower than the existing "ImmediateUpload" path, so the memory map usage is limited to downloads for the time being.
-rw-r--r--src/video_core/CMakeLists.txt4
-rw-r--r--src/video_core/buffer_cache/buffer_cache.h10
-rw-r--r--src/video_core/buffer_cache/buffer_cache_base.h1
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp58
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h29
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h1
-rw-r--r--src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp134
-rw-r--r--src/video_core/renderer_opengl/gl_staging_buffer_pool.h (renamed from src/video_core/renderer_opengl/gl_stream_buffer.h)42
-rw-r--r--src/video_core/renderer_opengl/gl_stream_buffer.cpp63
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp87
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h47
-rw-r--r--src/video_core/renderer_opengl/util_shaders.cpp9
-rw-r--r--src/video_core/renderer_opengl/util_shaders.h10
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h1
15 files changed, 298 insertions, 204 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 308d013d6..3e8bd0060 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -133,8 +133,8 @@ add_library(video_core STATIC
133 renderer_opengl/gl_shader_util.h 133 renderer_opengl/gl_shader_util.h
134 renderer_opengl/gl_state_tracker.cpp 134 renderer_opengl/gl_state_tracker.cpp
135 renderer_opengl/gl_state_tracker.h 135 renderer_opengl/gl_state_tracker.h
136 renderer_opengl/gl_stream_buffer.cpp 136 renderer_opengl/gl_staging_buffer_pool.cpp
137 renderer_opengl/gl_stream_buffer.h 137 renderer_opengl/gl_staging_buffer_pool.h
138 renderer_opengl/gl_texture_cache.cpp 138 renderer_opengl/gl_texture_cache.cpp
139 renderer_opengl/gl_texture_cache.h 139 renderer_opengl/gl_texture_cache.h
140 renderer_opengl/gl_texture_cache_base.cpp 140 renderer_opengl/gl_texture_cache_base.cpp
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h
index 65494097b..08bc66aaa 100644
--- a/src/video_core/buffer_cache/buffer_cache.h
+++ b/src/video_core/buffer_cache/buffer_cache.h
@@ -465,7 +465,6 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
465 465
466 if (committed_ranges.empty()) { 466 if (committed_ranges.empty()) {
467 if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) { 467 if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
468
469 async_buffers.emplace_back(std::optional<Async_Buffer>{}); 468 async_buffers.emplace_back(std::optional<Async_Buffer>{});
470 } 469 }
471 return; 470 return;
@@ -526,7 +525,6 @@ void BufferCache<P>::CommitAsyncFlushesHigh() {
526 committed_ranges.clear(); 525 committed_ranges.clear();
527 if (downloads.empty()) { 526 if (downloads.empty()) {
528 if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) { 527 if constexpr (IMPLEMENTS_ASYNC_DOWNLOADS) {
529
530 async_buffers.emplace_back(std::optional<Async_Buffer>{}); 528 async_buffers.emplace_back(std::optional<Async_Buffer>{});
531 } 529 }
532 return; 530 return;
@@ -678,7 +676,7 @@ void BufferCache<P>::BindHostIndexBuffer() {
678 const u32 size = index_buffer.size; 676 const u32 size = index_buffer.size;
679 const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); 677 const auto& draw_state = maxwell3d->draw_manager->GetDrawState();
680 if (!draw_state.inline_index_draw_indexes.empty()) [[unlikely]] { 678 if (!draw_state.inline_index_draw_indexes.empty()) [[unlikely]] {
681 if constexpr (USE_MEMORY_MAPS) { 679 if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
682 auto upload_staging = runtime.UploadStagingBuffer(size); 680 auto upload_staging = runtime.UploadStagingBuffer(size);
683 std::array<BufferCopy, 1> copies{ 681 std::array<BufferCopy, 1> copies{
684 {BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}}; 682 {BufferCopy{.src_offset = upload_staging.offset, .dst_offset = 0, .size = size}}};
@@ -1446,7 +1444,7 @@ bool BufferCache<P>::SynchronizeBufferNoModified(Buffer& buffer, VAddr cpu_addr,
1446template <class P> 1444template <class P>
1447void BufferCache<P>::UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy, 1445void BufferCache<P>::UploadMemory(Buffer& buffer, u64 total_size_bytes, u64 largest_copy,
1448 std::span<BufferCopy> copies) { 1446 std::span<BufferCopy> copies) {
1449 if constexpr (USE_MEMORY_MAPS) { 1447 if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
1450 MappedUploadMemory(buffer, total_size_bytes, copies); 1448 MappedUploadMemory(buffer, total_size_bytes, copies);
1451 } else { 1449 } else {
1452 ImmediateUploadMemory(buffer, largest_copy, copies); 1450 ImmediateUploadMemory(buffer, largest_copy, copies);
@@ -1457,7 +1455,7 @@ template <class P>
1457void BufferCache<P>::ImmediateUploadMemory([[maybe_unused]] Buffer& buffer, 1455void BufferCache<P>::ImmediateUploadMemory([[maybe_unused]] Buffer& buffer,
1458 [[maybe_unused]] u64 largest_copy, 1456 [[maybe_unused]] u64 largest_copy,
1459 [[maybe_unused]] std::span<const BufferCopy> copies) { 1457 [[maybe_unused]] std::span<const BufferCopy> copies) {
1460 if constexpr (!USE_MEMORY_MAPS) { 1458 if constexpr (!USE_MEMORY_MAPS_FOR_UPLOADS) {
1461 std::span<u8> immediate_buffer; 1459 std::span<u8> immediate_buffer;
1462 for (const BufferCopy& copy : copies) { 1460 for (const BufferCopy& copy : copies) {
1463 std::span<const u8> upload_span; 1461 std::span<const u8> upload_span;
@@ -1516,7 +1514,7 @@ bool BufferCache<P>::InlineMemory(VAddr dest_address, size_t copy_size,
1516 auto& buffer = slot_buffers[buffer_id]; 1514 auto& buffer = slot_buffers[buffer_id];
1517 SynchronizeBuffer(buffer, dest_address, static_cast<u32>(copy_size)); 1515 SynchronizeBuffer(buffer, dest_address, static_cast<u32>(copy_size));
1518 1516
1519 if constexpr (USE_MEMORY_MAPS) { 1517 if constexpr (USE_MEMORY_MAPS_FOR_UPLOADS) {
1520 auto upload_staging = runtime.UploadStagingBuffer(copy_size); 1518 auto upload_staging = runtime.UploadStagingBuffer(copy_size);
1521 std::array copies{BufferCopy{ 1519 std::array copies{BufferCopy{
1522 .src_offset = upload_staging.offset, 1520 .src_offset = upload_staging.offset,
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index ac00d4d9d..7c6ef49d5 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -103,6 +103,7 @@ class BufferCache : public VideoCommon::ChannelSetupCaches<VideoCommon::ChannelI
103 static constexpr bool USE_MEMORY_MAPS = P::USE_MEMORY_MAPS; 103 static constexpr bool USE_MEMORY_MAPS = P::USE_MEMORY_MAPS;
104 static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS; 104 static constexpr bool SEPARATE_IMAGE_BUFFERS_BINDINGS = P::SEPARATE_IMAGE_BUFFER_BINDINGS;
105 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = P::IMPLEMENTS_ASYNC_DOWNLOADS; 105 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = P::IMPLEMENTS_ASYNC_DOWNLOADS;
106 static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = P::USE_MEMORY_MAPS_FOR_UPLOADS;
106 107
107 static constexpr BufferId NULL_BUFFER_ID{0}; 108 static constexpr BufferId NULL_BUFFER_ID{0};
108 109
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 6af4ae793..724e53edb 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -106,8 +106,10 @@ GLuint Buffer::View(u32 offset, u32 size, PixelFormat format) {
106 return views.back().texture.handle; 106 return views.back().texture.handle;
107} 107}
108 108
109BufferCacheRuntime::BufferCacheRuntime(const Device& device_) 109BufferCacheRuntime::BufferCacheRuntime(const Device& device_,
110 : device{device_}, has_fast_buffer_sub_data{device.HasFastBufferSubData()}, 110 StagingBufferPool& staging_buffer_pool_)
111 : device{device_}, staging_buffer_pool{staging_buffer_pool_},
112 has_fast_buffer_sub_data{device.HasFastBufferSubData()},
111 use_assembly_shaders{device.UseAssemblyShaders()}, 113 use_assembly_shaders{device.UseAssemblyShaders()},
112 has_unified_vertex_buffers{device.HasVertexBufferUnifiedMemory()}, 114 has_unified_vertex_buffers{device.HasVertexBufferUnifiedMemory()},
113 stream_buffer{has_fast_buffer_sub_data ? std::nullopt : std::make_optional<StreamBuffer>()} { 115 stream_buffer{has_fast_buffer_sub_data ? std::nullopt : std::make_optional<StreamBuffer>()} {
@@ -140,6 +142,14 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_)
140 }(); 142 }();
141} 143}
142 144
145StagingBufferMap BufferCacheRuntime::UploadStagingBuffer(size_t size) {
146 return staging_buffer_pool.RequestUploadBuffer(size);
147}
148
149StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size) {
150 return staging_buffer_pool.RequestDownloadBuffer(size);
151}
152
143u64 BufferCacheRuntime::GetDeviceMemoryUsage() const { 153u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
144 if (device.CanReportMemoryUsage()) { 154 if (device.CanReportMemoryUsage()) {
145 return device_access_memory - device.GetCurrentDedicatedVideoMemory(); 155 return device_access_memory - device.GetCurrentDedicatedVideoMemory();
@@ -147,15 +157,49 @@ u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
147 return 2_GiB; 157 return 2_GiB;
148} 158}
149 159
150void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer, 160void BufferCacheRuntime::CopyBuffer(GLuint dst_buffer, GLuint src_buffer,
151 std::span<const VideoCommon::BufferCopy> copies) { 161 std::span<const VideoCommon::BufferCopy> copies, bool barrier) {
162 if (barrier) {
163 PreCopyBarrier();
164 }
152 for (const VideoCommon::BufferCopy& copy : copies) { 165 for (const VideoCommon::BufferCopy& copy : copies) {
153 glCopyNamedBufferSubData( 166 glCopyNamedBufferSubData(src_buffer, dst_buffer, static_cast<GLintptr>(copy.src_offset),
154 src_buffer.Handle(), dst_buffer.Handle(), static_cast<GLintptr>(copy.src_offset), 167 static_cast<GLintptr>(copy.dst_offset),
155 static_cast<GLintptr>(copy.dst_offset), static_cast<GLsizeiptr>(copy.size)); 168 static_cast<GLsizeiptr>(copy.size));
169 }
170 if (barrier) {
171 PostCopyBarrier();
156 } 172 }
157} 173}
158 174
175void BufferCacheRuntime::CopyBuffer(GLuint dst_buffer, Buffer& src_buffer,
176 std::span<const VideoCommon::BufferCopy> copies, bool barrier) {
177 CopyBuffer(dst_buffer, src_buffer.Handle(), copies, barrier);
178}
179
180void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, GLuint src_buffer,
181 std::span<const VideoCommon::BufferCopy> copies, bool barrier) {
182 CopyBuffer(dst_buffer.Handle(), src_buffer, copies, barrier);
183}
184
185void BufferCacheRuntime::CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
186 std::span<const VideoCommon::BufferCopy> copies) {
187 CopyBuffer(dst_buffer.Handle(), src_buffer.Handle(), copies);
188}
189
190void BufferCacheRuntime::PreCopyBarrier() {
191 // TODO: finer grained barrier?
192 glMemoryBarrier(GL_ALL_BARRIER_BITS);
193}
194
195void BufferCacheRuntime::PostCopyBarrier() {
196 glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT | GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
197}
198
199void BufferCacheRuntime::Finish() {
200 glFinish();
201}
202
159void BufferCacheRuntime::ClearBuffer(Buffer& dest_buffer, u32 offset, size_t size, u32 value) { 203void BufferCacheRuntime::ClearBuffer(Buffer& dest_buffer, u32 offset, size_t size, u32 value) {
160 glClearNamedBufferSubData(dest_buffer.Handle(), GL_R32UI, static_cast<GLintptr>(offset), 204 glClearNamedBufferSubData(dest_buffer.Handle(), GL_R32UI, static_cast<GLintptr>(offset),
161 static_cast<GLsizeiptr>(size), GL_RED, GL_UNSIGNED_INT, &value); 205 static_cast<GLsizeiptr>(size), GL_RED, GL_UNSIGNED_INT, &value);
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index 18d3c3ac0..a24991585 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -12,7 +12,7 @@
12#include "video_core/rasterizer_interface.h" 12#include "video_core/rasterizer_interface.h"
13#include "video_core/renderer_opengl/gl_device.h" 13#include "video_core/renderer_opengl/gl_device.h"
14#include "video_core/renderer_opengl/gl_resource_manager.h" 14#include "video_core/renderer_opengl/gl_resource_manager.h"
15#include "video_core/renderer_opengl/gl_stream_buffer.h" 15#include "video_core/renderer_opengl/gl_staging_buffer_pool.h"
16 16
17namespace OpenGL { 17namespace OpenGL {
18 18
@@ -60,11 +60,28 @@ class BufferCacheRuntime {
60public: 60public:
61 static constexpr u8 INVALID_BINDING = std::numeric_limits<u8>::max(); 61 static constexpr u8 INVALID_BINDING = std::numeric_limits<u8>::max();
62 62
63 explicit BufferCacheRuntime(const Device& device_); 63 explicit BufferCacheRuntime(const Device& device_, StagingBufferPool& staging_buffer_pool_);
64
65 [[nodiscard]] StagingBufferMap UploadStagingBuffer(size_t size);
66
67 [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size);
68
69 void CopyBuffer(GLuint dst_buffer, GLuint src_buffer,
70 std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
71
72 void CopyBuffer(GLuint dst_buffer, Buffer& src_buffer,
73 std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
74
75 void CopyBuffer(Buffer& dst_buffer, GLuint src_buffer,
76 std::span<const VideoCommon::BufferCopy> copies, bool barrier = true);
64 77
65 void CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer, 78 void CopyBuffer(Buffer& dst_buffer, Buffer& src_buffer,
66 std::span<const VideoCommon::BufferCopy> copies); 79 std::span<const VideoCommon::BufferCopy> copies);
67 80
81 void PreCopyBarrier();
82 void PostCopyBarrier();
83 void Finish();
84
68 void ClearBuffer(Buffer& dest_buffer, u32 offset, size_t size, u32 value); 85 void ClearBuffer(Buffer& dest_buffer, u32 offset, size_t size, u32 value);
69 86
70 void BindIndexBuffer(Buffer& buffer, u32 offset, u32 size); 87 void BindIndexBuffer(Buffer& buffer, u32 offset, u32 size);
@@ -169,6 +186,7 @@ private:
169 }; 186 };
170 187
171 const Device& device; 188 const Device& device;
189 StagingBufferPool& staging_buffer_pool;
172 190
173 bool has_fast_buffer_sub_data = false; 191 bool has_fast_buffer_sub_data = false;
174 bool use_assembly_shaders = false; 192 bool use_assembly_shaders = false;
@@ -201,7 +219,7 @@ private:
201struct BufferCacheParams { 219struct BufferCacheParams {
202 using Runtime = OpenGL::BufferCacheRuntime; 220 using Runtime = OpenGL::BufferCacheRuntime;
203 using Buffer = OpenGL::Buffer; 221 using Buffer = OpenGL::Buffer;
204 using Async_Buffer = u32; 222 using Async_Buffer = OpenGL::StagingBufferMap;
205 using MemoryTracker = VideoCommon::MemoryTrackerBase<VideoCore::RasterizerInterface>; 223 using MemoryTracker = VideoCommon::MemoryTrackerBase<VideoCore::RasterizerInterface>;
206 224
207 static constexpr bool IS_OPENGL = true; 225 static constexpr bool IS_OPENGL = true;
@@ -209,9 +227,12 @@ struct BufferCacheParams {
209 static constexpr bool HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT = true; 227 static constexpr bool HAS_FULL_INDEX_AND_PRIMITIVE_SUPPORT = true;
210 static constexpr bool NEEDS_BIND_UNIFORM_INDEX = true; 228 static constexpr bool NEEDS_BIND_UNIFORM_INDEX = true;
211 static constexpr bool NEEDS_BIND_STORAGE_INDEX = true; 229 static constexpr bool NEEDS_BIND_STORAGE_INDEX = true;
212 static constexpr bool USE_MEMORY_MAPS = false; 230 static constexpr bool USE_MEMORY_MAPS = true;
213 static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true; 231 static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true;
214 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false; 232 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false;
233
234 // TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads
235 static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false;
215}; 236};
216 237
217using BufferCache = VideoCommon::BufferCache<BufferCacheParams>; 238using BufferCache = VideoCommon::BufferCache<BufferCacheParams>;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f5baa0f3c..fc711c44a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -24,6 +24,7 @@
24#include "video_core/renderer_opengl/gl_query_cache.h" 24#include "video_core/renderer_opengl/gl_query_cache.h"
25#include "video_core/renderer_opengl/gl_rasterizer.h" 25#include "video_core/renderer_opengl/gl_rasterizer.h"
26#include "video_core/renderer_opengl/gl_shader_cache.h" 26#include "video_core/renderer_opengl/gl_shader_cache.h"
27#include "video_core/renderer_opengl/gl_staging_buffer_pool.h"
27#include "video_core/renderer_opengl/gl_texture_cache.h" 28#include "video_core/renderer_opengl/gl_texture_cache.h"
28#include "video_core/renderer_opengl/maxwell_to_gl.h" 29#include "video_core/renderer_opengl/maxwell_to_gl.h"
29#include "video_core/renderer_opengl/renderer_opengl.h" 30#include "video_core/renderer_opengl/renderer_opengl.h"
@@ -58,8 +59,9 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra
58 StateTracker& state_tracker_) 59 StateTracker& state_tracker_)
59 : RasterizerAccelerated(cpu_memory_), gpu(gpu_), device(device_), screen_info(screen_info_), 60 : RasterizerAccelerated(cpu_memory_), gpu(gpu_), device(device_), screen_info(screen_info_),
60 program_manager(program_manager_), state_tracker(state_tracker_), 61 program_manager(program_manager_), state_tracker(state_tracker_),
61 texture_cache_runtime(device, program_manager, state_tracker), 62 texture_cache_runtime(device, program_manager, state_tracker, staging_buffer_pool),
62 texture_cache(texture_cache_runtime, *this), buffer_cache_runtime(device), 63 texture_cache(texture_cache_runtime, *this),
64 buffer_cache_runtime(device, staging_buffer_pool),
63 buffer_cache(*this, cpu_memory_, buffer_cache_runtime), 65 buffer_cache(*this, cpu_memory_, buffer_cache_runtime),
64 shader_cache(*this, emu_window_, device, texture_cache, buffer_cache, program_manager, 66 shader_cache(*this, emu_window_, device, texture_cache, buffer_cache, program_manager,
65 state_tracker, gpu.ShaderNotify()), 67 state_tracker, gpu.ShaderNotify()),
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 410d8ffc5..a73ad15c1 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -230,6 +230,7 @@ private:
230 ProgramManager& program_manager; 230 ProgramManager& program_manager;
231 StateTracker& state_tracker; 231 StateTracker& state_tracker;
232 232
233 StagingBufferPool staging_buffer_pool;
233 TextureCacheRuntime texture_cache_runtime; 234 TextureCacheRuntime texture_cache_runtime;
234 TextureCache texture_cache; 235 TextureCache texture_cache;
235 BufferCacheRuntime buffer_cache_runtime; 236 BufferCacheRuntime buffer_cache_runtime;
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
new file mode 100644
index 000000000..72b1dbb32
--- /dev/null
+++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
@@ -0,0 +1,134 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <array>
5#include <memory>
6#include <span>
7
8#include <glad/glad.h>
9
10#include "common/alignment.h"
11#include "common/assert.h"
12#include "video_core/renderer_opengl/gl_staging_buffer_pool.h"
13
14namespace OpenGL {
15
16StagingBufferMap::~StagingBufferMap() {
17 if (sync) {
18 sync->Create();
19 }
20}
21
22StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_)
23 : storage_flags{storage_flags_}, map_flags{map_flags_} {}
24
25StagingBuffers::~StagingBuffers() = default;
26
27StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence) {
28 const size_t index = RequestBuffer(requested_size);
29 OGLSync* const sync = insert_fence ? &syncs[index] : nullptr;
30 return StagingBufferMap{
31 .mapped_span = std::span(maps[index], requested_size),
32 .sync = sync,
33 .buffer = buffers[index].handle,
34 };
35}
36
37size_t StagingBuffers::RequestBuffer(size_t requested_size) {
38 if (const std::optional<size_t> index = FindBuffer(requested_size); index) {
39 return *index;
40 }
41
42 OGLBuffer& buffer = buffers.emplace_back();
43 buffer.Create();
44 glNamedBufferStorage(buffer.handle, requested_size, nullptr,
45 storage_flags | GL_MAP_PERSISTENT_BIT);
46 maps.push_back(static_cast<u8*>(glMapNamedBufferRange(buffer.handle, 0, requested_size,
47 map_flags | GL_MAP_PERSISTENT_BIT)));
48
49 syncs.emplace_back();
50 sizes.push_back(requested_size);
51
52 ASSERT(syncs.size() == buffers.size() && buffers.size() == maps.size() &&
53 maps.size() == sizes.size());
54
55 return buffers.size() - 1;
56}
57
58std::optional<size_t> StagingBuffers::FindBuffer(size_t requested_size) {
59 size_t smallest_buffer = std::numeric_limits<size_t>::max();
60 std::optional<size_t> found;
61 const size_t num_buffers = sizes.size();
62 for (size_t index = 0; index < num_buffers; ++index) {
63 const size_t buffer_size = sizes[index];
64 if (buffer_size < requested_size || buffer_size >= smallest_buffer) {
65 continue;
66 }
67 if (syncs[index].handle != 0) {
68 if (!syncs[index].IsSignaled()) {
69 continue;
70 }
71 syncs[index].Release();
72 }
73 smallest_buffer = buffer_size;
74 found = index;
75 }
76 return found;
77}
78
79StreamBuffer::StreamBuffer() {
80 static constexpr GLenum flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
81 buffer.Create();
82 glObjectLabel(GL_BUFFER, buffer.handle, -1, "Stream Buffer");
83 glNamedBufferStorage(buffer.handle, STREAM_BUFFER_SIZE, nullptr, flags);
84 mapped_pointer =
85 static_cast<u8*>(glMapNamedBufferRange(buffer.handle, 0, STREAM_BUFFER_SIZE, flags));
86 for (OGLSync& sync : fences) {
87 sync.Create();
88 }
89}
90
91std::pair<std::span<u8>, size_t> StreamBuffer::Request(size_t size) noexcept {
92 ASSERT(size < REGION_SIZE);
93 for (size_t region = Region(used_iterator), region_end = Region(iterator); region < region_end;
94 ++region) {
95 fences[region].Create();
96 }
97 used_iterator = iterator;
98
99 for (size_t region = Region(free_iterator) + 1,
100 region_end = std::min(Region(iterator + size) + 1, NUM_SYNCS);
101 region < region_end; ++region) {
102 glClientWaitSync(fences[region].handle, 0, GL_TIMEOUT_IGNORED);
103 fences[region].Release();
104 }
105 if (iterator + size >= free_iterator) {
106 free_iterator = iterator + size;
107 }
108 if (iterator + size > STREAM_BUFFER_SIZE) {
109 for (size_t region = Region(used_iterator); region < NUM_SYNCS; ++region) {
110 fences[region].Create();
111 }
112 used_iterator = 0;
113 iterator = 0;
114 free_iterator = size;
115
116 for (size_t region = 0, region_end = Region(size); region <= region_end; ++region) {
117 glClientWaitSync(fences[region].handle, 0, GL_TIMEOUT_IGNORED);
118 fences[region].Release();
119 }
120 }
121 const size_t offset = iterator;
122 iterator = Common::AlignUp(iterator + size, MAX_ALIGNMENT);
123 return {std::span(mapped_pointer + offset, size), offset};
124}
125
126StagingBufferMap StagingBufferPool::RequestUploadBuffer(size_t size) {
127 return upload_buffers.RequestMap(size, true);
128}
129
130StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size) {
131 return download_buffers.RequestMap(size, false);
132}
133
134} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.h b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
index 8fe927aaf..2c467be3d 100644
--- a/src/video_core/renderer_opengl/gl_stream_buffer.h
+++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
@@ -4,8 +4,10 @@
4#pragma once 4#pragma once
5 5
6#include <array> 6#include <array>
7#include <optional>
7#include <span> 8#include <span>
8#include <utility> 9#include <utility>
10#include <vector>
9 11
10#include <glad/glad.h> 12#include <glad/glad.h>
11 13
@@ -17,6 +19,33 @@ namespace OpenGL {
17 19
18using namespace Common::Literals; 20using namespace Common::Literals;
19 21
22struct StagingBufferMap {
23 ~StagingBufferMap();
24
25 std::span<u8> mapped_span;
26 size_t offset = 0;
27 OGLSync* sync;
28 GLuint buffer;
29};
30
31struct StagingBuffers {
32 explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
33 ~StagingBuffers();
34
35 StagingBufferMap RequestMap(size_t requested_size, bool insert_fence);
36
37 size_t RequestBuffer(size_t requested_size);
38
39 std::optional<size_t> FindBuffer(size_t requested_size);
40
41 std::vector<OGLSync> syncs;
42 std::vector<OGLBuffer> buffers;
43 std::vector<u8*> maps;
44 std::vector<size_t> sizes;
45 GLenum storage_flags;
46 GLenum map_flags;
47};
48
20class StreamBuffer { 49class StreamBuffer {
21 static constexpr size_t STREAM_BUFFER_SIZE = 64_MiB; 50 static constexpr size_t STREAM_BUFFER_SIZE = 64_MiB;
22 static constexpr size_t NUM_SYNCS = 16; 51 static constexpr size_t NUM_SYNCS = 16;
@@ -48,4 +77,17 @@ private:
48 std::array<OGLSync, NUM_SYNCS> fences; 77 std::array<OGLSync, NUM_SYNCS> fences;
49}; 78};
50 79
80class StagingBufferPool {
81public:
82 StagingBufferPool() = default;
83 ~StagingBufferPool() = default;
84
85 StagingBufferMap RequestUploadBuffer(size_t size);
86 StagingBufferMap RequestDownloadBuffer(size_t size);
87
88private:
89 StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT};
90 StagingBuffers download_buffers{GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT, GL_MAP_READ_BIT};
91};
92
51} // namespace OpenGL 93} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_stream_buffer.cpp b/src/video_core/renderer_opengl/gl_stream_buffer.cpp
deleted file mode 100644
index 2005c8993..000000000
--- a/src/video_core/renderer_opengl/gl_stream_buffer.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <array>
5#include <memory>
6#include <span>
7
8#include <glad/glad.h>
9
10#include "common/alignment.h"
11#include "common/assert.h"
12#include "video_core/renderer_opengl/gl_stream_buffer.h"
13
14namespace OpenGL {
15
16StreamBuffer::StreamBuffer() {
17 static constexpr GLenum flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
18 buffer.Create();
19 glObjectLabel(GL_BUFFER, buffer.handle, -1, "Stream Buffer");
20 glNamedBufferStorage(buffer.handle, STREAM_BUFFER_SIZE, nullptr, flags);
21 mapped_pointer =
22 static_cast<u8*>(glMapNamedBufferRange(buffer.handle, 0, STREAM_BUFFER_SIZE, flags));
23 for (OGLSync& sync : fences) {
24 sync.Create();
25 }
26}
27
28std::pair<std::span<u8>, size_t> StreamBuffer::Request(size_t size) noexcept {
29 ASSERT(size < REGION_SIZE);
30 for (size_t region = Region(used_iterator), region_end = Region(iterator); region < region_end;
31 ++region) {
32 fences[region].Create();
33 }
34 used_iterator = iterator;
35
36 for (size_t region = Region(free_iterator) + 1,
37 region_end = std::min(Region(iterator + size) + 1, NUM_SYNCS);
38 region < region_end; ++region) {
39 glClientWaitSync(fences[region].handle, 0, GL_TIMEOUT_IGNORED);
40 fences[region].Release();
41 }
42 if (iterator + size >= free_iterator) {
43 free_iterator = iterator + size;
44 }
45 if (iterator + size > STREAM_BUFFER_SIZE) {
46 for (size_t region = Region(used_iterator); region < NUM_SYNCS; ++region) {
47 fences[region].Create();
48 }
49 used_iterator = 0;
50 iterator = 0;
51 free_iterator = size;
52
53 for (size_t region = 0, region_end = Region(size); region <= region_end; ++region) {
54 glClientWaitSync(fences[region].handle, 0, GL_TIMEOUT_IGNORED);
55 fences[region].Release();
56 }
57 }
58 const size_t offset = iterator;
59 iterator = Common::AlignUp(iterator + size, MAX_ALIGNMENT);
60 return {std::span(mapped_pointer + offset, size), offset};
61}
62
63} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 1e0823836..ad87f3e80 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -451,19 +451,14 @@ OGLTexture MakeImage(const VideoCommon::ImageInfo& info, GLenum gl_internal_form
451 return is_srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8; 451 return is_srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8;
452 } 452 }
453} 453}
454
455} // Anonymous namespace 454} // Anonymous namespace
456 455
457ImageBufferMap::~ImageBufferMap() {
458 if (sync) {
459 sync->Create();
460 }
461}
462
463TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager, 456TextureCacheRuntime::TextureCacheRuntime(const Device& device_, ProgramManager& program_manager,
464 StateTracker& state_tracker_) 457 StateTracker& state_tracker_,
465 : device{device_}, state_tracker{state_tracker_}, util_shaders(program_manager), 458 StagingBufferPool& staging_buffer_pool_)
466 format_conversion_pass{util_shaders}, resolution{Settings::values.resolution_info} { 459 : device{device_}, state_tracker{state_tracker_}, staging_buffer_pool{staging_buffer_pool_},
460 util_shaders(program_manager), format_conversion_pass{util_shaders},
461 resolution{Settings::values.resolution_info} {
467 static constexpr std::array TARGETS{GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D}; 462 static constexpr std::array TARGETS{GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D};
468 for (size_t i = 0; i < TARGETS.size(); ++i) { 463 for (size_t i = 0; i < TARGETS.size(); ++i) {
469 const GLenum target = TARGETS[i]; 464 const GLenum target = TARGETS[i];
@@ -553,12 +548,12 @@ void TextureCacheRuntime::Finish() {
553 glFinish(); 548 glFinish();
554} 549}
555 550
556ImageBufferMap TextureCacheRuntime::UploadStagingBuffer(size_t size) { 551StagingBufferMap TextureCacheRuntime::UploadStagingBuffer(size_t size) {
557 return upload_buffers.RequestMap(size, true); 552 return staging_buffer_pool.RequestUploadBuffer(size);
558} 553}
559 554
560ImageBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size) { 555StagingBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size) {
561 return download_buffers.RequestMap(size, false); 556 return staging_buffer_pool.RequestDownloadBuffer(size);
562} 557}
563 558
564u64 TextureCacheRuntime::GetDeviceMemoryUsage() const { 559u64 TextureCacheRuntime::GetDeviceMemoryUsage() const {
@@ -643,7 +638,7 @@ void TextureCacheRuntime::BlitFramebuffer(Framebuffer* dst, Framebuffer* src,
643 is_linear ? GL_LINEAR : GL_NEAREST); 638 is_linear ? GL_LINEAR : GL_NEAREST);
644} 639}
645 640
646void TextureCacheRuntime::AccelerateImageUpload(Image& image, const ImageBufferMap& map, 641void TextureCacheRuntime::AccelerateImageUpload(Image& image, const StagingBufferMap& map,
647 std::span<const SwizzleParameters> swizzles) { 642 std::span<const SwizzleParameters> swizzles) {
648 switch (image.info.type) { 643 switch (image.info.type) {
649 case ImageType::e2D: 644 case ImageType::e2D:
@@ -685,64 +680,6 @@ bool TextureCacheRuntime::HasNativeASTC() const noexcept {
685 return device.HasASTC(); 680 return device.HasASTC();
686} 681}
687 682
688TextureCacheRuntime::StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_)
689 : storage_flags{storage_flags_}, map_flags{map_flags_} {}
690
691TextureCacheRuntime::StagingBuffers::~StagingBuffers() = default;
692
693ImageBufferMap TextureCacheRuntime::StagingBuffers::RequestMap(size_t requested_size,
694 bool insert_fence) {
695 const size_t index = RequestBuffer(requested_size);
696 OGLSync* const sync = insert_fence ? &syncs[index] : nullptr;
697 return ImageBufferMap{
698 .mapped_span = std::span(maps[index], requested_size),
699 .sync = sync,
700 .buffer = buffers[index].handle,
701 };
702}
703
704size_t TextureCacheRuntime::StagingBuffers::RequestBuffer(size_t requested_size) {
705 if (const std::optional<size_t> index = FindBuffer(requested_size); index) {
706 return *index;
707 }
708
709 OGLBuffer& buffer = buffers.emplace_back();
710 buffer.Create();
711 glNamedBufferStorage(buffer.handle, requested_size, nullptr,
712 storage_flags | GL_MAP_PERSISTENT_BIT);
713 maps.push_back(static_cast<u8*>(glMapNamedBufferRange(buffer.handle, 0, requested_size,
714 map_flags | GL_MAP_PERSISTENT_BIT)));
715
716 syncs.emplace_back();
717 sizes.push_back(requested_size);
718
719 ASSERT(syncs.size() == buffers.size() && buffers.size() == maps.size() &&
720 maps.size() == sizes.size());
721
722 return buffers.size() - 1;
723}
724
725std::optional<size_t> TextureCacheRuntime::StagingBuffers::FindBuffer(size_t requested_size) {
726 size_t smallest_buffer = std::numeric_limits<size_t>::max();
727 std::optional<size_t> found;
728 const size_t num_buffers = sizes.size();
729 for (size_t index = 0; index < num_buffers; ++index) {
730 const size_t buffer_size = sizes[index];
731 if (buffer_size < requested_size || buffer_size >= smallest_buffer) {
732 continue;
733 }
734 if (syncs[index].handle != 0) {
735 if (!syncs[index].IsSignaled()) {
736 continue;
737 }
738 syncs[index].Release();
739 }
740 smallest_buffer = buffer_size;
741 found = index;
742 }
743 return found;
744}
745
746Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_, 683Image::Image(TextureCacheRuntime& runtime_, const VideoCommon::ImageInfo& info_, GPUVAddr gpu_addr_,
747 VAddr cpu_addr_) 684 VAddr cpu_addr_)
748 : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), runtime{&runtime_} { 685 : VideoCommon::ImageBase(info_, gpu_addr_, cpu_addr_), runtime{&runtime_} {
@@ -818,7 +755,7 @@ void Image::UploadMemory(GLuint buffer_handle, size_t buffer_offset,
818 } 755 }
819} 756}
820 757
821void Image::UploadMemory(const ImageBufferMap& map, 758void Image::UploadMemory(const StagingBufferMap& map,
822 std::span<const VideoCommon::BufferImageCopy> copies) { 759 std::span<const VideoCommon::BufferImageCopy> copies) {
823 UploadMemory(map.buffer, map.offset, copies); 760 UploadMemory(map.buffer, map.offset, copies);
824} 761}
@@ -865,7 +802,7 @@ void Image::DownloadMemory(std::span<GLuint> buffer_handles, std::span<size_t> b
865 } 802 }
866} 803}
867 804
868void Image::DownloadMemory(ImageBufferMap& map, 805void Image::DownloadMemory(StagingBufferMap& map,
869 std::span<const VideoCommon::BufferImageCopy> copies) { 806 std::span<const VideoCommon::BufferImageCopy> copies) {
870 DownloadMemory(map.buffer, map.offset, copies); 807 DownloadMemory(map.buffer, map.offset, copies);
871} 808}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 3e9b3302b..1148b73d7 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -11,6 +11,7 @@
11#include "shader_recompiler/shader_info.h" 11#include "shader_recompiler/shader_info.h"
12#include "video_core/renderer_opengl/gl_device.h" 12#include "video_core/renderer_opengl/gl_device.h"
13#include "video_core/renderer_opengl/gl_resource_manager.h" 13#include "video_core/renderer_opengl/gl_resource_manager.h"
14#include "video_core/renderer_opengl/gl_staging_buffer_pool.h"
14#include "video_core/renderer_opengl/util_shaders.h" 15#include "video_core/renderer_opengl/util_shaders.h"
15#include "video_core/texture_cache/image_view_base.h" 16#include "video_core/texture_cache/image_view_base.h"
16#include "video_core/texture_cache/texture_cache_base.h" 17#include "video_core/texture_cache/texture_cache_base.h"
@@ -37,15 +38,6 @@ using VideoCommon::Region2D;
37using VideoCommon::RenderTargets; 38using VideoCommon::RenderTargets;
38using VideoCommon::SlotVector; 39using VideoCommon::SlotVector;
39 40
40struct ImageBufferMap {
41 ~ImageBufferMap();
42
43 std::span<u8> mapped_span;
44 size_t offset = 0;
45 OGLSync* sync;
46 GLuint buffer;
47};
48
49struct FormatProperties { 41struct FormatProperties {
50 GLenum compatibility_class; 42 GLenum compatibility_class;
51 bool compatibility_by_size; 43 bool compatibility_by_size;
@@ -74,14 +66,15 @@ class TextureCacheRuntime {
74 66
75public: 67public:
76 explicit TextureCacheRuntime(const Device& device, ProgramManager& program_manager, 68 explicit TextureCacheRuntime(const Device& device, ProgramManager& program_manager,
77 StateTracker& state_tracker); 69 StateTracker& state_tracker,
70 StagingBufferPool& staging_buffer_pool);
78 ~TextureCacheRuntime(); 71 ~TextureCacheRuntime();
79 72
80 void Finish(); 73 void Finish();
81 74
82 ImageBufferMap UploadStagingBuffer(size_t size); 75 StagingBufferMap UploadStagingBuffer(size_t size);
83 76
84 ImageBufferMap DownloadStagingBuffer(size_t size); 77 StagingBufferMap DownloadStagingBuffer(size_t size);
85 78
86 u64 GetDeviceLocalMemory() const { 79 u64 GetDeviceLocalMemory() const {
87 return device_access_memory; 80 return device_access_memory;
@@ -120,7 +113,7 @@ public:
120 const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter, 113 const Region2D& src_region, Tegra::Engines::Fermi2D::Filter filter,
121 Tegra::Engines::Fermi2D::Operation operation); 114 Tegra::Engines::Fermi2D::Operation operation);
122 115
123 void AccelerateImageUpload(Image& image, const ImageBufferMap& map, 116 void AccelerateImageUpload(Image& image, const StagingBufferMap& map,
124 std::span<const VideoCommon::SwizzleParameters> swizzles); 117 std::span<const VideoCommon::SwizzleParameters> swizzles);
125 118
126 void InsertUploadMemoryBarrier(); 119 void InsertUploadMemoryBarrier();
@@ -149,35 +142,16 @@ public:
149 } 142 }
150 143
151private: 144private:
152 struct StagingBuffers {
153 explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
154 ~StagingBuffers();
155
156 ImageBufferMap RequestMap(size_t requested_size, bool insert_fence);
157
158 size_t RequestBuffer(size_t requested_size);
159
160 std::optional<size_t> FindBuffer(size_t requested_size);
161
162 std::vector<OGLSync> syncs;
163 std::vector<OGLBuffer> buffers;
164 std::vector<u8*> maps;
165 std::vector<size_t> sizes;
166 GLenum storage_flags;
167 GLenum map_flags;
168 };
169
170 const Device& device; 145 const Device& device;
171 StateTracker& state_tracker; 146 StateTracker& state_tracker;
147 StagingBufferPool& staging_buffer_pool;
148
172 UtilShaders util_shaders; 149 UtilShaders util_shaders;
173 FormatConversionPass format_conversion_pass; 150 FormatConversionPass format_conversion_pass;
174 151
175 std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties; 152 std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties;
176 bool has_broken_texture_view_formats = false; 153 bool has_broken_texture_view_formats = false;
177 154
178 StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT};
179 StagingBuffers download_buffers{GL_MAP_READ_BIT | GL_CLIENT_STORAGE_BIT, GL_MAP_READ_BIT};
180
181 OGLTexture null_image_1d_array; 155 OGLTexture null_image_1d_array;
182 OGLTexture null_image_cube_array; 156 OGLTexture null_image_cube_array;
183 OGLTexture null_image_3d; 157 OGLTexture null_image_3d;
@@ -213,7 +187,7 @@ public:
213 void UploadMemory(GLuint buffer_handle, size_t buffer_offset, 187 void UploadMemory(GLuint buffer_handle, size_t buffer_offset,
214 std::span<const VideoCommon::BufferImageCopy> copies); 188 std::span<const VideoCommon::BufferImageCopy> copies);
215 189
216 void UploadMemory(const ImageBufferMap& map, 190 void UploadMemory(const StagingBufferMap& map,
217 std::span<const VideoCommon::BufferImageCopy> copies); 191 std::span<const VideoCommon::BufferImageCopy> copies);
218 192
219 void DownloadMemory(GLuint buffer_handle, size_t buffer_offset, 193 void DownloadMemory(GLuint buffer_handle, size_t buffer_offset,
@@ -222,7 +196,8 @@ public:
222 void DownloadMemory(std::span<GLuint> buffer_handle, std::span<size_t> buffer_offset, 196 void DownloadMemory(std::span<GLuint> buffer_handle, std::span<size_t> buffer_offset,
223 std::span<const VideoCommon::BufferImageCopy> copies); 197 std::span<const VideoCommon::BufferImageCopy> copies);
224 198
225 void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies); 199 void DownloadMemory(StagingBufferMap& map,
200 std::span<const VideoCommon::BufferImageCopy> copies);
226 201
227 GLuint StorageHandle() noexcept; 202 GLuint StorageHandle() noexcept;
228 203
diff --git a/src/video_core/renderer_opengl/util_shaders.cpp b/src/video_core/renderer_opengl/util_shaders.cpp
index 2c7ac210b..544982d18 100644
--- a/src/video_core/renderer_opengl/util_shaders.cpp
+++ b/src/video_core/renderer_opengl/util_shaders.cpp
@@ -19,6 +19,7 @@
19#include "video_core/host_shaders/pitch_unswizzle_comp.h" 19#include "video_core/host_shaders/pitch_unswizzle_comp.h"
20#include "video_core/renderer_opengl/gl_shader_manager.h" 20#include "video_core/renderer_opengl/gl_shader_manager.h"
21#include "video_core/renderer_opengl/gl_shader_util.h" 21#include "video_core/renderer_opengl/gl_shader_util.h"
22#include "video_core/renderer_opengl/gl_staging_buffer_pool.h"
22#include "video_core/renderer_opengl/gl_texture_cache.h" 23#include "video_core/renderer_opengl/gl_texture_cache.h"
23#include "video_core/renderer_opengl/util_shaders.h" 24#include "video_core/renderer_opengl/util_shaders.h"
24#include "video_core/texture_cache/accelerated_swizzle.h" 25#include "video_core/texture_cache/accelerated_swizzle.h"
@@ -63,7 +64,7 @@ UtilShaders::UtilShaders(ProgramManager& program_manager_)
63 64
64UtilShaders::~UtilShaders() = default; 65UtilShaders::~UtilShaders() = default;
65 66
66void UtilShaders::ASTCDecode(Image& image, const ImageBufferMap& map, 67void UtilShaders::ASTCDecode(Image& image, const StagingBufferMap& map,
67 std::span<const VideoCommon::SwizzleParameters> swizzles) { 68 std::span<const VideoCommon::SwizzleParameters> swizzles) {
68 static constexpr GLuint BINDING_INPUT_BUFFER = 0; 69 static constexpr GLuint BINDING_INPUT_BUFFER = 0;
69 static constexpr GLuint BINDING_OUTPUT_IMAGE = 0; 70 static constexpr GLuint BINDING_OUTPUT_IMAGE = 0;
@@ -111,7 +112,7 @@ void UtilShaders::ASTCDecode(Image& image, const ImageBufferMap& map,
111 program_manager.RestoreGuestCompute(); 112 program_manager.RestoreGuestCompute();
112} 113}
113 114
114void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map, 115void UtilShaders::BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
115 std::span<const SwizzleParameters> swizzles) { 116 std::span<const SwizzleParameters> swizzles) {
116 static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1}; 117 static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1};
117 static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0; 118 static constexpr GLuint BINDING_SWIZZLE_BUFFER = 0;
@@ -148,7 +149,7 @@ void UtilShaders::BlockLinearUpload2D(Image& image, const ImageBufferMap& map,
148 program_manager.RestoreGuestCompute(); 149 program_manager.RestoreGuestCompute();
149} 150}
150 151
151void UtilShaders::BlockLinearUpload3D(Image& image, const ImageBufferMap& map, 152void UtilShaders::BlockLinearUpload3D(Image& image, const StagingBufferMap& map,
152 std::span<const SwizzleParameters> swizzles) { 153 std::span<const SwizzleParameters> swizzles) {
153 static constexpr Extent3D WORKGROUP_SIZE{16, 8, 8}; 154 static constexpr Extent3D WORKGROUP_SIZE{16, 8, 8};
154 155
@@ -189,7 +190,7 @@ void UtilShaders::BlockLinearUpload3D(Image& image, const ImageBufferMap& map,
189 program_manager.RestoreGuestCompute(); 190 program_manager.RestoreGuestCompute();
190} 191}
191 192
192void UtilShaders::PitchUpload(Image& image, const ImageBufferMap& map, 193void UtilShaders::PitchUpload(Image& image, const StagingBufferMap& map,
193 std::span<const SwizzleParameters> swizzles) { 194 std::span<const SwizzleParameters> swizzles) {
194 static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1}; 195 static constexpr Extent3D WORKGROUP_SIZE{32, 32, 1};
195 static constexpr GLuint BINDING_INPUT_BUFFER = 0; 196 static constexpr GLuint BINDING_INPUT_BUFFER = 0;
diff --git a/src/video_core/renderer_opengl/util_shaders.h b/src/video_core/renderer_opengl/util_shaders.h
index 9013808e7..feecd404c 100644
--- a/src/video_core/renderer_opengl/util_shaders.h
+++ b/src/video_core/renderer_opengl/util_shaders.h
@@ -16,23 +16,23 @@ namespace OpenGL {
16class Image; 16class Image;
17class ProgramManager; 17class ProgramManager;
18 18
19struct ImageBufferMap; 19struct StagingBufferMap;
20 20
21class UtilShaders { 21class UtilShaders {
22public: 22public:
23 explicit UtilShaders(ProgramManager& program_manager); 23 explicit UtilShaders(ProgramManager& program_manager);
24 ~UtilShaders(); 24 ~UtilShaders();
25 25
26 void ASTCDecode(Image& image, const ImageBufferMap& map, 26 void ASTCDecode(Image& image, const StagingBufferMap& map,
27 std::span<const VideoCommon::SwizzleParameters> swizzles); 27 std::span<const VideoCommon::SwizzleParameters> swizzles);
28 28
29 void BlockLinearUpload2D(Image& image, const ImageBufferMap& map, 29 void BlockLinearUpload2D(Image& image, const StagingBufferMap& map,
30 std::span<const VideoCommon::SwizzleParameters> swizzles); 30 std::span<const VideoCommon::SwizzleParameters> swizzles);
31 31
32 void BlockLinearUpload3D(Image& image, const ImageBufferMap& map, 32 void BlockLinearUpload3D(Image& image, const StagingBufferMap& map,
33 std::span<const VideoCommon::SwizzleParameters> swizzles); 33 std::span<const VideoCommon::SwizzleParameters> swizzles);
34 34
35 void PitchUpload(Image& image, const ImageBufferMap& map, 35 void PitchUpload(Image& image, const StagingBufferMap& map,
36 std::span<const VideoCommon::SwizzleParameters> swizzles); 36 std::span<const VideoCommon::SwizzleParameters> swizzles);
37 37
38 void CopyBC4(Image& dst_image, Image& src_image, 38 void CopyBC4(Image& dst_image, Image& src_image,
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index 5e9602905..b1f3c071f 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -157,6 +157,7 @@ struct BufferCacheParams {
157 static constexpr bool USE_MEMORY_MAPS = true; 157 static constexpr bool USE_MEMORY_MAPS = true;
158 static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = false; 158 static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = false;
159 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true; 159 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true;
160 static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = true;
160}; 161};
161 162
162using BufferCache = VideoCommon::BufferCache<BufferCacheParams>; 163using BufferCache = VideoCommon::BufferCache<BufferCacheParams>;