diff --git a/rpcs3/Emu/RSX/RSXFIFO.cpp b/rpcs3/Emu/RSX/RSXFIFO.cpp index d91f2f90fd..291dc98790 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.cpp +++ b/rpcs3/Emu/RSX/RSXFIFO.cpp @@ -19,20 +19,20 @@ namespace rsx m_ctrl = pctrl->ctrl; } - void FIFO_control::inc_get() + void FIFO_control::inc_get(bool wait) { m_internal_get += 4; - // Check if put allows to procceed execution - while (m_ctrl->put == m_internal_get) + if (wait && m_ctrl->put == m_internal_get) { - if (Emu.IsStopped()) - { - break; - } - + // NOTE: Only supposed to be invoked to wait for a single arg on command[0] (4 bytes) + // Wait for put to allow us to procceed execution sync_get(); - std::this_thread::yield(); + + while (m_ctrl->put == m_internal_get && !Emu.IsStopped()) + { + std::this_thread::yield(); + } } } @@ -62,6 +62,7 @@ namespace rsx // Update ctrl registers m_ctrl->get = get; m_internal_get = get; + m_remaining_commands = 0; // Clear memwatch spinner m_memwatch_addr = 0; @@ -70,19 +71,13 @@ namespace rsx bool FIFO_control::read_unsafe(register_pair& data) { // Fast read with no processing, only safe inside a PACKET_BEGIN+count block - if (m_remaining_commands) + if (m_remaining_commands && + m_internal_get != m_ctrl->put) { m_command_reg += m_command_inc; m_args_ptr += 4; - - if (--m_remaining_commands) - { - inc_get(); - } - else - { - m_internal_get += 4; - } + m_remaining_commands--; + m_internal_get += 4; data.set(m_command_reg, vm::read32(m_args_ptr)); return true; @@ -103,6 +98,12 @@ namespace rsx return; } + if (m_remaining_commands && read_unsafe(data)) + { + // Previous block aborted to wait for PUT pointer + return; + } + if (m_memwatch_addr) { if (m_internal_get == m_memwatch_addr) @@ -179,7 +180,7 @@ namespace rsx m_remaining_commands = count - 1; } - inc_get(); + inc_get(true); // Wait for data block to become available m_internal_get += 4; data.set(cmd & 0xfffc, vm::read32(m_args_ptr)); diff --git a/rpcs3/Emu/RSX/RSXFIFO.h b/rpcs3/Emu/RSX/RSXFIFO.h index 9b8ec2e18c..3ec60da0f4 100644 --- a/rpcs3/Emu/RSX/RSXFIFO.h +++ b/rpcs3/Emu/RSX/RSXFIFO.h @@ -115,7 +115,7 @@ namespace rsx u32 get_pos() { return m_internal_get; } void sync_get() { m_ctrl->get.store(m_internal_get); } - void inc_get(); + void inc_get(bool wait); void set_get(u32 get); void set_put(u32 put);