From b0a607539aa58d2b46d8ce46a1ee8d78e1132f9c Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Mon, 9 Mar 2026 00:34:12 -0400 Subject: [PATCH] [nce] Added rasterizer caching checks to memory management --- src/core/arm/nce/arm_nce.cpp | 4 +++- src/core/memory.cpp | 13 +++++++++++++ src/core/memory.h | 4 +++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp index 7f8326bf56..3140a78be3 100644 --- a/src/core/arm/nce/arm_nce.cpp +++ b/src/core/arm/nce/arm_nce.cpp @@ -199,8 +199,10 @@ bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, voi const Common::ProcessAddress addr = fault_addr & ~Memory::YUZU_PAGEMASK; const u64 page_offset = fault_addr & Memory::YUZU_PAGEMASK; auto& memory = parent->m_running_thread->GetOwnerProcess()->GetMemory(); + const bool rasterizer_cached = memory.IsRasterizerCached(addr); const bool prefer_precise_channel = ShouldUsePreciseAccessChannel(guest_ctx, fault_addr) || - parent->IsPreciseAccessPage(fault_addr); + parent->IsPreciseAccessPage(fault_addr) || + rasterizer_cached; if (prefer_precise_channel) { if (auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); next_pc) { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 0ad360c3df..f7031d88b5 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -639,6 +639,15 @@ struct Memory::Impl { GetInteger(vaddr), []() {}, []() {}); } + [[nodiscard]] bool IsRasterizerCached(const Common::ProcessAddress vaddr) const { + const u64 addr = GetInteger(vaddr) & 0xffffffffffffULL; + if (!AddressSpaceContains(*current_page_table, addr, 1)) { + return false; + } + return current_page_table->entries[addr >> YUZU_PAGEBITS].ptr.Type() == + Common::PageType::RasterizerCachedMemory; + } + /// @brief Reads a particular data type out of memory at the given virtual address. /// @param vaddr The virtual address to read the data type from. /// @tparam T The data type to read out of memory. @@ -1036,6 +1045,10 @@ void Memory::RasterizerMarkRegionCached(Common::ProcessAddress vaddr, u64 size, impl->RasterizerMarkRegionCached(GetInteger(vaddr), size, cached); } +bool Memory::IsRasterizerCached(Common::ProcessAddress vaddr) const { + return impl->IsRasterizerCached(vaddr); +} + void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) { impl->MarkRegionDebug(GetInteger(vaddr), size, debug); } diff --git a/src/core/memory.h b/src/core/memory.h index 7167efbb84..dcf8ea9656 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: 2014 Citra Emulator Project @@ -493,6 +493,8 @@ public: void SetGPUDirtyManagers(std::span managers); + [[nodiscard]] bool IsRasterizerCached(Common::ProcessAddress vaddr) const; + bool InvalidateNCE(Common::ProcessAddress vaddr, size_t size); bool InvalidateSeparateHeap(void* fault_address);