From d981944d7cad89841af60d9cc36b59ede6a089c1 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Thu, 23 Dec 2021 12:33:28 -0800 Subject: [PATCH 1/2] FifoPlayer: Fix uninitialized variable warnings in ClearEfb The actual values don't matter since we overwrite all of the relevant fields, but other bits were not initialized (e.g. the top 12 bits of X10Y10), so the warning was semi-valid. --- Source/Core/Core/FifoPlayer/FifoPlayer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp index 58add3faaa..0d1887cd82 100644 --- a/Source/Core/Core/FifoPlayer/FifoPlayer.cpp +++ b/Source/Core/Core/FifoPlayer/FifoPlayer.cpp @@ -571,18 +571,18 @@ void FifoPlayer::ClearEfb() // Trigger a bogus EFB copy to clear the screen // The target address is 0, and there shouldn't be anything there, // but even if there is it should be loaded in by LoadTextureMemory afterwards - X10Y10 tl; + X10Y10 tl = bpmem.copyTexSrcXY; tl.x = 0; tl.y = 0; LoadBPReg(BPMEM_EFB_TL, tl.hex); - X10Y10 wh; + X10Y10 wh = bpmem.copyTexSrcWH; wh.x = EFB_WIDTH - 1; wh.y = EFB_HEIGHT - 1; LoadBPReg(BPMEM_EFB_WH, wh.hex); LoadBPReg(BPMEM_MIPMAP_STRIDE, 0x140); // The clear color and Z value have already been loaded via LoadRegisters() LoadBPReg(BPMEM_EFB_ADDR, 0); - UPE_Copy copy; + UPE_Copy copy = bpmem.triggerEFBCopy; copy.clamp_top = false; copy.clamp_bottom = false; copy.yuv = false; From 86f2b39d660673bb3ae993dc2d71e34b36880e98 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sat, 11 Dec 2021 17:33:35 -0800 Subject: [PATCH 2/2] 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);