From 86f2b39d660673bb3ae993dc2d71e34b36880e98 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 11 Dec 2021 17:33:35 -0800 Subject: [PATCH] FifoPlayer: Wait after clearing the screen If we don't wait, then the copy will be performed at a later time, which may overwrite memory updates. --- Source/Core/Core/FifoPlayer/FifoPlayer.cpp | 25 ++++++++++++++++------ Source/Core/Core/FifoPlayer/FifoPlayer.h | 1 + 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index 0d1887cd82..e579ae547f 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -214,6 +214,9 @@ public: void Init() override { IsPlayingBackFifologWithBrokenEFBCopies = m_parent->m_File->HasBrokenEFBCopies(); + // Without this call, we deadlock in initialization in dual core, as the FIFO is disabled and + // thus ClearEfb()'s call to WaitForGPUInactive() never returns + CPU::EnableStepping(false); m_parent->m_CurrentFrame = m_parent->m_FrameRangeStart; m_parent->LoadMemory(); @@ -422,13 +425,7 @@ void FifoPlayer::WriteFrame(const FifoFrameInfo& frame, const AnalyzedFrameInfo& } FlushWGP(); - - // Sleep while the GPU is active - while (!IsIdleSet() && CPU::GetState() != CPU::State::PowerDown) - { - CoreTiming::Idle(); - CoreTiming::Advance(); - } + WaitForGPUInactive(); } void FifoPlayer::WriteFramePart(const FramePart& part, u32* next_mem_update, @@ -603,6 +600,10 @@ void FifoPlayer::ClearEfb() LoadBPReg(BPMEM_EFB_WH, m_File->GetBPMem()[BPMEM_EFB_WH]); LoadBPReg(BPMEM_MIPMAP_STRIDE, m_File->GetBPMem()[BPMEM_MIPMAP_STRIDE]); LoadBPReg(BPMEM_EFB_ADDR, m_File->GetBPMem()[BPMEM_EFB_ADDR]); + // Wait for the EFB copy to finish. That way, the EFB copy (which will be performed at a later + // time) won't clobber any memory updates. + FlushWGP(); + WaitForGPUInactive(); } void FifoPlayer::LoadMemory() @@ -695,6 +696,16 @@ void FifoPlayer::FlushWGP() GPFifo::ResetGatherPipe(); } +void FifoPlayer::WaitForGPUInactive() +{ + // Sleep while the GPU is active + while (!IsIdleSet() && CPU::GetState() != CPU::State::PowerDown) + { + CoreTiming::Idle(); + CoreTiming::Advance(); + } +} + void FifoPlayer::LoadBPReg(u8 reg, u32 value) { GPFifo::Write8(0x61); // load BP reg diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.h b/Source/Core/Core/FifoPlayer/FifoPlayer.h index 4e2e0ffed7..af19bac944 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.h +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.h @@ -159,6 +159,7 @@ private: void WritePI(u32 address, u32 value); void FlushWGP(); + void WaitForGPUInactive(); void LoadBPReg(u8 reg, u32 value); void LoadCPReg(u8 reg, u32 value);