VideoCommon: fix common opcode decoding errors

Many games call GXSetGPFifo() without first waiting for the GP to finish
consuming outstanding commands in the previous GP fifo. Normally,
Dolphin runs OpcodeDecoding in 1000-cycle time slices. In that time
frame, GXSetGPFifo() has probably completed and the GP read pointer now
points to entirely new memory. If the last GP fifo copy ended in an
incomplete command, the new GP fifo would most likely desync for a
while. To avoid all this, give the GP a time slice right now to copy the
remaining data from the previous GP fifo.
This commit is contained in:
Tillmann Karras 2024-10-10 00:29:21 +01:00
parent 7db13d23c9
commit e96960e2a6

View File

@ -594,22 +594,17 @@ void CommandProcessorManager::SetCpStatusRegister()
void CommandProcessorManager::SetCpControlRegister() void CommandProcessorManager::SetCpControlRegister()
{ {
if (m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable)
{
m_system.GetFifo().SyncGPUForRegisterAccess();
}
m_fifo.bFF_GPReadEnable.store(m_cp_ctrl_reg.GPReadEnable, std::memory_order_relaxed);
m_fifo.bFF_BPInt.store(m_cp_ctrl_reg.BPInt, std::memory_order_relaxed); m_fifo.bFF_BPInt.store(m_cp_ctrl_reg.BPInt, std::memory_order_relaxed);
m_fifo.bFF_BPEnable.store(m_cp_ctrl_reg.BPEnable, std::memory_order_relaxed); m_fifo.bFF_BPEnable.store(m_cp_ctrl_reg.BPEnable, std::memory_order_relaxed);
m_fifo.bFF_HiWatermarkInt.store(m_cp_ctrl_reg.FifoOverflowIntEnable, std::memory_order_relaxed); m_fifo.bFF_HiWatermarkInt.store(m_cp_ctrl_reg.FifoOverflowIntEnable, std::memory_order_relaxed);
m_fifo.bFF_LoWatermarkInt.store(m_cp_ctrl_reg.FifoUnderflowIntEnable, std::memory_order_relaxed); m_fifo.bFF_LoWatermarkInt.store(m_cp_ctrl_reg.FifoUnderflowIntEnable, std::memory_order_relaxed);
m_fifo.bFF_GPLinkEnable.store(m_cp_ctrl_reg.GPLinkEnable, std::memory_order_relaxed); m_fifo.bFF_GPLinkEnable.store(m_cp_ctrl_reg.GPLinkEnable, std::memory_order_relaxed);
if (m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) && !m_cp_ctrl_reg.GPReadEnable)
{
m_fifo.bFF_GPReadEnable.store(m_cp_ctrl_reg.GPReadEnable, std::memory_order_relaxed);
m_system.GetFifo().FlushGpu();
}
else
{
m_fifo.bFF_GPReadEnable = m_cp_ctrl_reg.GPReadEnable;
}
DEBUG_LOG_FMT(COMMANDPROCESSOR, "\t GPREAD {} | BP {} | Int {} | OvF {} | UndF {} | LINK {}", DEBUG_LOG_FMT(COMMANDPROCESSOR, "\t GPREAD {} | BP {} | Int {} | OvF {} | UndF {} | LINK {}",
m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) ? "ON" : "OFF", m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) ? "ON" : "OFF",
m_fifo.bFF_BPEnable.load(std::memory_order_relaxed) ? "ON" : "OFF", m_fifo.bFF_BPEnable.load(std::memory_order_relaxed) ? "ON" : "OFF",