From 1ff6bdd77799b817b9002b00d2bdfc05a2638f77 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 25 May 2025 20:00:19 +0300 Subject: [PATCH] rsx: Flush MM queue before applying nv3089 block transfers --- rpcs3/Emu/RSX/Host/MM.cpp | 25 +++++++++++++++++++++++++ rpcs3/Emu/RSX/Host/MM.h | 4 ++++ rpcs3/Emu/RSX/NV47/HW/nv0039.cpp | 8 ++++++++ 3 files changed, 37 insertions(+) diff --git a/rpcs3/Emu/RSX/Host/MM.cpp b/rpcs3/Emu/RSX/Host/MM.cpp index cf21b6e046..613f05e828 100644 --- a/rpcs3/Emu/RSX/Host/MM.cpp +++ b/rpcs3/Emu/RSX/Host/MM.cpp @@ -90,6 +90,31 @@ namespace rsx } } + void mm_flush(const rsx::simple_array& ranges) + { + std::lock_guard lock(g_mprotect_queue_lock); + if (g_deferred_mprotect_queue.empty()) + { + return; + } + + const auto ranges64 = ranges.map([](const auto& r) + { + const u64 start = reinterpret_cast(vm::base(r.start)); + const u64 end = start + r.length(); + return std::make_pair(start, end); + }); + + for (const auto& block : g_deferred_mprotect_queue) + { + if (ranges64.any(FN(block.overlaps(x.first, x.second)))) + { + mm_flush_mprotect_queue_internal(); + return; + } + } + } + void mm_flush_lazy() { if (!g_cfg.video.multithreaded_rsx) diff --git a/rpcs3/Emu/RSX/Host/MM.h b/rpcs3/Emu/RSX/Host/MM.h index e9415a685f..0c70a81aa5 100644 --- a/rpcs3/Emu/RSX/Host/MM.h +++ b/rpcs3/Emu/RSX/Host/MM.h @@ -3,6 +3,9 @@ #include #include +#include "Emu/RSX/Common/simple_array.hpp" +#include "Utilities/address_range.h" + namespace rsx { struct MM_block @@ -36,5 +39,6 @@ namespace rsx void mm_protect(void* start, u64 length, utils::protection prot); void mm_flush_lazy(); void mm_flush(u32 vm_address); + void mm_flush(const rsx::simple_array& ranges); void mm_flush(); } diff --git a/rpcs3/Emu/RSX/NV47/HW/nv0039.cpp b/rpcs3/Emu/RSX/NV47/HW/nv0039.cpp index fb20d93a69..831fa60adc 100644 --- a/rpcs3/Emu/RSX/NV47/HW/nv0039.cpp +++ b/rpcs3/Emu/RSX/NV47/HW/nv0039.cpp @@ -3,6 +3,7 @@ #include "Emu/RSX/RSXThread.h" #include "Emu/RSX/Core/RSXReservationLock.hpp" +#include "Emu/RSX/Host/MM.h" #include "context_accessors.define.h" @@ -57,6 +58,13 @@ namespace rsx auto res = ::rsx::reservation_lock(write_address, write_length, read_address, read_length); + rsx::simple_array flush_mm_ranges = + { + utils::address_range::start_length(write_address, write_length).to_page_range(), + utils::address_range::start_length(read_address, read_length).to_page_range() + }; + rsx::mm_flush(flush_mm_ranges); + u8 *dst = vm::_ptr(write_address); const u8 *src = vm::_ptr(read_address);