From b4b41ee62c0f18c929b7b9926e5f0597c2c45783 Mon Sep 17 00:00:00 2001 From: MaranBr Date: Sat, 27 Jun 2026 08:38:04 +0200 Subject: [PATCH] [buffer_cache] Add option to control GPU buffer readback (#4126) Added an option to control the GPU buffer readback, as it causes issues if the hardware cannot keep up with the additional workload. Some games require this to render certain effects properly. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4126 --- src/common/settings.h | 7 +++++++ src/qt_common/config/shared_translation.cpp | 2 ++ src/video_core/buffer_cache/buffer_cache.h | 18 ++++++++++-------- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/common/settings.h b/src/common/settings.h index 61979d836e..b80d6a5ec7 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -573,6 +573,13 @@ struct Values { false, #endif "rescale_hack", Category::RendererHacks}; + SwitchableSetting enable_gpu_buffer_readback{linkage, + false, + "enable_gpu_buffer_readback", + Category::RendererAdvanced, + Specialization::Default, + true, + true}; SwitchableSetting use_asynchronous_shaders{linkage, false, "use_asynchronous_shaders", Category::RendererHacks}; diff --git a/src/qt_common/config/shared_translation.cpp b/src/qt_common/config/shared_translation.cpp index 6778f37f7b..72241bab51 100644 --- a/src/qt_common/config/shared_translation.cpp +++ b/src/qt_common/config/shared_translation.cpp @@ -229,6 +229,8 @@ std::unique_ptr InitializeTranslations(QObject* parent) { INSERT(Settings, dma_accuracy, tr("DMA Accuracy:"), tr("Controls the DMA precision accuracy. Safe precision fixes issues in some games but " "may degrade performance.")); + INSERT(Settings, enable_gpu_buffer_readback, tr("Enable GPU buffer readback"), + tr("Preserves GPU-modified buffer data by reading it back before uploads.\nSome games require this to render certain effects properly.\nMay cause issues if the hardware cannot handle the additional workload.")); INSERT(Settings, use_asynchronous_shaders, tr("Enable asynchronous shader compilation"), tr("May reduce shader stutter.")); INSERT(Settings, fast_gpu_time, tr("Fast GPU Time"), diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 3494895f66..740d99558e 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1634,15 +1634,17 @@ bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si if (total_size_bytes == 0) { return true; } - u64 min_offset = (std::numeric_limits::max)(); - u64 max_offset = 0; - for (const auto& copy : upload_copies) { - min_offset = (std::min)(min_offset, copy.dst_offset); - max_offset = (std::max)(max_offset, copy.dst_offset + copy.size); + if (Settings::values.enable_gpu_buffer_readback.GetValue()) { + u64 min_offset = (std::numeric_limits::max)(); + u64 max_offset = 0; + for (const auto& copy : upload_copies) { + min_offset = (std::min)(min_offset, copy.dst_offset); + max_offset = (std::max)(max_offset, copy.dst_offset + copy.size); + } + const DAddr sync_addr = buffer.CpuAddr() + min_offset; + const u64 sync_size = max_offset - min_offset; + DownloadBufferMemory(buffer, sync_addr, sync_size); } - const DAddr sync_addr = buffer.CpuAddr() + min_offset; - const u64 sync_size = max_offset - min_offset; - DownloadBufferMemory(buffer, sync_addr, sync_size); const std::span copies_span(upload_copies.data(), upload_copies.size()); UploadMemory(buffer, total_size_bytes, largest_copy, copies_span); any_buffer_uploaded = true;