From e46dd1bd5f18c628a838f17a3f17c067e70d2e63 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Sat, 8 Aug 2026 19:03:46 -0400 Subject: [PATCH] [TEST] Split downloads --- src/video_core/buffer_cache/buffer_cache.h | 44 ++++++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index da86c14500..6ed3daf5f9 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -602,7 +602,13 @@ void BufferCache

::CommitAsyncFlushesHigh() { it++; } - boost::container::small_vector, 16> downloads; + struct QueuedDownload { + BufferCopy copy; + BufferId buffer_id; + bool written_in_place; + }; + + boost::container::small_vector downloads; u64 total_size_bytes = 0; u64 largest_copy = 0; for (const Common::RangeSet& range_set : committed_gpu_modified_ranges) { @@ -618,7 +624,8 @@ void BufferCache

::CommitAsyncFlushesHigh() { new_start, new_end - new_start, false, [&](u64 device_addr_out, u64 range_size) { const DAddr buffer_addr = buffer.CpuAddr(); - const auto add_download = [&](DAddr start, DAddr end) { + const auto add_download = [&](DAddr start, DAddr end, + bool written_in_place) { const u64 new_offset = start - buffer_addr; const u64 new_size = end - start; downloads.push_back({ @@ -628,6 +635,7 @@ void BufferCache

::CommitAsyncFlushesHigh() { .size = new_size, }, buffer_id, + written_in_place, }); // Align up to avoid cache conflicts constexpr u64 align = 64ULL; @@ -635,9 +643,23 @@ void BufferCache

::CommitAsyncFlushesHigh() { total_size_bytes += (new_size + align - 1) & mask; largest_copy = (std::max)(largest_copy, new_size); }; + const auto split_by_in_place = [&](DAddr start, DAddr end) { + DAddr cursor = start; + in_place_gpu_written_ranges.ForEachInRange( + start, end - start, [&](DAddr in_start, DAddr in_end) { + if (cursor < in_start) { + add_download(cursor, in_start, false); + } + add_download(in_start, in_end, true); + cursor = in_end; + }); + if (cursor < end) { + add_download(cursor, end, false); + } + }; gpu_modified_ranges.ForEachInRange(device_addr_out, range_size, - add_download); + split_by_in_place); }); }); }); @@ -661,9 +683,18 @@ void BufferCache

::CommitAsyncFlushesHigh() { boost::container::small_vector window_ids; UnifiedWindowGroups groups; u64 staging_size_bytes = 0; - for (auto& [copy, buffer_id] : downloads) { + bool has_in_place_writes = false; + for (auto& [copy, buffer_id, written_in_place] : downloads) { Buffer& buffer = slot_buffers[buffer_id]; const DAddr orig_device_addr = buffer.CpuAddr() + copy.src_offset; + if (written_in_place) { + BufferCopy record{copy}; + record.src_offset = static_cast(orig_device_addr); + async_downloads.Add(orig_device_addr, copy.size); + batch.unified_copies.push_back(record); + has_in_place_writes = true; + continue; + } bool unified = false; if constexpr (USE_UNIFIED_MEMORY) { if (runtime.HasUnifiedMemory()) { @@ -718,6 +749,11 @@ void BufferCache

::CommitAsyncFlushesHigh() { runtime.UnifiedMemoryHostBarrier(); } } + if constexpr (USE_UNIFIED_DIRECT_BINDING) { + if (has_in_place_writes) { + runtime.UnifiedMemoryShaderWriteBarrier(); + } + } runtime.PostCopyBarrier(); pending_downloads.emplace_back(std::move(batch)); async_buffers.emplace_back(std::move(download_staging));