diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index e331bac70f..e5706109bb 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -207,12 +207,22 @@ bool BufferCache

::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am std::optional src_window; std::optional dst_window; if constexpr (USE_UNIFIED_DIRECT_BINDING) { - src_window = TryObtainWindowBuffer(*cpu_src_address, static_cast(amount), - UNIFIED_COPY_BINDING_ALIGNMENT, - ObtainBufferOperation::DoNothing); - dst_window = TryObtainWindowBuffer(*cpu_dest_address, static_cast(amount), - UNIFIED_COPY_BINDING_ALIGNMENT, - ObtainBufferOperation::DoNothing); + if (amount <= (std::numeric_limits::max)()) { + src_window = TryObtainWindowBuffer(*cpu_src_address, static_cast(amount), + UNIFIED_COPY_BINDING_ALIGNMENT, + ObtainBufferOperation::DoNothing); + dst_window = TryObtainWindowBuffer(*cpu_dest_address, static_cast(amount), + UNIFIED_COPY_BINDING_ALIGNMENT, + ObtainBufferOperation::DoNothing); + if (src_window && dst_window && + src_window->window_index == dst_window->window_index) { + const u64 src_begin = src_window->offset; + const u64 dst_begin = dst_window->offset; + if (src_begin < dst_begin + amount && dst_begin < src_begin + amount) { + dst_window.reset(); + } + } + } } ClearDownload(*cpu_dest_address, amount); @@ -364,11 +374,10 @@ void BufferCache

::MarkGpuWrittenRange(DAddr device_addr, u32 size) { if (size == 0) { return; } - const BufferId buffer_id = FindBuffer(device_addr, size); - if (buffer_id == NULL_BUFFER_ID) { - return; - } - MarkWrittenBuffer(buffer_id, device_addr, size); + memory_tracker.MarkRegionAsGpuModified(device_addr, size); + gpu_modified_ranges.Add(device_addr, size); + uncommitted_gpu_modified_ranges.Add(device_addr, size); + in_place_gpu_written_ranges.Subtract(device_addr, size); } template @@ -1868,14 +1877,6 @@ void BufferCache

::ForgetGpuModifiedRange(DAddr device_addr, u64 size) { in_place_gpu_written_ranges.Subtract(device_addr, size); } -template -bool BufferCache

::IsRegionWrittenInPlace(DAddr device_addr, u64 size) { - u64 covered = 0; - in_place_gpu_written_ranges.ForEachInRange( - device_addr, size, [&](DAddr start, DAddr end) { covered += end - start; }); - return covered == size; -} - template bool BufferCache

::IntersectsInPlaceWrites(DAddr device_addr, u64 size) { bool intersects = false; @@ -2212,8 +2213,7 @@ bool BufferCache

::ResolveUnifiedDirectBinding([[maybe_unused]] DAddr device_a } contiguous += Core::DEVICE_PAGESIZE; } - if (IsRegionGpuModified(device_addr, size) && - !IsRegionWrittenInPlace(device_addr, size)) { + if (IsRegionGpuModified(device_addr, size)) { return false; } window_index = relative / window_size; diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h index 90e33b8aa9..8784b76414 100644 --- a/src/video_core/buffer_cache/buffer_cache_base.h +++ b/src/video_core/buffer_cache/buffer_cache_base.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -449,8 +450,6 @@ private: void ForgetGpuModifiedRange(DAddr device_addr, u64 size); - [[nodiscard]] bool IsRegionWrittenInPlace(DAddr device_addr, u64 size); - [[nodiscard]] bool IntersectsInPlaceWrites(DAddr device_addr, u64 size); void WaitForInPlaceWrites();