From 0e9a6759f90cd45ef708c17b2fb1f74db5c8fce7 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Thu, 21 Jan 2021 19:08:43 -0300
Subject: [PATCH] video_core/memory_manager: Flush destination buffer on
 CopyBlock

When we copy into a buffer, it might contain data modified from the GPU
on the same pages. Because of this, we have to flush the contents before
writing new data.

An alternative approach would be to write the data in place, but games
can also write data in other ways, invalidating our contents.

Fixes geometry in Zombie Panic in Wonderland DX.
---
 src/video_core/memory_manager.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index 1926bb025c..e5d357773e 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -332,6 +332,10 @@ void MemoryManager::FlushRegion(GPUVAddr gpu_addr, size_t size) const {
 void MemoryManager::CopyBlock(GPUVAddr gpu_dest_addr, GPUVAddr gpu_src_addr, std::size_t size) {
     std::vector<u8> tmp_buffer(size);
     ReadBlock(gpu_src_addr, tmp_buffer.data(), size);
+
+    // The output block must be flushed in case it has data modified from the GPU.
+    // Fixes NPC geometry in Zombie Panic in Wonderland DX
+    FlushRegion(gpu_dest_addr, size);
     WriteBlock(gpu_dest_addr, tmp_buffer.data(), size);
 }