From 600c8b5ab974a4f02161935b4f968885de47a694 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 1 Jul 2026 06:09:14 +0000 Subject: [PATCH] [vk, nce] force flush when NCE fault on rasterizer area Signed-off-by: lizzie --- src/core/arm/nce/arm_nce.cpp | 5 ++--- src/core/memory.cpp | 36 +++++++++++++++++------------------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp index 63d5638fce..ad57146f1a 100644 --- a/src/core/arm/nce/arm_nce.cpp +++ b/src/core/arm/nce/arm_nce.cpp @@ -162,9 +162,8 @@ bool ArmNce::HandleGuestAccessFault(GuestContext* guest_ctx, void* raw_info, voi // Try to handle an invalid access. // TODO: handle accesses which split a page? - const Common::ProcessAddress addr = - (reinterpret_cast(info->si_addr) & ~Memory::YUZU_PAGEMASK); - auto& memory = guest_ctx->parent->m_running_thread->GetOwnerProcess()->GetMemory(); + const Common::ProcessAddress addr = u64(info->si_addr) & ~Memory::YUZU_PAGEMASK; + if (memory.InvalidateNCE(addr, Memory::YUZU_PAGESIZE)) { // We handled the access successfully and are returning to guest code. return true; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 38e77e863f..55ff112154 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -737,10 +737,9 @@ struct Memory::Impl { PAddr last_address; }; - void InvalidateGPUMemory(u8* p, size_t size) { + void InvalidateGPUMemory(u8* p, size_t size, bool flush) { constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1; - const size_t core = (std::min)(system.GetCurrentHostThreadID(), - sys_core); // any other calls threads go to syscore. + const size_t core = (std::min)(system.GetCurrentHostThreadID(), sys_core); // any other calls threads go to syscore. if (!gpu_device_memory) [[unlikely]] { gpu_device_memory = &system.Host1x().MemoryManager(); } @@ -754,8 +753,12 @@ struct Memory::Impl { } }; auto& gpu = system.GPU(); - gpu_device_memory->ApplyOpOnPointer( - p, scratch_buffers[core], [&](DAddr address) { gpu.InvalidateRegion(address, size); }); + gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) { + if (flush) { + gpu.FlushRegion(address, size); + } + gpu.InvalidateRegion(address, size); + }); } Core::System& system; @@ -959,27 +962,22 @@ void Memory::MarkRegionDebug(Common::ProcessAddress vaddr, u64 size, bool debug) } bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) { - [[maybe_unused]] bool mapped = true; - [[maybe_unused]] bool rasterizer = false; - - u8* const ptr = impl->GetPointerImpl( - GetInteger(vaddr), - [&] { - LOG_ERROR(HW_Memory, "Unmapped InvalidateNCE for {} bytes @ {:#x}", size, - GetInteger(vaddr)); - mapped = false; - }, - [&] { rasterizer = true; }); + bool mapped = true; + bool rasterizer = false; + u8* const ptr = impl->GetPointerImpl(GetInteger(vaddr), [&] { + LOG_ERROR(HW_Memory, "Unmapped InvalidateNCE for {} bytes @ {:#x}", size, GetInteger(vaddr)); + mapped = false; + }, [&] { + rasterizer = true; + }); if (rasterizer) { - impl->InvalidateGPUMemory(ptr, size); + impl->InvalidateGPUMemory(ptr, size, true); } - #ifdef __ANDROID__ if (!rasterizer && mapped) { impl->host_buffer->DeferredMapSeparateHeap(GetInteger(vaddr)); } #endif - return mapped && ptr != nullptr; }