diff options
| author | snowstormxd <214507868+snowstormxd@users.noreply.github.com> | 2026-11-01 14:21:03 +0000 |
|---|---|---|
| committer | snowstormxd <214507868+snowstormxd@users.noreply.github.com> | 2026-11-02 20:51:11 +0000 |
| commit | 06e211e0d0a1634d16f1d74d75682092fc92a5de (patch) | |
| tree | 807c900cc04018c5451a0db999b09b5988185051 /src/core/memory.cpp | |
| parent | 294cf48fb9c3032c1f778e8376ebc1f07ea02c49 (diff) | |
nx2: rearm clean read areas when the GPU writes them again
Port the coherency changes from alarok/Eglantine 77fc365f2 without its diagnostic framework or shutdown changes. Only GPU-dirty CPU reads become permanently preflushable, clean areas can be trapped on the next write, non-core readers avoid indexing core arrays, and collected CPU writes precede readback.
Assisted-by: Codex (source review, selective integration and verification)
(cherry picked from commit b64e211957180aa218ec6d9a3bcb020332279c3f)
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index cfc39916db..1f7315f3c1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -549,6 +549,8 @@ struct Memory::Impl { } void RasterizerArmReadTraps(u64 vaddr, u64 size) { + // Clean cached read areas also need invalidation when reactive flushing is enabled. + read_trap_generation.fetch_add(1, std::memory_order_release); if (vaddr == 0 || size == 0 || !AddressSpaceContains(*current_page_table, vaddr, size) || !ReadTrapsEnabled()) { return; @@ -781,6 +783,19 @@ struct Memory::Impl { gpu_device_memory = &system.Host1x().MemoryManager(); } const size_t core = system.GetCurrentHostThreadID(); + if (core >= Core::Hardware::NUM_CPU_CORES) { + // A service thread has no slot in the arrays below, and it does not use a slot of a + // core. It keeps no area, so it asks on each read. + if (static std::atomic_flag logged; !logged.test_and_set(std::memory_order_relaxed)) { + LOG_INFO(HW_Memory, "Read of cached guest memory from a thread that is not a core"); + } + Common::ScratchBuffer<u32> scratch; + gpu_device_memory->ApplyOpOnPointer(p, scratch, [&](DAddr address) { + DisarmReadTraps(v_address, size); + (void)system.GPU().OnCPURead(address, size); + }); + return; + } auto& current_area = rasterizer_read_areas[core]; if (const u64 generation = read_trap_generation.load(std::memory_order_acquire); read_area_generations[core] != generation) { |
