From 536fc7f0ea77e08d68c760f387c307d258804e3b Mon Sep 17 00:00:00 2001
From: Lioncash <mathew1800@gmail.com>
Date: Tue, 26 Nov 2019 14:10:49 -0500
Subject: [PATCH] core: Prepare various classes for memory read/write migration

Amends a few interfaces to be able to handle the migration over to the
new Memory class by passing the class by reference as a function
parameter where necessary.

Notably, within the filesystem services, this eliminates two ReadBlock()
calls by using the helper functions of HLERequestContext to do that for
us.
---
 src/audio_core/audio_renderer.cpp             | 24 ++++++++++---------
 src/audio_core/audio_renderer.h               | 10 ++++++--
 src/core/arm/arm_interface.cpp                |  3 +--
 src/core/arm/arm_interface.h                  |  8 ++++++-
 src/core/arm/dynarmic/arm_dynarmic.cpp        |  8 ++++---
 src/core/arm/dynarmic/arm_dynarmic.h          |  1 -
 src/core/arm/unicorn/arm_unicorn.cpp          |  2 +-
 src/core/arm/unicorn/arm_unicorn.h            |  1 -
 src/core/hle/kernel/client_session.cpp        |  4 ++--
 src/core/hle/kernel/client_session.h          |  6 ++++-
 src/core/hle/kernel/server_session.cpp        |  3 ++-
 src/core/hle/kernel/server_session.h          |  9 ++++++-
 src/core/hle/kernel/svc.cpp                   |  2 +-
 src/core/hle/service/audio/audren_u.cpp       |  5 ++--
 src/core/hle/service/filesystem/fsp_srv.cpp   |  7 ++----
 src/core/hle/service/lm/lm.cpp                | 13 ++++++----
 src/core/reporter.cpp                         | 14 +++++------
 src/core/tools/freezer.cpp                    | 14 +++++------
 src/core/tools/freezer.h                      |  7 +++++-
 src/video_core/rasterizer_accelerated.cpp     |  3 ++-
 src/video_core/rasterizer_accelerated.h       |  9 +++++--
 .../renderer_opengl/gl_rasterizer.cpp         |  5 ++--
 .../renderer_vulkan/vk_buffer_cache.cpp       |  4 +++-
 .../renderer_vulkan/vk_buffer_cache.h         |  7 +++++-
 24 files changed, 108 insertions(+), 61 deletions(-)

diff --git a/src/audio_core/audio_renderer.cpp b/src/audio_core/audio_renderer.cpp
index 6b0167acde..12e2b79019 100644
--- a/src/audio_core/audio_renderer.cpp
+++ b/src/audio_core/audio_renderer.cpp
@@ -36,9 +36,9 @@ public:
     }
 
     void SetWaveIndex(std::size_t index);
-    std::vector<s16> DequeueSamples(std::size_t sample_count);
+    std::vector<s16> DequeueSamples(std::size_t sample_count, Memory::Memory& memory);
     void UpdateState();
-    void RefreshBuffer();
+    void RefreshBuffer(Memory::Memory& memory);
 
 private:
     bool is_in_use{};
@@ -66,17 +66,18 @@ public:
         return info;
     }
 
-    void UpdateState();
+    void UpdateState(Memory::Memory& memory);
 
 private:
     EffectOutStatus out_status{};
     EffectInStatus info{};
 };
-AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
+AudioRenderer::AudioRenderer(Core::Timing::CoreTiming& core_timing, Memory::Memory& memory_,
+                             AudioRendererParameter params,
                              std::shared_ptr<Kernel::WritableEvent> buffer_event,
                              std::size_t instance_number)
     : worker_params{params}, buffer_event{buffer_event}, voices(params.voice_count),
