summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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>;