From e580073430d1857a70c566dffc1378f6f2bdcce1 Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Mon, 23 Jun 2025 01:10:22 +0300 Subject: [PATCH] liverpool: Use pending downloads API for rewind Prevents creating huge buffers --- src/video_core/amdgpu/liverpool.cpp | 8 ++------ src/video_core/buffer_cache/buffer_cache.cpp | 10 +++++++--- src/video_core/buffer_cache/buffer_cache.h | 2 +- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 4 ++-- src/video_core/renderer_vulkan/vk_rasterizer.h | 2 +- src/video_core/renderer_vulkan/vk_scheduler.h | 4 ++-- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index fd38e3fbf..65dad7da8 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -708,9 +708,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span dcb, std::span(header)); - const u32 flush_size = dcb.size_bytes(); - rasterizer->ReadMemory(flush_addr, flush_size); + rasterizer->CommitPendingDownloads(true); } const PM4CmdRewind* rewind = reinterpret_cast(header); while (!rewind->Valid()) { @@ -915,9 +913,7 @@ Liverpool::Task Liverpool::ProcessCompute(const u32* acb, u32 acb_dwords, u32 vq } case PM4ItOpcode::Rewind: { if (rasterizer) { - const VAddr flush_addr = VAddr(reinterpret_cast(header)); - const u32 flush_size = acb_dwords * sizeof(u32); - rasterizer->ReadMemory(flush_addr, flush_size); + rasterizer->CommitPendingDownloads(true); } const PM4CmdRewind* rewind = reinterpret_cast(header); while (!rewind->Valid()) { diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 70bc9c226..54d516e71 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -27,7 +27,7 @@ static constexpr size_t UboStreamBufferSize = 128_MB; static constexpr size_t DownloadBufferSize = 128_MB; static constexpr size_t DeviceBufferSize = 128_MB; static constexpr size_t MaxPageFaults = 1024; -static constexpr size_t DownloadSizeThreshold = 2_MB; +static constexpr size_t DownloadSizeThreshold = 1_MB; BufferCache::BufferCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& scheduler_, AmdGpu::Liverpool* liverpool_, TextureCache& texture_cache_, @@ -188,7 +188,7 @@ void BufferCache::DownloadBufferMemory(const Buffer& buffer, VAddr device_addr, } } -bool BufferCache::CommitPendingDownloads() { +bool BufferCache::CommitPendingDownloads(bool wait_done) { if (pending_download_ranges.Empty()) { return false; } @@ -254,7 +254,11 @@ bool BufferCache::CommitPendingDownloads() { } } }); - scheduler.Flush(); + if (wait_done) { + scheduler.Finish(); + } else { + scheduler.Flush(); + } return true; } diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 8e6253633..48e27ba81 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -128,7 +128,7 @@ public: void CopyBuffer(VAddr dst, VAddr src, u32 num_bytes, bool dst_gds, bool src_gds); /// Schedules pending GPU modified ranges since last commit to be copied back the host memory. - bool CommitPendingDownloads(); + bool CommitPendingDownloads(bool wait_done); /// Obtains a buffer for the specified region. [[nodiscard]] std::pair ObtainBuffer(VAddr gpu_addr, u32 size, bool is_written, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 21b6ee057..b3a2a53ba 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -60,9 +60,9 @@ void Rasterizer::CpSync() { vk::DependencyFlagBits::eByRegion, ib_barrier, {}, {}); } -bool Rasterizer::CommitPendingDownloads() { +bool Rasterizer::CommitPendingDownloads(bool wait_done) { scheduler.PopPendingOperations(); - return buffer_cache.CommitPendingDownloads(); + return buffer_cache.CommitPendingDownloads(wait_done); } bool Rasterizer::FilterDraw() { diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 1ae615b52..dfcb9f775 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -65,7 +65,7 @@ public: void UnmapMemory(VAddr addr, u64 size); void CpSync(); - bool CommitPendingDownloads(); + bool CommitPendingDownloads(bool wait_done = false); u64 Flush(); void Finish(); void ProcessFaults(); diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h index 84c28ac67..c19c326c7 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.h +++ b/src/video_core/renderer_vulkan/vk_scheduler.h @@ -357,8 +357,8 @@ public: } /// Defers an operation until the gpu has reached the current cpu tick. - void DeferOperation(Common::UniqueFunction&& func, bool prev_tick = false) { - pending_ops.emplace(std::move(func), prev_tick ? CurrentTick() - 1 : CurrentTick()); + void DeferOperation(Common::UniqueFunction&& func) { + pending_ops.emplace(std::move(func), CurrentTick()); } static std::mutex submit_mutex;