diff --git a/rpcs3/Emu/RSX/RSXFIFO.cpp b/rpcs3/Emu/RSX/RSXFIFO.cpp index 0eca963bcb..886795fa6a 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.cpp +++ b/rpcs3/Emu/RSX/RSXFIFO.cpp @@ -137,11 +137,9 @@ namespace rsx m_memwatch_cmp = 0; } - u32 cmd; - if (u32 addr = RSXIOMem.RealAddr(m_internal_get)) { - cmd = vm::read32(addr); + m_cmd = vm::read32(addr); } else { @@ -150,15 +148,15 @@ namespace rsx return; } - if (UNLIKELY(cmd & RSX_METHOD_NON_METHOD_CMD_MASK)) + if (UNLIKELY(m_cmd & RSX_METHOD_NON_METHOD_CMD_MASK)) { - if ((cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD || - (cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD || - (cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD || - (cmd & RSX_METHOD_RETURN_MASK) == RSX_METHOD_RETURN_CMD) + if ((m_cmd & RSX_METHOD_OLD_JUMP_CMD_MASK) == RSX_METHOD_OLD_JUMP_CMD || + (m_cmd & RSX_METHOD_NEW_JUMP_CMD_MASK) == RSX_METHOD_NEW_JUMP_CMD || + (m_cmd & RSX_METHOD_CALL_CMD_MASK) == RSX_METHOD_CALL_CMD || + (m_cmd & RSX_METHOD_RETURN_MASK) == RSX_METHOD_RETURN_CMD) { // Flow control, stop reading - data.reg = cmd; + data.reg = m_cmd; return; } @@ -177,7 +175,7 @@ namespace rsx } verify(HERE), !m_remaining_commands; - const u32 count = (cmd >> 18) & 0x7ff; + const u32 count = (m_cmd >> 18) & 0x7ff; if (!count) { @@ -189,15 +187,15 @@ namespace rsx if (count > 1) { // Set up readback parameters - m_command_reg = cmd & 0xfffc; - m_command_inc = ((cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? 0 : 4; + m_command_reg = m_cmd & 0xfffc; + m_command_inc = ((m_cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? 0 : 4; m_remaining_commands = count - 1; } inc_get(true); // Wait for data block to become available m_internal_get += 4; - data.set(cmd & 0xfffc, vm::read32(m_args_ptr)); + data.set(m_cmd & 0xfffc, vm::read32(m_args_ptr)); } void flattening_helper::reset(bool _enabled) @@ -405,7 +403,7 @@ namespace rsx } case FIFO::FIFO_ERROR: { - LOG_ERROR(RSX, "FIFO error: possible desync event"); + LOG_ERROR(RSX, "FIFO error: possible desync event (last cmd = 0x%x)", fifo_ctrl->last_cmd()); recover_fifo(); return; } diff --git a/rpcs3/Emu/RSX/RSXFIFO.h b/rpcs3/Emu/RSX/RSXFIFO.h index d9ba900ee2..d70918f72f 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.h +++ b/rpcs3/Emu/RSX/RSXFIFO.h @@ -121,12 +121,14 @@ namespace rsx u32 m_command_inc = 0; u32 m_remaining_commands = 0; u32 m_args_ptr = 0; + u32 m_cmd = ~0u; public: FIFO_control(rsx::thread* pctrl); ~FIFO_control() = default; u32 get_pos() { return m_internal_get; } + u32 last_cmd() { return m_cmd; } void sync_get() { m_ctrl->get.release(m_internal_get); } void inc_get(bool wait); void set_get(u32 get); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 99d41a5d9a..3ddf4220bd 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2349,6 +2349,12 @@ namespace rsx invalid_command_interrupt_raised = false; } + u32 thread::get_fifo_cmd() + { + // Last fifo cmd for logging and utility + return fifo_ctrl->last_cmd(); + } + void thread::read_barrier(u32 memory_address, u32 memory_range) { zcull_ctrl->read_barrier(this, memory_address, memory_range); diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 505adcb286..a110d8aea9 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -520,6 +520,7 @@ namespace rsx atomic_t external_interrupt_ack{ false }; void flush_fifo(); void recover_fifo(); + u32 get_fifo_cmd(); // Performance approximation counters struct diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index c4d5267573..0504c666a7 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -41,7 +41,9 @@ namespace rsx { //Don't throw, gather information and ignore broken/garbage commands //TODO: Investigate why these commands are executed at all. (Heap corruption? Alignment padding?) - LOG_ERROR(RSX, "Invalid RSX method 0x%x (arg=0x%x)", _reg << 2, arg); + const u32 cmd = rsx->get_fifo_cmd(); + LOG_ERROR(RSX, "Invalid RSX method 0x%x (arg=0x%x, start=0x%x, count=0x%x, non-inc=%s)", _reg << 2, arg, + cmd & 0xfffc, (cmd >> 18) & 0x7ff, !!(cmd & RSX_METHOD_NON_INCREMENT_CMD)); rsx->invalid_command_interrupt_raised = true; }