From 648ed55fe61f4f55f2a8c58d9bc2d4dca934cd37 Mon Sep 17 00:00:00 2001
From: Fernando Sahmkow <fsahmkow27@gmail.com>
Date: Sun, 7 Jan 2024 07:52:09 +0100
Subject: [PATCH] Core: Make sure GPU Dirty Managers ae shared by all
 processes.

---
 src/core/core.cpp                 | 12 +++++++++++-
 src/core/core.h                   |  4 ++++
 src/core/hle/kernel/k_process.cpp | 14 ++++----------
 src/core/hle/kernel/k_process.h   |  4 ----
 4 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/core/core.cpp b/src/core/core.cpp
index 04e1f13ff8..2392fe1368 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -28,6 +28,7 @@
 #include "core/file_sys/savedata_factory.h"
 #include "core/file_sys/vfs_concat.h"
 #include "core/file_sys/vfs_real.h"
+#include "core/gpu_dirty_memory_manager.h"
 #include "core/hle/kernel/k_memory_manager.h"
 #include "core/hle/kernel/k_process.h"
 #include "core/hle/kernel/k_resource_limit.h"
@@ -565,6 +566,9 @@ struct System::Impl {
     std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
     std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_cpu{};
 
+    std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES>
+        gpu_dirty_memory_managers;
+
     std::deque<std::vector<u8>> user_channel;
 };
 
@@ -651,8 +655,14 @@ size_t System::GetCurrentHostThreadID() const {
     return impl->kernel.GetCurrentHostThreadID();
 }
 
+std::span<GPUDirtyMemoryManager> System::GetGPUDirtyMemoryManager() {
+    return impl->gpu_dirty_memory_managers;
+}
+
 void System::GatherGPUDirtyMemory(std::function<void(PAddr, size_t)>& callback) {
-    return this->ApplicationProcess()->GatherGPUDirtyMemory(callback);
+    for (auto& manager : impl->gpu_dirty_memory_managers) {
+        manager.Gather(callback);
+    }
 }
 
 PerfStatsResults System::GetAndResetPerfStats() {
diff --git a/src/core/core.h b/src/core/core.h
index 20ec2ffff3..80446f385c 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -8,6 +8,7 @@
 #include <functional>
 #include <memory>
 #include <mutex>
+#include <span>
 #include <string>
 #include <vector>
 
@@ -116,6 +117,7 @@ class CpuManager;
 class Debugger;
 class DeviceMemory;
 class ExclusiveMonitor;
+class GPUDirtyMemoryManager;
 class PerfStats;
 class Reporter;
 class SpeedLimiter;
@@ -224,6 +226,8 @@ public:
     /// Prepare the core emulation for a reschedule
     void PrepareReschedule(u32 core_index);
 
+    std::span<GPUDirtyMemoryManager> GetGPUDirtyMemoryManager();
+
     void GatherGPUDirtyMemory(std::function<void(PAddr, size_t)>& callback);
 
     [[nodiscard]] size_t GetCurrentHostThreadID() const;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 53735a2251..0b08e877ef 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -5,6 +5,7 @@
 #include "common/scope_exit.h"
 #include "common/settings.h"
 #include "core/core.h"
+#include "core/gpu_dirty_memory_manager.h"
 #include "core/hle/kernel/k_process.h"
 #include "core/hle/kernel/k_scoped_resource_reservation.h"
 #include "core/hle/kernel/k_shared_memory.h"
@@ -320,7 +321,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa
 
     // Ensure our memory is initialized.
     m_memory.SetCurrentPageTable(*this);
-    m_memory.SetGPUDirtyManagers(m_dirty_memory_managers);
+    m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager());
 
     // Ensure we can insert the code region.
     R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize,
@@ -417,7 +418,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params,
 
     // Ensure our memory is initialized.
     m_memory.SetCurrentPageTable(*this);
-    m_memory.SetGPUDirtyManagers(m_dirty_memory_managers);
+    m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager());
 
     // Ensure we can insert the code region.
     R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code),
@@ -1141,8 +1142,7 @@ void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {}
 KProcess::KProcess(KernelCore& kernel)
     : KAutoObjectWithSlabHeapAndContainer(kernel), m_page_table{kernel}, m_state_lock{kernel},
       m_list_lock{kernel}, m_cond_var{kernel.System()}, m_address_arbiter{kernel.System()},
-      m_handle_table{kernel}, m_dirty_memory_managers{},
-      m_exclusive_monitor{}, m_memory{kernel.System()} {}
+      m_handle_table{kernel}, m_exclusive_monitor{}, m_memory{kernel.System()} {}
 KProcess::~KProcess() = default;
 
 Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size,
@@ -1324,10 +1324,4 @@ bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointT
     return true;
 }
 
-void KProcess::GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback) {
-    for (auto& manager : m_dirty_memory_managers) {
-        manager.Gather(callback);
-    }
-}
-
 } // namespace Kernel
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index 53c0e33162..ab1358a129 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -7,7 +7,6 @@
 
 #include "core/arm/arm_interface.h"
 #include "core/file_sys/program_metadata.h"
-#include "core/gpu_dirty_memory_manager.h"
 #include "core/hle/kernel/code_set.h"
 #include "core/hle/kernel/k_address_arbiter.h"
 #include "core/hle/kernel/k_capabilities.h"
@@ -128,7 +127,6 @@ private:
 #ifdef HAS_NCE
     std::unordered_map<u64, u64> m_post_handlers{};
 #endif
-    std::array<Core::GPUDirtyMemoryManager, Core::Hardware::NUM_CPU_CORES> m_dirty_memory_managers;
     std::unique_ptr<Core::ExclusiveMonitor> m_exclusive_monitor;
     Core::Memory::Memory m_memory;
 
@@ -511,8 +509,6 @@ public:
         return m_memory;
     }
 
-    void GatherGPUDirtyMemory(std::function<void(VAddr, size_t)>& callback);
-
     Core::ExclusiveMonitor& GetExclusiveMonitor() const {
         return *m_exclusive_monitor;
     }