diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index 58f4c19c05..bd38a4a95c 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -309,6 +309,11 @@ error_code sys_rsx_context_iomap(u32 context_id, u32 io, u32 ea, u32 size, u64 f return CELL_EINVAL; } + if (!render->is_fifo_idle()) + { + sys_rsx.warning("sys_rsx_context_iomap(): RSX is not idle while mapping io"); + } + vm::reader_lock rlock; for (u32 addr = ea, end = ea + size; addr < end; addr += 0x100000) @@ -355,6 +360,11 @@ error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size) return CELL_EINVAL; } + if (!render->is_fifo_idle()) + { + sys_rsx.warning("sys_rsx_context_iounmap(): RSX is not idle while unmapping io"); + } + vm::reader_lock rlock; std::scoped_lock lock(s_rsxmem_mtx); @@ -549,6 +559,11 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64 verify(HERE), a3 < std::size(render->tiles); + if (!render->is_fifo_idle()) + { + sys_rsx.warning("sys_rsx_context_attribute(): RSX is not idle while setting tile"); + } + auto& tile = render->tiles[a3]; const u32 location = ((a4 >> 32) & 0x3) - 1; @@ -629,6 +644,11 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64 verify(HERE), a3 < std::size(render->zculls); + if (!render->is_fifo_idle()) + { + sys_rsx.warning("sys_rsx_context_attribute(): RSX is not idle while setting zcull"); + } + const u32 offset = (a5 & 0xFFFFFFFF); const bool binded = (a6 & 0xFFFFFFFF) != 0; diff --git a/rpcs3/Emu/RSX/Capture/rsx_replay.cpp b/rpcs3/Emu/RSX/Capture/rsx_replay.cpp index e60096f4a8..6cc3b39f86 100644 --- a/rpcs3/Emu/RSX/Capture/rsx_replay.cpp +++ b/rpcs3/Emu/RSX/Capture/rsx_replay.cpp @@ -200,7 +200,7 @@ namespace rsx continue; // wait until rsx idle and at our first 'stop' to apply state - while (!Emu.IsStopped() && (render->ctrl->get != render->ctrl->put) && (render->ctrl->get != fifo_stops[stopIdx])) + while (!Emu.IsStopped() && !render->is_fifo_idle() && (render->ctrl->get != fifo_stops[stopIdx])) { while (Emu.IsPaused()) std::this_thread::sleep_for(10ms); @@ -222,7 +222,7 @@ namespace rsx u32 end = fifo_stops.back(); render->ctrl->put = end; - while (render->ctrl->get != end && !Emu.IsStopped()) + while (!render->is_fifo_idle() && !Emu.IsStopped()) { while (Emu.IsPaused()) std::this_thread::sleep_for(10ms); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 1d84ef8737..b44f6543db 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2262,6 +2262,11 @@ namespace rsx zcull_ctrl->on_sync_hint(args); } + bool thread::is_fifo_idle() const + { + return ctrl->get == (ctrl->put & ~3); + } + void thread::flush_fifo() { // Make sure GET value is exposed before sync points diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index ece2c93c53..595601b66a 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -622,6 +622,7 @@ namespace rsx u32 restore_point = 0; atomic_t external_interrupt_lock{ 0 }; atomic_t external_interrupt_ack{ false }; + bool is_fifo_idle() const; void flush_fifo(); void recover_fifo(); static void fifo_wake_delay(u64 div = 1);