Browse Source

[TEST] Sync and copy buffer hazards

CamilleLaVey 2 days ago
parent
commit
f4e48b5d8c
  1. 42
      src/video_core/buffer_cache/buffer_cache.h
  2. 3
      src/video_core/buffer_cache/buffer_cache_base.h

42
src/video_core/buffer_cache/buffer_cache.h

@ -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;

3
src/video_core/buffer_cache/buffer_cache_base.h

@ -10,6 +10,7 @@
#include <array>
#include <bit>
#include <functional>
#include <limits>
#include <memory>
#include <mutex>
#include <numeric>
@ -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();

Loading…
Cancel
Save