diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 837016de1d..eabc6dfccb 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -757,7 +757,7 @@ struct Memory::Impl { }; auto& gpu = system.GPU(); gpu_device_memory->ApplyOpOnPointer( - p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size); }); + p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size, true); }); } Core::System& system; diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 9901cf4262..6aa7f9abd8 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -226,7 +226,17 @@ struct GPU::Impl { } /// Notify rasterizer that any caches of the specified region should be invalidated - void InvalidateRegion(DAddr addr, u64 size) { + void InvalidateRegion(DAddr addr, u64 size, bool preserve_gpu_writes) { + VideoCore::RasterizerInterface* rasterizer = renderer->ReadRasterizer(); + if (preserve_gpu_writes && rasterizer->MustFlushRegion(addr, size, VideoCommon::CacheType::BufferCache)) { + const u64 fence = RequestSyncOperation([rasterizer, addr, size] { + rasterizer->FlushRegion(addr, size, VideoCommon::CacheType::BufferCache); + rasterizer->OnCacheInvalidation(addr, size); + }); + gpu_thread.TickGPU(is_async); + WaitForSyncOperation(fence); + return; + } gpu_thread.InvalidateRegion(addr, size); } @@ -518,8 +528,8 @@ void GPU::FlushRegion(DAddr addr, u64 size) { impl->FlushRegion(addr, size); } -void GPU::InvalidateRegion(DAddr addr, u64 size) { - impl->InvalidateRegion(addr, size); +void GPU::InvalidateRegion(DAddr addr, u64 size, bool preserve_gpu_writes) { + impl->InvalidateRegion(addr, size, preserve_gpu_writes); } bool GPU::OnCPUWrite(DAddr addr, u64 size) { diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 75956ea199..974d214e10 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -248,7 +248,7 @@ public: void FlushRegion(DAddr addr, u64 size); /// Notify rasterizer that any caches of the specified region should be invalidated - void InvalidateRegion(DAddr addr, u64 size); + void InvalidateRegion(DAddr addr, u64 size, bool preserve_gpu_writes = false); /// Notify rasterizer that CPU is trying to write this area. It returns true if the area is /// sensible, false otherwise, addr and size must be a valid combination