diff --git a/src/video_core/amdgpu/liverpool.cpp b/src/video_core/amdgpu/liverpool.cpp index 246c8c947..9fd865cd7 100644 --- a/src/video_core/amdgpu/liverpool.cpp +++ b/src/video_core/amdgpu/liverpool.cpp @@ -74,6 +74,7 @@ Liverpool::~Liverpool() { void Liverpool::Process(std::stop_token stoken) { Common::SetCurrentThreadName("shadPS4:GpuCommandProcessor"); + gpu_id = std::this_thread::get_id(); while (!stoken.stop_requested()) { { diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index c18bcd57b..be039bce4 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -1502,6 +1502,7 @@ public: u32 pipe_id; }; Common::SlotVector asc_queues{}; + std::thread::id gpu_id; private: struct Task { diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 1e3e37c4c..cf6e5bdb2 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -46,12 +46,24 @@ void BufferCache::InvalidateMemory(VAddr device_addr, u64 size) { return; } if (memory_tracker->IsRegionGpuModified(device_addr, size)) { - memory_tracker->UnmarkRegionAsGpuModified(device_addr, size); + ReadMemory(device_addr, size); } memory_tracker->MarkRegionAsCpuModified(device_addr, size); } void BufferCache::ReadMemory(VAddr device_addr, u64 size) { + if (std::this_thread::get_id() != liverpool->gpu_id) { + std::binary_semaphore command_wait{0}; + liverpool->SendCommand([this, &command_wait, device_addr, size] { + Buffer& buffer = slot_buffers[FindBuffer(device_addr, size)]; + DownloadBufferMemory(buffer, device_addr, size); + command_wait.release(); + }); + command_wait.acquire(); + } else { + Buffer& buffer = slot_buffers[FindBuffer(device_addr, size)]; + DownloadBufferMemory(buffer, device_addr, size); + } memory_tracker->UnmarkRegionAsGpuModified(device_addr, size); }