From e96960e2a678f072f316173c80650897013fb99c Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Thu, 10 Oct 2024 00:29:21 +0100 Subject: [PATCH] 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. --- Source/Core/VideoCommon/CommandProcessor.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 3f5179a726..69b52c5355 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -594,22 +594,17 @@ void CommandProcessorManager::SetCpStatusRegister() 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_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_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); - 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 {}", m_fifo.bFF_GPReadEnable.load(std::memory_order_relaxed) ? "ON" : "OFF", m_fifo.bFF_BPEnable.load(std::memory_order_relaxed) ? "ON" : "OFF",