summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/jni/native.cpp3
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/host_memory.cpp28
-rw-r--r--src/core/file_sys/patch_manager.cpp4
-rw-r--r--src/core/file_sys/romfs.cpp19
-rw-r--r--src/core/file_sys/romfs_factory.cpp2
-rw-r--r--src/core/hle/service/nfc/common/device.cpp10
-rw-r--r--src/core/loader/nca.cpp6
-rw-r--r--src/shader_recompiler/backend/glsl/glsl_emit_context.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp84
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h7
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp1
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp66
-rw-r--r--src/video_core/renderer_opengl/gl_staging_buffer_pool.h22
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h8
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp17
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp6
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.h4
-rw-r--r--src/video_core/texture_cache/texture_cache.h2
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/main.cpp5
24 files changed, 159 insertions, 159 deletions
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index ed5ce6f8a..3d795b57f 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -123,9 +123,6 @@ int EmulationSession::InstallFileToNand(std::string filename, std::string file_e
123 ErrorFilenameExtension = 4, 123 ErrorFilenameExtension = 4,
124 }; 124 };
125 125
126 m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
127 m_system.GetFileSystemController().CreateFactories(*m_vfs);
128
129 [[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp; 126 [[maybe_unused]] std::shared_ptr<FileSys::NSP> nsp;
130 if (file_extension == "nsp") { 127 if (file_extension == "nsp") {
131 nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read)); 128 nsp = std::make_shared<FileSys::NSP>(m_vfs->OpenFile(filename, FileSys::Mode::Read));
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 2c6fc7657..b58a7073f 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -188,7 +188,7 @@ if (UNIX AND NOT APPLE)
188 linux/gamemode.h 188 linux/gamemode.h
189 ) 189 )
190 190
191 target_link_libraries(common PRIVATE gamemode) 191 target_link_libraries(common PRIVATE gamemode::headers)
192endif() 192endif()
193 193
194if(ARCHITECTURE_x86_64) 194if(ARCHITECTURE_x86_64)
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 3a9ea6eb4..4bfc64f2d 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -25,6 +25,10 @@
25#include <unistd.h> 25#include <unistd.h>
26#include "common/scope_exit.h" 26#include "common/scope_exit.h"
27 27
28#ifndef MAP_NORESERVE
29#define MAP_NORESERVE 0
30#endif
31
28#endif // ^^^ Linux ^^^ 32#endif // ^^^ Linux ^^^
29 33
30#include <mutex> 34#include <mutex>
@@ -404,6 +408,16 @@ static void* ChooseVirtualBase(size_t virtual_size) {
404#else 408#else
405 409
406static void* ChooseVirtualBase(size_t virtual_size) { 410static void* ChooseVirtualBase(size_t virtual_size) {
411#if defined(__FreeBSD__)
412 void* virtual_base =
413 mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
414 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
415
416 if (virtual_base != MAP_FAILED) {
417 return virtual_base;
418 }
419#endif
420
407 return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, 421 return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE,
408 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); 422 MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
409} 423}
@@ -459,24 +473,12 @@ public:
459 } 473 }
460 474
461 // Virtual memory initialization 475 // Virtual memory initialization
462#if defined(__FreeBSD__)
463 virtual_base =
464 static_cast<u8*>(mmap(nullptr, virtual_size, PROT_NONE,
465 MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0));
466 if (virtual_base == MAP_FAILED) {
467 virtual_base = static_cast<u8*>(
468 mmap(nullptr, virtual_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
469 if (virtual_base == MAP_FAILED) {
470 LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
471 throw std::bad_alloc{};
472 }
473 }
474#else
475 virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size)); 476 virtual_base = virtual_map_base = static_cast<u8*>(ChooseVirtualBase(virtual_size));
476 if (virtual_base == MAP_FAILED) { 477 if (virtual_base == MAP_FAILED) {
477 LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno)); 478 LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno));
478 throw std::bad_alloc{}; 479 throw std::bad_alloc{};
479 } 480 }
481#if defined(__linux__)
480 madvise(virtual_base, virtual_size, MADV_HUGEPAGE); 482 madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
481#endif 483#endif
482 484
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index 0bca05587..cc7af2ea3 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -429,10 +429,6 @@ VirtualFile PatchManager::PatchRomFS(const NCA* base_nca, VirtualFile base_romfs
429 LOG_DEBUG(Loader, "{}", log_string); 429 LOG_DEBUG(Loader, "{}", log_string);
430 } 430 }
431 431
432 if (base_romfs == nullptr) {
433 return base_romfs;
434 }
435
436 auto romfs = base_romfs; 432 auto romfs = base_romfs;
437 433
438 // Game Updates 434 // Game Updates
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
index 1eb1f439a..6de2103a0 100644
--- a/src/core/file_sys/romfs.cpp
+++ b/src/core/file_sys/romfs.cpp
@@ -3,6 +3,7 @@
3 3
4#include <memory> 4#include <memory>
5 5
6#include "common/assert.h"
6#include "common/common_types.h" 7#include "common/common_types.h"
7#include "common/string_util.h" 8#include "common/string_util.h"
8#include "common/swap.h" 9#include "common/swap.h"
@@ -101,24 +102,30 @@ void ProcessDirectory(const VirtualFile& file, std::size_t dir_offset, std::size
101} // Anonymous namespace 102} // Anonymous namespace
102 103
103VirtualDir ExtractRomFS(VirtualFile file) { 104VirtualDir ExtractRomFS(VirtualFile file) {
105 auto root_container = std::make_shared<VectorVfsDirectory>();
106 if (!file) {
107 return root_container;
108 }
109
104 RomFSHeader header{}; 110 RomFSHeader header{};
105 if (file->ReadObject(&header) != sizeof(RomFSHeader)) 111 if (file->ReadObject(&header) != sizeof(RomFSHeader)) {
106 return nullptr; 112 return root_container;
113 }
107 114
108 if (header.header_size != sizeof(RomFSHeader)) 115 if (header.header_size != sizeof(RomFSHeader)) {
109 return nullptr; 116 return root_container;
117 }
110 118
111 const u64 file_offset = header.file_meta.offset; 119 const u64 file_offset = header.file_meta.offset;
112 const u64 dir_offset = header.directory_meta.offset; 120 const u64 dir_offset = header.directory_meta.offset;
113 121
114 auto root_container = std::make_shared<VectorVfsDirectory>();
115
116 ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root_container); 122 ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root_container);
117 123
118 if (auto root = root_container->GetSubdirectory(""); root) { 124 if (auto root = root_container->GetSubdirectory(""); root) {
119 return std::make_shared<CachedVfsDirectory>(std::move(root)); 125 return std::make_shared<CachedVfsDirectory>(std::move(root));
120 } 126 }
121 127
128 ASSERT(false);
122 return nullptr; 129 return nullptr;
123} 130}
124 131
diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp
index 1bc07dae5..35e149905 100644
--- a/src/core/file_sys/romfs_factory.cpp
+++ b/src/core/file_sys/romfs_factory.cpp
@@ -22,7 +22,7 @@ RomFSFactory::RomFSFactory(Loader::AppLoader& app_loader, ContentProvider& provi
22 : content_provider{provider}, filesystem_controller{controller} { 22 : content_provider{provider}, filesystem_controller{controller} {
23 // Load the RomFS from the app 23 // Load the RomFS from the app
24 if (app_loader.ReadRomFS(file) != Loader::ResultStatus::Success) { 24 if (app_loader.ReadRomFS(file) != Loader::ResultStatus::Success) {
25 LOG_ERROR(Service_FS, "Unable to read RomFS!"); 25 LOG_WARNING(Service_FS, "Unable to read base RomFS");
26 } 26 }
27 27
28 updatable = app_loader.IsRomFSUpdatable(); 28 updatable = app_loader.IsRomFSUpdatable();
diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp
index 47516f883..f97e5b44c 100644
--- a/src/core/hle/service/nfc/common/device.cpp
+++ b/src/core/hle/service/nfc/common/device.cpp
@@ -438,16 +438,16 @@ Result NfcDevice::Mount(NFP::ModelType model_type, NFP::MountTarget mount_target
438 is_corrupted = true; 438 is_corrupted = true;
439 } 439 }
440 440
441 if (!is_corrupted) { 441 device_state = DeviceState::TagMounted;
442 mount_target = mount_target_;
443
444 if (!is_corrupted && mount_target != NFP::MountTarget::Rom) {
442 std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File)); 445 std::vector<u8> data(sizeof(NFP::EncryptedNTAG215File));
443 memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data)); 446 memcpy(data.data(), &encrypted_tag_data, sizeof(encrypted_tag_data));
444 WriteBackupData(encrypted_tag_data.uuid, data); 447 WriteBackupData(encrypted_tag_data.uuid, data);
445 } 448 }
446 449
447 device_state = DeviceState::TagMounted; 450 if (is_corrupted && mount_target != NFP::MountTarget::Rom) {
448 mount_target = mount_target_;
449
450 if (is_corrupted) {
451 bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess(); 451 bool has_backup = HasBackup(encrypted_tag_data.uuid).IsSuccess();
452 return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData; 452 return has_backup ? ResultCorruptedDataWithBackup : ResultCorruptedData;
453 } 453 }
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp
index 4feb6968a..814407535 100644
--- a/src/core/loader/nca.cpp
+++ b/src/core/loader/nca.cpp
@@ -74,10 +74,8 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::S
74 return load_result; 74 return load_result;
75 } 75 }
76 76
77 if (nca->GetRomFS() != nullptr && nca->GetRomFS()->GetSize() > 0) { 77 system.GetFileSystemController().RegisterRomFS(std::make_unique<FileSys::RomFSFactory>(
78 system.GetFileSystemController().RegisterRomFS(std::make_unique<FileSys::RomFSFactory>( 78 *this, system.GetContentProvider(), system.GetFileSystemController()));
79 *this, system.GetContentProvider(), system.GetFileSystemController()));
80 }
81 79
82 is_loaded = true; 80 is_loaded = true;
83 return load_result; 81 return load_result;
diff --git a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
index fd9a99449..b2ceeefc4 100644
--- a/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
+++ b/src/shader_recompiler/backend/glsl/glsl_emit_context.cpp
@@ -1,6 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "common/div_ceil.h"
4#include "shader_recompiler/backend/bindings.h" 5#include "shader_recompiler/backend/bindings.h"
5#include "shader_recompiler/backend/glsl/glsl_emit_context.h" 6#include "shader_recompiler/backend/glsl/glsl_emit_context.h"
6#include "shader_recompiler/frontend/ir/program.h" 7#include "shader_recompiler/frontend/ir/program.h"
@@ -431,9 +432,11 @@ void EmitContext::DefineConstantBuffers(Bindings& bindings) {
431 } 432 }
432 for (const auto& desc : info.constant_buffer_descriptors) { 433 for (const auto& desc : info.constant_buffer_descriptors) {
433 const auto cbuf_type{profile.has_gl_cbuf_ftou_bug ? "uvec4" : "vec4"}; 434 const auto cbuf_type{profile.has_gl_cbuf_ftou_bug ? "uvec4" : "vec4"};
435 const u32 cbuf_used_size{Common::DivCeil(info.constant_buffer_used_sizes[desc.index], 16U)};
436 const u32 cbuf_binding_size{info.uses_global_memory ? 0x1000U : cbuf_used_size};
434 header += fmt::format("layout(std140,binding={}) uniform {}_cbuf_{}{{{} {}_cbuf{}[{}];}};", 437 header += fmt::format("layout(std140,binding={}) uniform {}_cbuf_{}{{{} {}_cbuf{}[{}];}};",
435 bindings.uniform_buffer, stage_name, desc.index, cbuf_type, 438 bindings.uniform_buffer, stage_name, desc.index, cbuf_type,
436 stage_name, desc.index, 4 * 1024); 439 stage_name, desc.index, cbuf_binding_size);
437 bindings.uniform_buffer += desc.count; 440 bindings.uniform_buffer += desc.count;
438 } 441 }
439} 442}
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index dfd696de6..e6c70fb34 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -53,13 +53,11 @@ Buffer::Buffer(BufferCacheRuntime& runtime, VideoCore::RasterizerInterface& rast
53 VAddr cpu_addr_, u64 size_bytes_) 53 VAddr cpu_addr_, u64 size_bytes_)
54 : VideoCommon::BufferBase<VideoCore::RasterizerInterface>(rasterizer_, cpu_addr_, size_bytes_) { 54 : VideoCommon::BufferBase<VideoCore::RasterizerInterface>(rasterizer_, cpu_addr_, size_bytes_) {
55 buffer.Create(); 55 buffer.Create();
56 const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr()); 56 if (runtime.device.HasDebuggingToolAttached()) {
57 glObjectLabel(GL_BUFFER, buffer.handle, static_cast<GLsizei>(name.size()), name.data()); 57 const std::string name = fmt::format("Buffer 0x{:x}", CpuAddr());
58 glNamedBufferData(buffer.handle, SizeBytes(), nullptr, GL_DYNAMIC_DRAW); 58 glObjectLabel(GL_BUFFER, buffer.handle, static_cast<GLsizei>(name.size()), name.data());
59
60 if (runtime.has_unified_vertex_buffers) {
61 glGetNamedBufferParameterui64vNV(buffer.handle, GL_BUFFER_GPU_ADDRESS_NV, &address);
62 } 59 }
60 glNamedBufferData(buffer.handle, SizeBytes(), nullptr, GL_DYNAMIC_DRAW);
63} 61}
64 62
65void Buffer::ImmediateUpload(size_t offset, std::span<const u8> data) noexcept { 63void Buffer::ImmediateUpload(size_t offset, std::span<const u8> data) noexcept {
@@ -111,7 +109,6 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_,
111 : device{device_}, staging_buffer_pool{staging_buffer_pool_}, 109 : device{device_}, staging_buffer_pool{staging_buffer_pool_},
112 has_fast_buffer_sub_data{device.HasFastBufferSubData()}, 110 has_fast_buffer_sub_data{device.HasFastBufferSubData()},
113 use_assembly_shaders{device.UseAssemblyShaders()}, 111 use_assembly_shaders{device.UseAssemblyShaders()},
114 has_unified_vertex_buffers{device.HasVertexBufferUnifiedMemory()},
115 stream_buffer{has_fast_buffer_sub_data ? std::nullopt : std::make_optional<StreamBuffer>()} { 112 stream_buffer{has_fast_buffer_sub_data ? std::nullopt : std::make_optional<StreamBuffer>()} {
116 GLint gl_max_attributes; 113 GLint gl_max_attributes;
117 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &gl_max_attributes); 114 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &gl_max_attributes);
@@ -123,16 +120,18 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_,
123 GL_STREAM_DRAW); 120 GL_STREAM_DRAW);
124 } 121 }
125 } 122 }
126 for (auto& stage_uniforms : copy_uniforms) { 123 if (use_assembly_shaders) {
127 for (OGLBuffer& buffer : stage_uniforms) { 124 for (auto& stage_uniforms : copy_uniforms) {
125 for (OGLBuffer& buffer : stage_uniforms) {
126 buffer.Create();
127 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
128 }
129 }
130 for (OGLBuffer& buffer : copy_compute_uniforms) {
128 buffer.Create(); 131 buffer.Create();
129 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY); 132 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
130 } 133 }
131 } 134 }
132 for (OGLBuffer& buffer : copy_compute_uniforms) {
133 buffer.Create();
134 glNamedBufferData(buffer.handle, 0x10'000, nullptr, GL_STREAM_COPY);
135 }
136 135
137 device_access_memory = [this]() -> u64 { 136 device_access_memory = [this]() -> u64 {
138 if (device.CanReportMemoryUsage()) { 137 if (device.CanReportMemoryUsage()) {
@@ -146,8 +145,12 @@ StagingBufferMap BufferCacheRuntime::UploadStagingBuffer(size_t size) {
146 return staging_buffer_pool.RequestUploadBuffer(size); 145 return staging_buffer_pool.RequestUploadBuffer(size);
147} 146}
148 147
149StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size) { 148StagingBufferMap BufferCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
150 return staging_buffer_pool.RequestDownloadBuffer(size); 149 return staging_buffer_pool.RequestDownloadBuffer(size, deferred);
150}
151
152void BufferCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
153 staging_buffer_pool.FreeDeferredStagingBuffer(buffer);
151} 154}
152 155
153u64 BufferCacheRuntime::GetDeviceMemoryUsage() const { 156u64 BufferCacheRuntime::GetDeviceMemoryUsage() const {
@@ -207,14 +210,8 @@ void BufferCacheRuntime::ClearBuffer(Buffer& dest_buffer, u32 offset, size_t siz
207} 210}
208 211
209void BufferCacheRuntime::BindIndexBuffer(Buffer& buffer, u32 offset, u32 size) { 212void BufferCacheRuntime::BindIndexBuffer(Buffer& buffer, u32 offset, u32 size) {
210 if (has_unified_vertex_buffers) { 213 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.Handle());
211 buffer.MakeResident(GL_READ_ONLY); 214 index_buffer_offset = offset;
212 glBufferAddressRangeNV(GL_ELEMENT_ARRAY_ADDRESS_NV, 0, buffer.HostGpuAddr() + offset,
213 static_cast<GLsizeiptr>(Common::AlignUp(size, 4)));
214 } else {
215 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer.Handle());
216 index_buffer_offset = offset;
217 }
218} 215}
219 216
220void BufferCacheRuntime::BindVertexBuffer(u32 index, Buffer& buffer, u32 offset, u32 size, 217void BufferCacheRuntime::BindVertexBuffer(u32 index, Buffer& buffer, u32 offset, u32 size,
@@ -222,24 +219,23 @@ void BufferCacheRuntime::BindVertexBuffer(u32 index, Buffer& buffer, u32 offset,
222 if (index >= max_attributes) { 219 if (index >= max_attributes) {
223 return; 220 return;
224 } 221 }
225 if (has_unified_vertex_buffers) { 222 glBindVertexBuffer(index, buffer.Handle(), static_cast<GLintptr>(offset),
226 buffer.MakeResident(GL_READ_ONLY); 223 static_cast<GLsizei>(stride));
227 glBindVertexBuffer(index, 0, 0, static_cast<GLsizei>(stride));
228 glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, index,
229 buffer.HostGpuAddr() + offset, static_cast<GLsizeiptr>(size));
230 } else {
231 glBindVertexBuffer(index, buffer.Handle(), static_cast<GLintptr>(offset),
232 static_cast<GLsizei>(stride));
233 }
234} 224}
235 225
236void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bindings) { 226void BufferCacheRuntime::BindVertexBuffers(VideoCommon::HostBindings<Buffer>& bindings) {
237 for (u32 index = 0; index < bindings.buffers.size(); ++index) { 227 // TODO: Should HostBindings provide the correct runtime types to avoid these transforms?
238 BindVertexBuffer(bindings.min_index + index, *bindings.buffers[index], 228 std::array<GLuint, 32> buffer_handles;
239 static_cast<u32>(bindings.offsets[index]), 229 std::array<GLsizei, 32> buffer_strides;
240 static_cast<u32>(bindings.sizes[index]), 230 std::ranges::transform(bindings.buffers, buffer_handles.begin(),
241 static_cast<u32>(bindings.strides[index])); 231 [](const Buffer* const buffer) { return buffer->Handle(); });
242 } 232 std::ranges::transform(bindings.strides, buffer_strides.begin(),
233 [](u64 stride) { return static_cast<GLsizei>(stride); });
234 const u32 count =
235 std::min(static_cast<u32>(bindings.buffers.size()), max_attributes - bindings.min_index);
236 glBindVertexBuffers(bindings.min_index, static_cast<GLsizei>(count), buffer_handles.data(),
237 reinterpret_cast<const GLintptr*>(bindings.offsets.data()),
238 buffer_strides.data());
243} 239}
244 240
245void BufferCacheRuntime::BindUniformBuffer(size_t stage, u32 binding_index, Buffer& buffer, 241void BufferCacheRuntime::BindUniformBuffer(size_t stage, u32 binding_index, Buffer& buffer,
@@ -331,11 +327,13 @@ void BufferCacheRuntime::BindTransformFeedbackBuffer(u32 index, Buffer& buffer,
331} 327}
332 328
333void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<Buffer>& bindings) { 329void BufferCacheRuntime::BindTransformFeedbackBuffers(VideoCommon::HostBindings<Buffer>& bindings) {
334 for (u32 index = 0; index < bindings.buffers.size(); ++index) { 330 std::array<GLuint, 4> buffer_handles;
335 glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, index, bindings.buffers[index]->Handle(), 331 std::ranges::transform(bindings.buffers, buffer_handles.begin(),
336 static_cast<GLintptr>(bindings.offsets[index]), 332 [](const Buffer* const buffer) { return buffer->Handle(); });
337 static_cast<GLsizeiptr>(bindings.sizes[index])); 333 glBindBuffersRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
338 } 334 static_cast<GLsizei>(bindings.buffers.size()), buffer_handles.data(),
335 reinterpret_cast<const GLintptr*>(bindings.offsets.data()),
336 reinterpret_cast<const GLsizeiptr*>(bindings.strides.data()));
339} 337}
340 338
341void BufferCacheRuntime::BindTextureBuffer(Buffer& buffer, u32 offset, u32 size, 339void BufferCacheRuntime::BindTextureBuffer(Buffer& buffer, u32 offset, u32 size,
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index 000f29a82..71cd45d35 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -66,7 +66,9 @@ public:
66 66
67 [[nodiscard]] StagingBufferMap UploadStagingBuffer(size_t size); 67 [[nodiscard]] StagingBufferMap UploadStagingBuffer(size_t size);
68 68
69 [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size); 69 [[nodiscard]] StagingBufferMap DownloadStagingBuffer(size_t size, bool deferred = false);
70
71 void FreeDeferredStagingBuffer(StagingBufferMap& buffer);
70 72
71 bool CanReorderUpload(const Buffer&, std::span<const VideoCommon::BufferCopy>) { 73 bool CanReorderUpload(const Buffer&, std::span<const VideoCommon::BufferCopy>) {
72 return false; 74 return false;
@@ -207,7 +209,6 @@ private:
207 209
208 bool has_fast_buffer_sub_data = false; 210 bool has_fast_buffer_sub_data = false;
209 bool use_assembly_shaders = false; 211 bool use_assembly_shaders = false;
210 bool has_unified_vertex_buffers = false;
211 212
212 bool use_storage_buffers = false; 213 bool use_storage_buffers = false;
213 214
@@ -246,7 +247,7 @@ struct BufferCacheParams {
246 static constexpr bool NEEDS_BIND_STORAGE_INDEX = true; 247 static constexpr bool NEEDS_BIND_STORAGE_INDEX = true;
247 static constexpr bool USE_MEMORY_MAPS = true; 248 static constexpr bool USE_MEMORY_MAPS = true;
248 static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true; 249 static constexpr bool SEPARATE_IMAGE_BUFFER_BINDINGS = true;
249 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false; 250 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true;
250 251
251 // TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads 252 // TODO: Investigate why OpenGL seems to perform worse with persistently mapped buffer uploads
252 static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false; 253 static constexpr bool USE_MEMORY_MAPS_FOR_UPLOADS = false;
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 993438a27..a6c93068f 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -200,7 +200,6 @@ Device::Device(Core::Frontend::EmuWindow& emu_window) {
200 has_broken_texture_view_formats = is_amd || (!is_linux && is_intel); 200 has_broken_texture_view_formats = is_amd || (!is_linux && is_intel);
201 has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2; 201 has_nv_viewport_array2 = GLAD_GL_NV_viewport_array2;
202 has_derivative_control = GLAD_GL_ARB_derivative_control; 202 has_derivative_control = GLAD_GL_ARB_derivative_control;
203 has_vertex_buffer_unified_memory = GLAD_GL_NV_vertex_buffer_unified_memory;
204 has_debugging_tool_attached = IsDebugToolAttached(extensions); 203 has_debugging_tool_attached = IsDebugToolAttached(extensions);
205 has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float"); 204 has_depth_buffer_float = HasExtension(extensions, "GL_NV_depth_buffer_float");
206 has_geometry_shader_passthrough = GLAD_GL_NV_geometry_shader_passthrough; 205 has_geometry_shader_passthrough = GLAD_GL_NV_geometry_shader_passthrough;
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index a5a6bbbba..96034ea4a 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -72,10 +72,6 @@ public:
72 return has_texture_shadow_lod; 72 return has_texture_shadow_lod;
73 } 73 }
74 74
75 bool HasVertexBufferUnifiedMemory() const {
76 return has_vertex_buffer_unified_memory;
77 }
78
79 bool HasASTC() const { 75 bool HasASTC() const {
80 return has_astc; 76 return has_astc;
81 } 77 }
@@ -215,7 +211,6 @@ private:
215 bool has_vertex_viewport_layer{}; 211 bool has_vertex_viewport_layer{};
216 bool has_image_load_formatted{}; 212 bool has_image_load_formatted{};
217 bool has_texture_shadow_lod{}; 213 bool has_texture_shadow_lod{};
218 bool has_vertex_buffer_unified_memory{};
219 bool has_astc{}; 214 bool has_astc{};
220 bool has_variable_aoffi{}; 215 bool has_variable_aoffi{};
221 bool has_component_indexing_bug{}; 216 bool has_component_indexing_bug{};
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
index bbb06e51f..cadad6507 100644
--- a/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.cpp
@@ -28,63 +28,69 @@ StagingBuffers::StagingBuffers(GLenum storage_flags_, GLenum map_flags_)
28 28
29StagingBuffers::~StagingBuffers() = default; 29StagingBuffers::~StagingBuffers() = default;
30 30
31StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence) { 31StagingBufferMap StagingBuffers::RequestMap(size_t requested_size, bool insert_fence,
32 bool deferred) {
32 MICROPROFILE_SCOPE(OpenGL_BufferRequest); 33 MICROPROFILE_SCOPE(OpenGL_BufferRequest);
33 34
34 const size_t index = RequestBuffer(requested_size); 35 const size_t index = RequestBuffer(requested_size);
35 OGLSync* const sync = insert_fence ? &syncs[index] : nullptr; 36 OGLSync* const sync = insert_fence ? &allocs[index].sync : nullptr;
36 sync_indices[index] = insert_fence ? ++current_sync_index : 0; 37 allocs[index].sync_index = insert_fence ? ++current_sync_index : 0;
38 allocs[index].deferred = deferred;
37 return StagingBufferMap{ 39 return StagingBufferMap{
38 .mapped_span = std::span(maps[index], requested_size), 40 .mapped_span = std::span(allocs[index].map, requested_size),
39 .sync = sync, 41 .sync = sync,
40 .buffer = buffers[index].handle, 42 .buffer = allocs[index].buffer.handle,
43 .index = index,
41 }; 44 };
42} 45}
43 46
47void StagingBuffers::FreeDeferredStagingBuffer(size_t index) {
48 ASSERT(allocs[index].deferred);
49 allocs[index].deferred = false;
50}
51
44size_t StagingBuffers::RequestBuffer(size_t requested_size) { 52size_t StagingBuffers::RequestBuffer(size_t requested_size) {
45 if (const std::optional<size_t> index = FindBuffer(requested_size); index) { 53 if (const std::optional<size_t> index = FindBuffer(requested_size); index) {
46 return *index; 54 return *index;
47 } 55 }
48 56 StagingBufferAlloc alloc;
49 OGLBuffer& buffer = buffers.emplace_back(); 57 alloc.buffer.Create();
50 buffer.Create();
51 const auto next_pow2_size = Common::NextPow2(requested_size); 58 const auto next_pow2_size = Common::NextPow2(requested_size);
52 glNamedBufferStorage(buffer.handle, next_pow2_size, nullptr, 59 glNamedBufferStorage(alloc.buffer.handle, next_pow2_size, nullptr,
53 storage_flags | GL_MAP_PERSISTENT_BIT); 60 storage_flags | GL_MAP_PERSISTENT_BIT);
54 maps.push_back(static_cast<u8*>(glMapNamedBufferRange(buffer.handle, 0, next_pow2_size, 61 alloc.map = static_cast<u8*>(glMapNamedBufferRange(alloc.buffer.handle, 0, next_pow2_size,
55 map_flags | GL_MAP_PERSISTENT_BIT))); 62 map_flags | GL_MAP_PERSISTENT_BIT));
56 syncs.emplace_back(); 63 alloc.size = next_pow2_size;
57 sync_indices.emplace_back(); 64 allocs.emplace_back(std::move(alloc));
58 sizes.push_back(next_pow2_size); 65 return allocs.size() - 1;
59
60 ASSERT(syncs.size() == buffers.size() && buffers.size() == maps.size() &&
61 maps.size() == sizes.size());
62
63 return buffers.size() - 1;
64} 66}
65 67
66std::optional<size_t> StagingBuffers::FindBuffer(size_t requested_size) { 68std::optional<size_t> StagingBuffers::FindBuffer(size_t requested_size) {
67 size_t known_unsignaled_index = current_sync_index + 1; 69 size_t known_unsignaled_index = current_sync_index + 1;
68 size_t smallest_buffer = std::numeric_limits<size_t>::max(); 70 size_t smallest_buffer = std::numeric_limits<size_t>::max();
69 std::optional<size_t> found; 71 std::optional<size_t> found;
70 const size_t num_buffers = sizes.size(); 72 const size_t num_buffers = allocs.size();
71 for (size_t index = 0; index < num_buffers; ++index) { 73 for (size_t index = 0; index < num_buffers; ++index) {
72 const size_t buffer_size = sizes[index]; 74 StagingBufferAlloc& alloc = allocs[index];
75 const size_t buffer_size = alloc.size;
73 if (buffer_size < requested_size || buffer_size >= smallest_buffer) { 76 if (buffer_size < requested_size || buffer_size >= smallest_buffer) {
74 continue; 77 continue;
75 } 78 }
76 if (syncs[index].handle != 0) { 79 if (alloc.deferred) {
77 if (sync_indices[index] >= known_unsignaled_index) { 80 continue;
81 }
82 if (alloc.sync.handle != 0) {
83 if (alloc.sync_index >= known_unsignaled_index) {
78 // This fence is later than a fence that is known to not be signaled 84 // This fence is later than a fence that is known to not be signaled
79 continue; 85 continue;
80 } 86 }
81 if (!syncs[index].IsSignaled()) { 87 if (!alloc.sync.IsSignaled()) {
82 // Since this fence hasn't been signaled, it's safe to assume all later 88 // Since this fence hasn't been signaled, it's safe to assume all later
83 // fences haven't been signaled either 89 // fences haven't been signaled either
84 known_unsignaled_index = std::min(known_unsignaled_index, sync_indices[index]); 90 known_unsignaled_index = std::min(known_unsignaled_index, alloc.sync_index);
85 continue; 91 continue;
86 } 92 }
87 syncs[index].Release(); 93 alloc.sync.Release();
88 } 94 }
89 smallest_buffer = buffer_size; 95 smallest_buffer = buffer_size;
90 found = index; 96 found = index;
@@ -143,8 +149,12 @@ StagingBufferMap StagingBufferPool::RequestUploadBuffer(size_t size) {
143 return upload_buffers.RequestMap(size, true); 149 return upload_buffers.RequestMap(size, true);
144} 150}
145 151
146StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size) { 152StagingBufferMap StagingBufferPool::RequestDownloadBuffer(size_t size, bool deferred) {
147 return download_buffers.RequestMap(size, false); 153 return download_buffers.RequestMap(size, false, deferred);
154}
155
156void StagingBufferPool::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
157 download_buffers.FreeDeferredStagingBuffer(buffer.index);
148} 158}
149 159
150} // namespace OpenGL 160} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_staging_buffer_pool.h b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
index 60f72d3a0..07a56b4d2 100644
--- a/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
+++ b/src/video_core/renderer_opengl/gl_staging_buffer_pool.h
@@ -26,23 +26,30 @@ struct StagingBufferMap {
26 size_t offset = 0; 26 size_t offset = 0;
27 OGLSync* sync; 27 OGLSync* sync;
28 GLuint buffer; 28 GLuint buffer;
29 size_t index;
29}; 30};
30 31
31struct StagingBuffers { 32struct StagingBuffers {
32 explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_); 33 explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
33 ~StagingBuffers(); 34 ~StagingBuffers();
34 35
35 StagingBufferMap RequestMap(size_t requested_size, bool insert_fence); 36 StagingBufferMap RequestMap(size_t requested_size, bool insert_fence, bool deferred = false);
37
38 void FreeDeferredStagingBuffer(size_t index);
36 39
37 size_t RequestBuffer(size_t requested_size); 40 size_t RequestBuffer(size_t requested_size);
38 41
39 std::optional<size_t> FindBuffer(size_t requested_size); 42 std::optional<size_t> FindBuffer(size_t requested_size);
40 43
41 std::vector<OGLSync> syncs; 44 struct StagingBufferAlloc {
42 std::vector<OGLBuffer> buffers; 45 OGLSync sync;
43 std::vector<u8*> maps; 46 OGLBuffer buffer;
44 std::vector<size_t> sizes; 47 u8* map;
45 std::vector<size_t> sync_indices; 48 size_t size;
49 size_t sync_index;
50 bool deferred;
51 };
52 std::vector<StagingBufferAlloc> allocs;
46 GLenum storage_flags; 53 GLenum storage_flags;
47 GLenum map_flags; 54 GLenum map_flags;
48 size_t current_sync_index = 0; 55 size_t current_sync_index = 0;
@@ -85,7 +92,8 @@ public:
85 ~StagingBufferPool() = default; 92 ~StagingBufferPool() = default;
86 93
87 StagingBufferMap RequestUploadBuffer(size_t size); 94 StagingBufferMap RequestUploadBuffer(size_t size);
88 StagingBufferMap RequestDownloadBuffer(size_t size); 95 StagingBufferMap RequestDownloadBuffer(size_t size, bool deferred = false);
96 void FreeDeferredStagingBuffer(StagingBufferMap& buffer);
89 97
90private: 98private:
91 StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT}; 99 StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT};
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index 512eef575..66a5ca03e 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -557,8 +557,12 @@ StagingBufferMap TextureCacheRuntime::UploadStagingBuffer(size_t size) {
557 return staging_buffer_pool.RequestUploadBuffer(size); 557 return staging_buffer_pool.RequestUploadBuffer(size);
558} 558}
559 559
560StagingBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size) { 560StagingBufferMap TextureCacheRuntime::DownloadStagingBuffer(size_t size, bool deferred) {
561 return staging_buffer_pool.RequestDownloadBuffer(size); 561 return staging_buffer_pool.RequestDownloadBuffer(size, deferred);
562}
563
564void TextureCacheRuntime::FreeDeferredStagingBuffer(StagingBufferMap& buffer) {
565 staging_buffer_pool.FreeDeferredStagingBuffer(buffer);
562} 566}
563 567
564u64 TextureCacheRuntime::GetDeviceMemoryUsage() const { 568u64 TextureCacheRuntime::GetDeviceMemoryUsage() const {
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index e71b87e99..34870c81f 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -74,7 +74,9 @@ public:
74 74
75 StagingBufferMap UploadStagingBuffer(size_t size); 75 StagingBufferMap UploadStagingBuffer(size_t size);
76 76
77 StagingBufferMap DownloadStagingBuffer(size_t size); 77 StagingBufferMap DownloadStagingBuffer(size_t size, bool deferred = false);
78
79 void FreeDeferredStagingBuffer(StagingBufferMap& buffer);
78 80
79 u64 GetDeviceLocalMemory() const { 81 u64 GetDeviceLocalMemory() const {
80 return device_access_memory; 82 return device_access_memory;
@@ -359,7 +361,7 @@ struct TextureCacheParams {
359 static constexpr bool FRAMEBUFFER_BLITS = true; 361 static constexpr bool FRAMEBUFFER_BLITS = true;
360 static constexpr bool HAS_EMULATED_COPIES = true; 362 static constexpr bool HAS_EMULATED_COPIES = true;
361 static constexpr bool HAS_DEVICE_MEMORY_INFO = true; 363 static constexpr bool HAS_DEVICE_MEMORY_INFO = true;
362 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = false; 364 static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true;
363 365
364 using Runtime = OpenGL::TextureCacheRuntime; 366 using Runtime = OpenGL::TextureCacheRuntime;
365 using Image = OpenGL::Image; 367 using Image = OpenGL::Image;
@@ -367,7 +369,7 @@ struct TextureCacheParams {
367 using ImageView = OpenGL::ImageView; 369 using ImageView = OpenGL::ImageView;
368 using Sampler = OpenGL::Sampler; 370 using Sampler = OpenGL::Sampler;
369 using Framebuffer = OpenGL::Framebuffer; 371 using Framebuffer = OpenGL::Framebuffer;
370 using AsyncBuffer = u32; 372 using AsyncBuffer = OpenGL::StagingBufferMap;
371 using BufferType = GLuint; 373 using BufferType = GLuint;
372}; 374};
373 375
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 6b8d4e554..6bfed08a1 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -168,15 +168,6 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
168 if (!GLAD_GL_ARB_seamless_cubemap_per_texture && !GLAD_GL_AMD_seamless_cubemap_per_texture) { 168 if (!GLAD_GL_ARB_seamless_cubemap_per_texture && !GLAD_GL_AMD_seamless_cubemap_per_texture) {
169 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); 169 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
170 } 170 }
171 // Enable unified vertex attributes and query vertex buffer address when the driver supports it
172 if (device.HasVertexBufferUnifiedMemory()) {
173 glEnableClientState(GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV);
174 glEnableClientState(GL_ELEMENT_ARRAY_UNIFIED_NV);
175
176 glMakeNamedBufferResidentNV(vertex_buffer.handle, GL_READ_ONLY);
177 glGetNamedBufferParameterui64vNV(vertex_buffer.handle, GL_BUFFER_GPU_ADDRESS_NV,
178 &vertex_buffer_address);
179 }
180} 171}
181 172
182RendererOpenGL::~RendererOpenGL() = default; 173RendererOpenGL::~RendererOpenGL() = default;
@@ -680,13 +671,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
680 offsetof(ScreenRectVertex, tex_coord)); 671 offsetof(ScreenRectVertex, tex_coord));
681 glVertexAttribBinding(PositionLocation, 0); 672 glVertexAttribBinding(PositionLocation, 0);
682 glVertexAttribBinding(TexCoordLocation, 0); 673 glVertexAttribBinding(TexCoordLocation, 0);
683 if (device.HasVertexBufferUnifiedMemory()) { 674 glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
684 glBindVertexBuffer(0, 0, 0, sizeof(ScreenRectVertex));
685 glBufferAddressRangeNV(GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV, 0, vertex_buffer_address,
686 sizeof(vertices));
687 } else {
688 glBindVertexBuffer(0, vertex_buffer.handle, 0, sizeof(ScreenRectVertex));
689 }
690 675
691 if (Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::NearestNeighbor) { 676 if (Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::NearestNeighbor) {
692 glBindSampler(0, present_sampler.handle); 677 glBindSampler(0, present_sampler.handle);
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 66483a900..5e461fbd0 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -1211,7 +1211,7 @@ void BlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer) {
1211 aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass); 1211 aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass);
1212 return; 1212 return;
1213 } 1213 }
1214 aa_renderpass = CreateRenderPassImpl(GetFormat(framebuffer)); 1214 aa_renderpass = CreateRenderPassImpl(VK_FORMAT_R16G16B16A16_SFLOAT);
1215 aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass); 1215 aa_framebuffer = CreateFramebuffer(*aa_image_view, size, aa_renderpass);
1216 1216
1217 const std::array<VkPipelineShaderStageCreateInfo, 2> fxaa_shader_stages{{ 1217 const std::array<VkPipelineShaderStageCreateInfo, 2> fxaa_shader_stages{{
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 5dbec2e62..38b1619df 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -1439,7 +1439,7 @@ void Image::UploadMemory(const StagingBufferRef& map, std::span<const BufferImag
1439 UploadMemory(map.buffer, map.offset, copies); 1439 UploadMemory(map.buffer, map.offset, copies);
1440} 1440}
1441 1441
1442void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset, 1442void Image::DownloadMemory(VkBuffer buffer, size_t offset,
1443 std::span<const VideoCommon::BufferImageCopy> copies) { 1443 std::span<const VideoCommon::BufferImageCopy> copies) {
1444 std::array buffer_handles{ 1444 std::array buffer_handles{
1445 buffer, 1445 buffer,
@@ -1450,7 +1450,7 @@ void Image::DownloadMemory(VkBuffer buffer, VkDeviceSize offset,
1450 DownloadMemory(buffer_handles, buffer_offsets, copies); 1450 DownloadMemory(buffer_handles, buffer_offsets, copies);
1451} 1451}
1452 1452
1453void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<VkDeviceSize> offsets_span, 1453void Image::DownloadMemory(std::span<VkBuffer> buffers_span, std::span<size_t> offsets_span,
1454 std::span<const VideoCommon::BufferImageCopy> copies) { 1454 std::span<const VideoCommon::BufferImageCopy> copies) {
1455 const bool is_rescaled = True(flags & ImageFlagBits::Rescaled); 1455 const bool is_rescaled = True(flags & ImageFlagBits::Rescaled);
1456 if (is_rescaled) { 1456 if (is_rescaled) {
@@ -1530,7 +1530,7 @@ void Image::DownloadMemory(const StagingBufferRef& map, std::span<const BufferIm
1530 map.buffer, 1530 map.buffer,
1531 }; 1531 };
1532 std::array offsets{ 1532 std::array offsets{
1533 map.offset, 1533 static_cast<size_t>(map.offset),
1534 }; 1534 };
1535 DownloadMemory(buffers, offsets, copies); 1535 DownloadMemory(buffers, offsets, copies);
1536} 1536}
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.h b/src/video_core/renderer_vulkan/vk_texture_cache.h
index edf5d7635..0dbde65d6 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.h
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.h
@@ -147,10 +147,10 @@ public:
147 void UploadMemory(const StagingBufferRef& map, 147 void UploadMemory(const StagingBufferRef& map,
148 std::span<const VideoCommon::BufferImageCopy> copies); 148 std::span<const VideoCommon::BufferImageCopy> copies);
149 149
150 void DownloadMemory(VkBuffer buffer, VkDeviceSize offset, 150 void DownloadMemory(VkBuffer buffer, size_t offset,
151 std::span<const VideoCommon::BufferImageCopy> copies); 151 std::span<const VideoCommon::BufferImageCopy> copies);
152 152
153 void DownloadMemory(std::span<VkBuffer> buffers, std::span<VkDeviceSize> offsets, 153 void DownloadMemory(std::span<VkBuffer> buffers, std::span<size_t> offsets,
154 std::span<const VideoCommon::BufferImageCopy> copies); 154 std::span<const VideoCommon::BufferImageCopy> copies);
155 155
156 void DownloadMemory(const StagingBufferRef& map, 156 void DownloadMemory(const StagingBufferRef& map,
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index d575c57ca..dade38b18 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -995,7 +995,7 @@ void TextureCache<P>::DownloadImageIntoBuffer(typename TextureCache<P>::Image* i
995 buffer, 995 buffer,
996 download_map.buffer, 996 download_map.buffer,
997 }; 997 };
998 std::array<u64, 2> buffer_offsets{ 998 std::array<size_t, 2> buffer_offsets{
999 buffer_offset, 999 buffer_offset,
1000 download_map.offset, 1000 download_map.offset,
1001 }; 1001 };
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index f3ad2214b..90278052a 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -386,7 +386,7 @@ if (NOT WIN32)
386 target_include_directories(yuzu PRIVATE ${Qt${QT_MAJOR_VERSION}Gui_PRIVATE_INCLUDE_DIRS}) 386 target_include_directories(yuzu PRIVATE ${Qt${QT_MAJOR_VERSION}Gui_PRIVATE_INCLUDE_DIRS})
387endif() 387endif()
388if (UNIX AND NOT APPLE) 388if (UNIX AND NOT APPLE)
389 target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::DBus gamemode) 389 target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::DBus)
390endif() 390endif()
391 391
392target_compile_definitions(yuzu PRIVATE 392target_compile_definitions(yuzu PRIVATE
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 10c788290..b056c3717 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -2713,11 +2713,6 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
2713 } 2713 }
2714 2714
2715 const auto base_romfs = base_nca->GetRomFS(); 2715 const auto base_romfs = base_nca->GetRomFS();
2716 if (!base_romfs) {
2717 failed();
2718 return;
2719 }
2720
2721 const auto dump_dir = 2716 const auto dump_dir =
2722 target == DumpRomFSTarget::Normal 2717 target == DumpRomFSTarget::Normal
2723 ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir) 2718 ? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)