- 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
This commit is contained in:
Marcos Vitali 2011-01-29 20:04:16 +00:00
parent a767de8e09
commit fb35a83d2c
4 changed files with 21 additions and 16 deletions

View File

@ -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;

View File

@ -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();
}

View File

@ -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)

View File

@ -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;