diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 14129e731d..36bd0143b6 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1662,7 +1662,7 @@ void spu_thread::cpu_work() // If either MFC size exceeds limit or timeout has been reached execute pending MFC commands if (mfc_size > g_cfg.core.mfc_transfers_shuffling || (timeout && get_system_time() - mfc_last_timestamp >= timeout)) { - do_mfc(false); + do_mfc(false, false); check_mfc_interrupts(pc + 4); } } @@ -2960,7 +2960,7 @@ void spu_thread::do_putlluc(const spu_mfc_cmd& args) vm::reservation_notifier(addr).notify_all(-128); } -void spu_thread::do_mfc(bool can_escape) +void spu_thread::do_mfc(bool can_escape, bool must_finish) { u32 removed = 0; u32 barrier = 0; @@ -3106,6 +3106,14 @@ void spu_thread::do_mfc(bool can_escape) { break; } + + if (!must_finish && g_cfg.core.mfc_shuffling_in_steps) + { + // Exit early, not all pending commands have to be executed at a single iteration + // Update last timestamp so the next MFC timeout check will use the current time + mfc_last_timestamp = get_system_time(); + return; + } } if (state & cpu_flag::pending) @@ -3171,12 +3179,14 @@ bool spu_thread::process_mfc_cmd() // Reset MFC timestamp in the case of full queue mfc_last_timestamp = 0; - // Process MFC commands if (test_stopped()) { return false; } + // Process MFC commands + do_mfc(); + auto old = state.add_fetch(cpu_flag::wait); if (is_stopped(old)) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 5047676b05..8ef8a7cec5 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -791,7 +791,7 @@ public: bool do_list_transfer(spu_mfc_cmd& args); void do_putlluc(const spu_mfc_cmd& args); bool do_putllc(const spu_mfc_cmd& args); - void do_mfc(bool can_escape = true); + void do_mfc(bool can_escape = true, bool must_finish = true); u32 get_mfc_completed() const; bool process_mfc_cmd(); diff --git a/rpcs3/Emu/system_config.h b/rpcs3/Emu/system_config.h index 7cffb9aefb..3c76c271e9 100644 --- a/rpcs3/Emu/system_config.h +++ b/rpcs3/Emu/system_config.h @@ -48,7 +48,8 @@ struct cfg_root : cfg::node cfg::_bool spu_cache{ this, "SPU Cache", true }; cfg::_bool spu_prof{ this, "SPU Profiler", false }; cfg::uint<0, 16> mfc_transfers_shuffling{ this, "MFC Commands Shuffling Limit", 0 }; - cfg::uint<0, 10000> mfc_transfers_timeout{ this, "MFC Commands Timeout", 0, true}; + cfg::uint<0, 10000> mfc_transfers_timeout{ this, "MFC Commands Timeout", 0, true }; + cfg::_bool mfc_shuffling_in_steps{ this, "MFC Commands Shuffling In Steps", false, true }; cfg::_enum enable_TSX{ this, "Enable TSX", has_rtm() ? tsx_usage::enabled : tsx_usage::disabled }; // Enable TSX. Forcing this on Haswell/Broadwell CPUs should be used carefully cfg::_bool spu_accurate_xfloat{ this, "Accurate xfloat", false }; cfg::_bool spu_approx_xfloat{ this, "Approximate xfloat", true };