-      effects(params.effect_count) {
+      effects(params.effect_count), memory{memory_} {
 
     audio_out = std::make_unique<AudioCore::AudioOut>();
     stream = audio_out->OpenStream(core_timing, STREAM_SAMPLE_RATE, STREAM_NUM_CHANNELS,
@@ -162,7 +163,7 @@ std::vector<u8> AudioRenderer::UpdateAudioRenderer(const std::vector<u8>& input_
     }
 
     for (auto& effect : effects) {
-        effect.UpdateState();
+        effect.UpdateState(memory);
     }
 
     // Release previous buffers and queue next ones for playback
@@ -206,13 +207,14 @@ void AudioRenderer::VoiceState::SetWaveIndex(std::size_t index) {
     is_refresh_pending = true;
 }
 
-std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count) {
+std::vector<s16> AudioRenderer::VoiceState::DequeueSamples(std::size_t sample_count,
+                                                           Memory::Memory& memory) {
     if (!IsPlaying()) {
         return {};
     }
 
     if (is_refresh_pending) {
-        RefreshBuffer();
+        RefreshBuffer(memory);
     }
 
     const std::size_t max_size{samples.size() - offset};
@@ -256,7 +258,7 @@ void AudioRenderer::VoiceState::UpdateState() {
     is_in_use = info.is_in_use;
 }
 
-void AudioRenderer::VoiceState::RefreshBuffer() {
+void AudioRenderer::VoiceState::RefreshBuffer(Memory::Memory& memory) {
     std::vector<s16> new_samples(info.wave_buffer[wave_index].buffer_sz / sizeof(s16));
     Memory::ReadBlock(info.wave_buffer[wave_index].buffer_addr, new_samples.data(),
                       info.wave_buffer[wave_index].buffer_sz);
@@ -307,7 +309,7 @@ void AudioRenderer::VoiceState::RefreshBuffer() {
     is_refresh_pending = false;
 }
 
-void AudioRenderer::EffectState::UpdateState() {
+void AudioRenderer::EffectState::UpdateState(Memory::Memory& memory) {
     if (info.is_new) {
         out_status.state = EffectStatus::New;
     } else {
@@ -340,7 +342,7 @@ void AudioRenderer::QueueMixedBuffer(Buffer::Tag tag) {
         std::size_t offset{};
         s64 samples_remaining{BUFFER_SIZE};
         while (samples_remaining > 0) {
-            const std::vector<s16> samples{voice.DequeueSamples(samples_remaining)};
+            const std::vector<s16> samples{voice.DequeueSamples(samples_remaining, memory)};
 
             if (samples.empty()) {
                 break;
diff --git a/src/audio_core/audio_renderer.h b/src/audio_core/audio_renderer.h
index abed224bb4..be1b019f17 100644
--- a/src/audio_core/audio_renderer.h
+++ b/src/audio_core/audio_renderer.h
@@ -22,6 +22,10 @@ namespace Kernel {
 class WritableEvent;
 }
 
+namespace Memory {
+class Memory;
+}
+
 namespace AudioCore {
 
 class AudioOut;
@@ -217,7 +221,8 @@ static_assert(sizeof(UpdateDataHeader) == 0x40, "UpdateDataHeader has wrong size
 
 class AudioRenderer {
 public:
-    AudioRenderer(Core::Timing::CoreTiming& core_timing, AudioRendererParameter params,
+    AudioRenderer(Core::Timing::CoreTiming& core_timing, Memory::Memory& memory_,
+                  AudioRendererParameter params,
                   std::shared_ptr<Kernel::WritableEvent> buffer_event, std::size_t instance_number);
     ~AudioRenderer();
 
@@ -238,7 +243,8 @@ private:
     std::vector<VoiceState> voices;
     std::vector<EffectState> effects;
     std::unique_ptr<AudioOut> audio_out;
-    AudioCore::StreamPtr stream;
+    StreamPtr stream;
+    Memory::Memory& memory;
 };
 
 } // namespace AudioCore
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 372612c9b3..dea192869f 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -13,7 +13,6 @@
 #include "core/memory.h"
 
 namespace Core {
-
 namespace {
 
 constexpr u64 ELF_DYNAMIC_TAG_NULL = 0;
@@ -156,7 +155,7 @@ std::vector<ARM_Interface::BacktraceEntry> ARM_Interface::GetBacktrace() const {
     }
 
     std::map<VAddr, std::string> modules;
-    auto& loader{System::GetInstance().GetAppLoader()};
+    auto& loader{system.GetAppLoader()};
     if (loader.ReadNSOModules(modules) != Loader::ResultStatus::Success) {
         return {};
     }
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 45e94e6257..47b964eb70 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -17,11 +17,13 @@ enum class VMAPermission : u8;
 }
 
 namespace Core {
+class System;
 
 /// Generic ARMv8 CPU interface
 class ARM_Interface : NonCopyable {
 public:
-    virtual ~ARM_Interface() {}
+    explicit ARM_Interface(System& system_) : system{system_} {}
+    virtual ~ARM_Interface() = default;
 
     struct ThreadContext {
         std::array<u64, 31> cpu_registers;
@@ -163,6 +165,10 @@ public:
     /// fp+0 : pointer to previous frame record
     /// fp+8 : value of lr for frame
     void LogBacktrace() const;
+
+protected:
+    /// System context that this ARM interface is running under.
+    System& system;
 };
 
 } // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index a0705b2b89..2b396f1d67 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -28,6 +28,7 @@ public:
     explicit ARM_Dynarmic_Callbacks(ARM_Dynarmic& parent) : parent(parent) {}
 
     u8 MemoryRead8(u64 vaddr) override {
+        auto& s = parent.system;
         return Memory::Read8(vaddr);
     }
     u16 MemoryRead16(u64 vaddr) override {
@@ -171,9 +172,10 @@ void ARM_Dynarmic::Step() {
 
 ARM_Dynarmic::ARM_Dynarmic(System& system, ExclusiveMonitor& exclusive_monitor,
                            std::size_t core_index)
-    : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
-      core_index{core_index}, system{system},
-      exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
+    : ARM_Interface{system},
+      cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), inner_unicorn{system},
+      core_index{core_index}, exclusive_monitor{
+                                  dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
 
 ARM_Dynarmic::~ARM_Dynarmic() = default;
 
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index 504d46c689..d08de475f2 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -58,7 +58,6 @@ private:
     ARM_Unicorn inner_unicorn;
 
     std::size_t core_index;
-    System& system;
     DynarmicExclusiveMonitor& exclusive_monitor;
 };
 
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 9698172dbf..48182c99ae 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -60,7 +60,7 @@ static bool UnmappedMemoryHook(uc_engine* uc, uc_mem_type type, u64 addr, int si
     return false;
 }
 
-ARM_Unicorn::ARM_Unicorn(System& system) : system{system} {
+ARM_Unicorn::ARM_Unicorn(System& system) : ARM_Interface{system} {
     CHECKED(uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc));
 
     auto fpv = 3 << 20;
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index b39426ea0b..3c5b155f93 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -45,7 +45,6 @@ private:
     static void InterruptHook(uc_engine* uc, u32 int_no, void* user_data);
 
     uc_engine* uc{};
-    System& system;
     GDBStub::BreakpointAddress last_bkpt{};
     bool last_bkpt_hit = false;
 };
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp
index 5995a65569..9849dbe914 100644
--- a/src/core/hle/kernel/client_session.cpp
+++ b/src/core/hle/kernel/client_session.cpp
@@ -21,10 +21,10 @@ ClientSession::~ClientSession() {
     }
 }
 
-ResultCode ClientSession::SendSyncRequest(Thread* thread) {
+ResultCode ClientSession::SendSyncRequest(Thread* thread, Memory::Memory& memory) {
     // Signal the server session that new data is available
     if (auto server = parent->server.lock()) {
-        return server->HandleSyncRequest(SharedFrom(thread));
+        return server->HandleSyncRequest(SharedFrom(thread), memory);
     }
 
     return ERR_SESSION_CLOSED_BY_REMOTE;
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index 5ae41db29c..484dd7bc90 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -10,6 +10,10 @@
 
 union ResultCode;
 
+namespace Memory {
+class Memory;
+}
+
 namespace Kernel {
 
 class KernelCore;
@@ -37,7 +41,7 @@ public:
         return HANDLE_TYPE;
     }
 
-    ResultCode SendSyncRequest(Thread* thread);
+    ResultCode SendSyncRequest(Thread* thread, Memory::Memory& memory);
 
 private:
     /// The parent session, which links to the server endpoint.
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index c7db21eb21..57878514d2 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -127,7 +127,8 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
     return RESULT_SUCCESS;
 }
 
-ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread) {
+ResultCode ServerSession::HandleSyncRequest(std::shared_ptr<Thread> thread,
+                                            Memory::Memory& memory) {
     // The ServerSession received a sync request, this means that there's new data available
     // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
     // similar.
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index 8a65647b6c..641709a45a 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -13,6 +13,10 @@
 #include "core/hle/kernel/wait_object.h"
 #include "core/hle/result.h"
 
+namespace Memory {
+class Memory;
+}
+
 namespace Kernel {
 
 class ClientPort;
@@ -85,10 +89,13 @@ public:
 
     /**
      * Handle a sync request from the emulated application.
+     *
      * @param thread Thread that initiated the request.
+     * @param memory Memory context to handle the sync request under.
+     *
      * @returns ResultCode from the operation.
      */
-    ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread);
+    ResultCode HandleSyncRequest(std::shared_ptr<Thread> thread, Memory::Memory& memory);
 
     bool ShouldWait(const Thread* thread) const override;
 
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index eddafaf601..68bff11ec2 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -383,7 +383,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
 
     // TODO(Subv): svcSendSyncRequest should put the caller thread to sleep while the server
     // responds and cause a reschedule.
-    return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread());
+    return session->SendSyncRequest(system.CurrentScheduler().GetCurrentThread(), system.Memory());
 }
 
 /// Get the ID for the specified thread.
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 4ea7ade6eb..82a5dbf141 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -49,8 +49,9 @@ public:
 
         system_event =
             Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent");
-        renderer = std::make_unique<AudioCore::AudioRenderer>(
-            system.CoreTiming(), audren_params, system_event.writable, instance_number);
+        renderer = std::make_unique<AudioCore::AudioRenderer>(system.CoreTiming(), system.Memory(),
+                                                              audren_params, system_event.writable,
+                                                              instance_number);
     }
 
 private:
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 5874ed6bda..89e1957f9c 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -391,13 +391,10 @@ public:
     }
 
     void RenameFile(Kernel::HLERequestContext& ctx) {
-        std::vector<u8> buffer;
-        buffer.resize(ctx.BufferDescriptorX()[0].Size());
-        Memory::ReadBlock(ctx.BufferDescriptorX()[0].Address(), buffer.data(), buffer.size());
+        std::vector<u8> buffer = ctx.ReadBuffer(0);
         const std::string src_name = Common::StringFromBuffer(buffer);
 
-        buffer.resize(ctx.BufferDescriptorX()[1].Size());
-        Memory::ReadBlock(ctx.BufferDescriptorX()[1].Address(), buffer.data(), buffer.size());
+        buffer = ctx.ReadBuffer(1);
         const std::string dst_name = Common::StringFromBuffer(buffer);
 
         LOG_DEBUG(Service_FS, "called. file '{}' to file '{}'", src_name, dst_name);
diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp
index 435f2d2865..74ecaef1b7 100644
--- a/src/core/hle/service/lm/lm.cpp
+++ b/src/core/hle/service/lm/lm.cpp
@@ -17,7 +17,8 @@ namespace Service::LM {
 
 class ILogger final : public ServiceFramework<ILogger> {
 public:
-    ILogger(Manager& manager) : ServiceFramework("ILogger"), manager(manager) {
+    explicit ILogger(Manager& manager_, Memory::Memory& memory_)
+        : ServiceFramework("ILogger"), manager{manager_}, memory{memory_} {
         static const FunctionInfo functions[] = {
             {0, &ILogger::Log, "Log"},
             {1, &ILogger::SetDestination, "SetDestination"},
@@ -74,11 +75,13 @@ private:
     }
 
     Manager& manager;
+    Memory::Memory& memory;
 };
 
 class LM final : public ServiceFramework<LM> {
 public:
-    explicit LM(Manager& manager) : ServiceFramework{"lm"}, manager(manager) {
+    explicit LM(Manager& manager_, Memory::Memory& memory_)
+        : ServiceFramework{"lm"}, manager{manager_}, memory{memory_} {
         // clang-format off
         static const FunctionInfo functions[] = {
             {0, &LM::OpenLogger, "OpenLogger"},
@@ -94,14 +97,16 @@ private:
 
         IPC::ResponseBuilder rb{ctx, 2, 0, 1};
         rb.Push(RESULT_SUCCESS);
-        rb.PushIpcInterface<ILogger>(manager);
+        rb.PushIpcInterface<ILogger>(manager, memory);
     }
 
     Manager& manager;
+    Memory::Memory& memory;
 };
 
 void InstallInterfaces(Core::System& system) {
-    std::make_shared<LM>(system.GetLogManager())->InstallAsService(system.ServiceManager());
+    std::make_shared<LM>(system.GetLogManager(), system.Memory())
+        ->InstallAsService(system.ServiceManager());
 }
 
 } // namespace Service::LM
diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp
index 6f4af77fd4..af0988d623 100644
--- a/src/core/reporter.cpp
+++ b/src/core/reporter.cpp
@@ -147,7 +147,7 @@ json GetFullDataAuto(const std::string& timestamp, u64 title_id, Core::System& s
 }
 
 template <bool read_value, typename DescriptorType>
-json GetHLEBufferDescriptorData(const std::vector<DescriptorType>& buffer) {
+json GetHLEBufferDescriptorData(const std::vector<DescriptorType>& buffer, Memory::Memory& memory) {
     auto buffer_out = json::array();
     for (const auto& desc : buffer) {
         auto entry = json{
@@ -167,7 +167,7 @@ json GetHLEBufferDescriptorData(const std::vector<DescriptorType>& buffer) {
     return buffer_out;
 }
 
-json GetHLERequestContextData(Kernel::HLERequestContext& ctx) {
+json GetHLERequestContextData(Kernel::HLERequestContext& ctx, Memory::Memory& memory) {
     json out;
 
     auto cmd_buf = json::array();
@@ -177,10 +177,10 @@ json GetHLERequestContextData(Kernel::HLERequestContext& ctx) {
 
     out["command_buffer"] = std::move(cmd_buf);
 
-    out["buffer_descriptor_a"] = GetHLEBufferDescriptorData<true>(ctx.BufferDescriptorA());
-    out["buffer_descriptor_b"] = GetHLEBufferDescriptorData<false>(ctx.BufferDescriptorB());
-    out["buffer_descriptor_c"] = GetHLEBufferDescriptorData<false>(ctx.BufferDescriptorC());
-    out["buffer_descriptor_x"] = GetHLEBufferDescriptorData<true>(ctx.BufferDescriptorX());
+    out["buffer_descriptor_a"] = GetHLEBufferDescriptorData<true>(ctx.BufferDescriptorA(), memory);
+    out["buffer_descriptor_b"] = GetHLEBufferDescriptorData<false>(ctx.BufferDescriptorB(), memory);
+    out["buffer_descriptor_c"] = GetHLEBufferDescriptorData<false>(ctx.BufferDescriptorC(), memory);
+    out["buffer_descriptor_x"] = GetHLEBufferDescriptorData<true>(ctx.BufferDescriptorX(), memory);
 
     return out;
 }
@@ -259,7 +259,7 @@ void Reporter::SaveUnimplementedFunctionReport(Kernel::HLERequestContext& ctx, u
     const auto title_id = system.CurrentProcess()->GetTitleID();
     auto out = GetFullDataAuto(timestamp, title_id, system);
 
-    auto function_out = GetHLERequestContextData(ctx);
+    auto function_out = GetHLERequestContextData(ctx, system.Memory());
     function_out["command_id"] = command_id;
     function_out["function_name"] = name;
     function_out["service_name"] = service_name;
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp
index 19b531ecb0..c7f42388f1 100644
--- a/src/core/tools/freezer.cpp
+++ b/src/core/tools/freezer.cpp
@@ -11,12 +11,11 @@
 #include "core/tools/freezer.h"
 
 namespace Tools {
-
 namespace {
 
 constexpr s64 MEMORY_FREEZER_TICKS = static_cast<s64>(Core::Timing::BASE_CLOCK_RATE / 60);
 
-u64 MemoryReadWidth(u32 width, VAddr addr) {
+u64 MemoryReadWidth(Memory::Memory& memory, u32 width, VAddr addr) {
     switch (width) {
     case 1:
         return Memory::Read8(addr);
@@ -32,7 +31,7 @@ u64 MemoryReadWidth(u32 width, VAddr addr) {
     }
 }
 
-void MemoryWriteWidth(u32 width, VAddr addr, u64 value) {
+void MemoryWriteWidth(Memory::Memory& memory, u32 width, VAddr addr, u64 value) {
     switch (width) {
     case 1:
         Memory::Write8(addr, static_cast<u8>(value));
@@ -53,7 +52,8 @@ void MemoryWriteWidth(u32 width, VAddr addr, u64 value) {
 
 } // Anonymous namespace
 
-Freezer::Freezer(Core::Timing::CoreTiming& core_timing) : core_timing(core_timing) {
+Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Memory::Memory& memory_)
+    : core_timing{core_timing_}, memory{memory_} {
     event = Core::Timing::CreateEvent(
         "MemoryFreezer::FrameCallback",
         [this](u64 userdata, s64 cycles_late) { FrameCallback(userdata, cycles_late); });
@@ -89,7 +89,7 @@ void Freezer::Clear() {
 u64 Freezer::Freeze(VAddr address, u32 width) {
     std::lock_guard lock{entries_mutex};
 
-    const auto current_value = MemoryReadWidth(width, address);
+    const auto current_value = MemoryReadWidth(memory, width, address);
     entries.push_back({address, width, current_value});
 
     LOG_DEBUG(Common_Memory,
@@ -169,7 +169,7 @@ void Freezer::FrameCallback(u64 userdata, s64 cycles_late) {
         LOG_DEBUG(Common_Memory,
                   "Enforcing memory freeze at address={:016X}, value={:016X}, width={:02X}",
                   entry.address, entry.value, entry.width);
-        MemoryWriteWidth(entry.width, entry.address, entry.value);
+        MemoryWriteWidth(memory, entry.width, entry.address, entry.value);
     }
 
     core_timing.ScheduleEvent(MEMORY_FREEZER_TICKS - cycles_late, event);
@@ -181,7 +181,7 @@ void Freezer::FillEntryReads() {
     LOG_DEBUG(Common_Memory, "Updating memory freeze entries to current values.");
 
     for (auto& entry : entries) {
-        entry.value = MemoryReadWidth(entry.width, entry.address);
+        entry.value = MemoryReadWidth(memory, entry.width, entry.address);
     }
 }
 
diff --git a/src/core/tools/freezer.h b/src/core/tools/freezer.h
index 90b1a885c1..916339c6c8 100644
--- a/src/core/tools/freezer.h
+++ b/src/core/tools/freezer.h
@@ -16,6 +16,10 @@ class CoreTiming;
 struct EventType;
 } // namespace Core::Timing
 
+namespace Memory {
+class Memory;
+}
+
 namespace Tools {
 
 /**
@@ -34,7 +38,7 @@ public:
         u64 value;
     };
 
-    explicit Freezer(Core::Timing::CoreTiming& core_timing);
+    explicit Freezer(Core::Timing::CoreTiming& core_timing_, Memory::Memory& memory_);
     ~Freezer();
 
     // Enables or disables the entire memory freezer.
@@ -78,6 +82,7 @@ private:
 
     std::shared_ptr<Core::Timing::EventType> event;
     Core::Timing::CoreTiming& core_timing;
+    Memory::Memory& memory;
 };
 
 } // namespace Tools
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp
index b230dcc182..f3dbadebcf 100644
--- a/src/video_core/rasterizer_accelerated.cpp
+++ b/src/video_core/rasterizer_accelerated.cpp
@@ -22,7 +22,8 @@ constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
 
 } // Anonymous namespace
 
-RasterizerAccelerated::RasterizerAccelerated() = default;
+RasterizerAccelerated::RasterizerAccelerated(Memory::Memory& cpu_memory_)
+    : cpu_memory{cpu_memory_} {}
 
 RasterizerAccelerated::~RasterizerAccelerated() = default;
 
diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h
index 8f7e3547e9..315798e7c8 100644
--- a/src/video_core/rasterizer_accelerated.h
+++ b/src/video_core/rasterizer_accelerated.h
@@ -11,12 +11,16 @@
 #include "common/common_types.h"
 #include "video_core/rasterizer_interface.h"
 
+namespace Memory {
+class Memory;
+}
+
 namespace VideoCore {
 
 /// Implements the shared part in GPU accelerated rasterizers in RasterizerInterface.
 class RasterizerAccelerated : public RasterizerInterface {
 public:
-    explicit RasterizerAccelerated();
+    explicit RasterizerAccelerated(Memory::Memory& cpu_memory_);
     ~RasterizerAccelerated() override;
 
     void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) override;
@@ -24,8 +28,9 @@ public:
 private:
     using CachedPageMap = boost::icl::interval_map<u64, int>;
     CachedPageMap cached_pages;
-
     std::mutex pages_mutex;
+
+    Memory::Memory& cpu_memory;
 };
 
 } // namespace VideoCore
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f97ec06f0c..85f05544cd 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -86,8 +86,9 @@ std::size_t GetConstBufferSize(const Tegra::Engines::ConstBufferInfo& buffer,
 
 RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
                                    ScreenInfo& info)
-    : texture_cache{system, *this, device}, shader_cache{*this, system, emu_window, device},
-      system{system}, screen_info{info}, buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} {
+    : RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device},
+      shader_cache{*this, system, emu_window, device}, system{system}, screen_info{info},
+      buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} {
     shader_program_manager = std::make_unique<GLShader::ProgramManager>();
     state.draw.shader_program = 0;
     state.Apply();
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index d2e9f40315..9596387471 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -24,9 +24,11 @@ CachedBufferEntry::CachedBufferEntry(VAddr cpu_addr, std::size_t size, u64 offse
       alignment{alignment} {}
 
 VKBufferCache::VKBufferCache(Tegra::MemoryManager& tegra_memory_manager,
+                             Memory::Memory& cpu_memory_,
                              VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
                              VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size)
-    : RasterizerCache{rasterizer}, tegra_memory_manager{tegra_memory_manager} {
+    : RasterizerCache{rasterizer}, tegra_memory_manager{tegra_memory_manager}, cpu_memory{
+                                                                                   cpu_memory_} {
     const auto usage = vk::BufferUsageFlagBits::eVertexBuffer |
                        vk::BufferUsageFlagBits::eIndexBuffer |
                        vk::BufferUsageFlagBits::eUniformBuffer;
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index 49f13bcdcd..daa8ccf667 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -13,6 +13,10 @@
 #include "video_core/renderer_vulkan/declarations.h"
 #include "video_core/renderer_vulkan/vk_scheduler.h"
 
+namespace Memory {
+class Memory;
+}
+
 namespace Tegra {
 class MemoryManager;
 }
@@ -58,7 +62,7 @@ private:
 
 class VKBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> {
 public:
-    explicit VKBufferCache(Tegra::MemoryManager& tegra_memory_manager,
+    explicit VKBufferCache(Tegra::MemoryManager& tegra_memory_manager, Memory::Memory& cpu_memory_,
                            VideoCore::RasterizerInterface& rasterizer, const VKDevice& device,
                            VKMemoryManager& memory_manager, VKScheduler& scheduler, u64 size);
     ~VKBufferCache();
@@ -92,6 +96,7 @@ private:
     void AlignBuffer(std::size_t alignment);
 
     Tegra::MemoryManager& tegra_memory_manager;
+    Memory::Memory& cpu_memory;
 
     std::unique_ptr<VKStreamBuffer> stream_buffer;
     vk::Buffer buffer_handle;