From fb35a83d2c9b81a7c745e09e6c25a7770f80f442 Mon Sep 17 00:00:00 2001 From: Marcos Vitali Date: Sat, 29 Jan 2011 20:04:16 +0000 Subject: [PATCH] - Fixed Metroid Prime 2 "GFX FIFO: Unknown Opcode (0x%x).\n" This was happened because FIFO_RESET is executed, but at this moment the Write Gather Pipe is not empty. (maybe also fix the same problem reported in MP1, i dont have this game for testing) - Reimplemented AbortFrame. Now the Write Gather Pipe buffer is reseted and Read Write Distances is reseted before the game do it instead the process all GP CPRWDistance for prevent CP wrong pointers. This fifo reset should be more accurate, efficient and smooth the FPS when happens. Please, test regresion of SMG1 and SMG2 or others games with FIFO RESETS. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6971 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/Core.cpp | 1 + .../Core/VideoCommon/Src/CommandProcessor.cpp | 14 +++++++++---- Source/Core/VideoCommon/Src/Fifo.cpp | 20 ++++++++----------- Source/PluginSpecs/pluginspecs_video.h | 2 ++ 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Source/Core/Core/Src/Core.cpp b/Source/Core/Core/Src/Core.cpp index f5b2be9c0b..81ffe4ba99 100644 --- a/Source/Core/Core/Src/Core.cpp +++ b/Source/Core/Core/Src/Core.cpp @@ -349,6 +349,7 @@ void EmuThread() VideoInitialize.pUpdateFPSDisplay = NULL; VideoInitialize.pMemoryBase = Memory::base; VideoInitialize.pCoreMessage = Callback_CoreMessage; + VideoInitialize.pResetGatherPipe = GPFifo::ResetGatherPipe; VideoInitialize.bWii = _CoreParameter.bWii; VideoInitialize.bOnThread = _CoreParameter.bCPUThread; VideoInitialize.Fifo_CPUBase = &ProcessorInterface::Fifo_CPUBase; diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index 9e625ce3f1..14187548f4 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -805,10 +805,16 @@ void SetFifoIdleFromVideoPlugin() // to 0 when PI_FIFO_RESET occurs. void AbortFrame() { - - Fifo_SetRendering(false); - ProcessFifoAllDistance(); - Fifo_SetRendering(true); + g_VideoInitialize.pResetGatherPipe(); + fifo.bFF_GPReadEnable = false; + while (CommandProcessor::isFifoBusy) + Common::YieldCPU(); + g_VideoInitialize.pResetGatherPipe(); + fifo.CPReadPointer = fifo.CPWritePointer; + fifo.CPReadWriteDistance = 0; + fifo.CPBreakpoint = 0; + fifo.bFF_Breakpoint = false; + fifo.CPCmdIdle = false; PixelEngine::ResetSetToken(); PixelEngine::ResetSetFinish(); } diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index ad5bec1d71..3aa6ec1fbc 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -154,6 +154,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) { // while the FIFO is processing data we activate this for sync with emulator thread. + CommandProcessor::isFifoBusy = true; if (!fifoStateRun) break; @@ -173,22 +174,16 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) _assert_msg_(COMMANDPROCESSOR, (s32)_fifo.CPReadWriteDistance - distToSend >= 0 , "Negative fifo.CPReadWriteDistance = %i in FIFO Loop !\nThat can produce inestabilty in the game. Please report it.", _fifo.CPReadWriteDistance - distToSend); - // Execute new instructions found in uData - Fifo_SendFifoData(uData, distToSend); + Fifo_SendFifoData(uData, distToSend); + + OpcodeDecoder_Run(g_bSkipCurrentFrame); + Common::AtomicStore(_fifo.CPReadPointer, readPtr); Common::AtomicAdd(_fifo.CPReadWriteDistance, -distToSend); - - CommandProcessor::isFifoBusy = true; + CommandProcessor::SetStatus(); - - _fifo.CPCmdIdle = false; - OpcodeDecoder_Run(g_bSkipCurrentFrame); - - _fifo.CPCmdIdle = true; - - CommandProcessor::isFifoBusy = false; CommandProcessor::FifoCriticalLeave(); // Those two are pretty important and must be called in the FIFO Loop. @@ -198,7 +193,8 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) VideoFifo_CheckAsyncRequest(); } - + + CommandProcessor::isFifoBusy = false; CommandProcessor::SetFifoIdleFromVideoPlugin(); if (EmuRunning) diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index 32b0954048..d337374c02 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -25,6 +25,7 @@ typedef void (*TCopiedToXFB)(bool video_update); typedef unsigned int (*TPeekMessages)(void); typedef void (*TUpdateFPSDisplay)(const char* text); // sets the window title typedef void (*TCoreMessage)(int Id); // passes message to the core +typedef void (*TResetGatherPipe)(void); enum FieldType { @@ -94,6 +95,7 @@ typedef struct TPeekMessages pPeekMessages; TUpdateFPSDisplay pUpdateFPSDisplay; TCoreMessage pCoreMessage; + TResetGatherPipe pResetGatherPipe; void *pMemoryBase; bool bWii; bool bOnThread;