|
|
|
@ -207,12 +207,22 @@ bool BufferCache<P>::DMACopy(GPUVAddr src_address, GPUVAddr dest_address, u64 am |
|
|
|
std::optional<WindowBufferRef> src_window; |
|
|
|
std::optional<WindowBufferRef> dst_window; |
|
|
|
if constexpr (USE_UNIFIED_DIRECT_BINDING) { |
|
|
|
src_window = TryObtainWindowBuffer(*cpu_src_address, static_cast<u32>(amount), |
|
|
|
UNIFIED_COPY_BINDING_ALIGNMENT, |
|
|
|
ObtainBufferOperation::DoNothing); |
|
|
|
dst_window = TryObtainWindowBuffer(*cpu_dest_address, static_cast<u32>(amount), |
|
|
|
UNIFIED_COPY_BINDING_ALIGNMENT, |
|
|
|
ObtainBufferOperation::DoNothing); |
|
|
|
if (amount <= (std::numeric_limits<u32>::max)()) { |
|
|
|
src_window = TryObtainWindowBuffer(*cpu_src_address, static_cast<u32>(amount), |
|
|
|
UNIFIED_COPY_BINDING_ALIGNMENT, |
|
|
|
ObtainBufferOperation::DoNothing); |
|
|
|
dst_window = TryObtainWindowBuffer(*cpu_dest_address, static_cast<u32>(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<P>::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 <class P> |
|
|
|
@ -1868,14 +1877,6 @@ void BufferCache<P>::ForgetGpuModifiedRange(DAddr device_addr, u64 size) { |
|
|
|
in_place_gpu_written_ranges.Subtract(device_addr, size); |
|
|
|
} |
|
|
|
|
|
|
|
template <class P> |
|
|
|
bool BufferCache<P>::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 <class P> |
|
|
|
bool BufferCache<P>::IntersectsInPlaceWrites(DAddr device_addr, u64 size) { |
|
|
|
bool intersects = false; |
|
|
|
@ -2212,8 +2213,7 @@ bool BufferCache<P>::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; |
|
|
|
|