diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 31e887e819..fd76eddf7b 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -1617,6 +1617,32 @@ void BufferCache

::TouchBuffer(Buffer& buffer, BufferId buffer_id) noexcept { } template +bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size) { + upload_copies.clear(); + u64 total_size_bytes = 0; + u64 largest_copy = 0; + DAddr buffer_start = buffer.cpu_addr_cached; + memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 device_addr_out, u64 range_size) { + if (IsRegionGpuModified(device_addr_out, range_size)) { + return; + } + upload_copies.push_back(BufferCopy{ + .src_offset = total_size_bytes, + .dst_offset = device_addr_out - buffer_start, + .size = range_size, + }); + total_size_bytes += range_size; + largest_copy = (std::max)(largest_copy, range_size); + }); + if (total_size_bytes == 0) { + return true; + } + std::span copies_span(upload_copies.data(), upload_copies.size()); + UploadMemory(buffer, total_size_bytes, largest_copy, copies_span); + any_buffer_uploaded = true; + return false; +} + bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 size) { upload_copies.clear(); u64 staging_offset = 0; @@ -1624,10 +1650,10 @@ bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si DAddr buffer_start = buffer.CpuAddr(); auto push = [&](u64 start, u64 end) { if (start >= end) { - return; - } + return; + } u64 sz = end - start; - copies.push_back({ + upload_copies.push_back({ .src_offset = staging_offset, .dst_offset = start - buffer_start, .size = sz @@ -1636,21 +1662,21 @@ bool BufferCache

::SynchronizeBuffer(Buffer& buffer, DAddr device_addr, u32 si largest_copy = std::max(largest_copy, sz); }; memory_tracker.ForEachUploadRange(device_addr, size, [&](u64 addr, u64 range_size) { - u64 start = addr; - u64 end = addr + range_size; - gpu_modified_ranges.ForEachInRange(start, range_size, [&](u64 gstart, u64 gsize) { - u64 gend = gstart + gsize; - push(start, gstart); - start = std::max(start, gend); - }); - push(start, end); - ClearDownload(addr, range_size); - gpu_modified_ranges.Subtract(addr, range_size); + u64 start = addr; + u64 end = addr + range_size; + gpu_modified_ranges.ForEachInRange(start, range_size, [&](u64 gstart, u64 gsize) { + u64 gend = gstart + gsize; + push(start, gstart); + start = std::max(start, gend); + }); + push(start, end); + ClearDownload(addr, range_size); + gpu_modified_ranges.Subtract(addr, range_size); }); - if (copies.empty()) { - return true; - } - UploadMemory(buffer, staging_offset, largest_copy, std::span(copies)); + if (upload_copies.empty()) { + return true; + } + UploadMemory(buffer, staging_offset, largest_copy, std::span(upload_copies)); return false; }