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 ::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 ::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;
}