Fixed Issue 1921

This also fixed Ikaruga, not sure whether it could fix Metriod Prime. If not, how about disabling EFB copy?

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4777 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
ayuanx 2010-01-03 16:04:40 +00:00
parent ad594abe69
commit a3c258cf9c
3 changed files with 36 additions and 14 deletions

View File

@ -381,8 +381,11 @@ void Write16(const u16 _Value, const u32 _Address)
DEBUG_LOG(COMMANDPROCESSOR, "*********************** GXSetGPFifo very soon? ***********************"); DEBUG_LOG(COMMANDPROCESSOR, "*********************** GXSetGPFifo very soon? ***********************");
// (mb2) We don't sleep here since it could be a perf issue for super monkey ball (yup only this game IIRC) // (mb2) We don't sleep here since it could be a perf issue for super monkey ball (yup only this game IIRC)
// Touching that game is a no-go so I don't want to take the risk :p // Touching that game is a no-go so I don't want to take the risk :p
while (fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !fifo.bFF_Breakpoint) while (fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
{
Fifo_RunLoop();
s_fifoIdleEvent.MsgWait(); s_fifoIdleEvent.MsgWait();
}
} }
} }
@ -411,6 +414,8 @@ void Write16(const u16 _Value, const u32 _Address)
Common::AtomicStore(fifo.bFF_Breakpoint, 0); Common::AtomicStore(fifo.bFF_Breakpoint, 0);
} }
Fifo_RunLoop();
DEBUG_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value); DEBUG_LOG(COMMANDPROCESSOR,"\t write to CTRL_REGISTER : %04x", _Value);
DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | LINK %s | BP %s || Init %s | OvF %s | UndF %s" DEBUG_LOG(COMMANDPROCESSOR, "\t GPREAD %s | LINK %s | BP %s || Init %s | OvF %s | UndF %s"
, fifo.bFF_GPReadEnable ? "ON" : "OFF" , fifo.bFF_GPReadEnable ? "ON" : "OFF"
@ -566,7 +571,10 @@ bool AllowIdleSkipping()
void WaitForFrameFinish() void WaitForFrameFinish()
{ {
while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint))); while ((fake_GPWatchdogLastToken == fifo.Fake_GPWDToken) && fifo.bFF_GPReadEnable && ((!fifo.bFF_BPEnable && fifo.CPReadWriteDistance) || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)));
{
Fifo_RunLoop();
s_fifoIdleEvent.MsgWait(); s_fifoIdleEvent.MsgWait();
}
fake_GPWatchdogLastToken = fifo.Fake_GPWDToken; fake_GPWatchdogLastToken = fifo.Fake_GPWDToken;
} }
@ -586,6 +594,7 @@ void STACKALIGN GatherPipeBursted()
fifo.CPWritePointer += GATHER_PIPE_SIZE; fifo.CPWritePointer += GATHER_PIPE_SIZE;
Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE); Common::AtomicAdd(fifo.CPReadWriteDistance, GATHER_PIPE_SIZE);
Fifo_RunLoop();
// High watermark overflow handling (hacked way) // High watermark overflow handling (hacked way)
if (fifo.CPReadWriteDistance > fifo.CPHiWatermark) if (fifo.CPReadWriteDistance > fifo.CPHiWatermark)
@ -608,8 +617,11 @@ void STACKALIGN GatherPipeBursted()
INFO_LOG(COMMANDPROCESSOR, "(GatherPipeBursted): CPHiWatermark (Hi: 0x%04x, Lo: 0x%04x) reached (RWDistance: 0x%04x)", fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance); INFO_LOG(COMMANDPROCESSOR, "(GatherPipeBursted): CPHiWatermark (Hi: 0x%04x, Lo: 0x%04x) reached (RWDistance: 0x%04x)", fifo.CPHiWatermark, fifo.CPLoWatermark, fifo.CPReadWriteDistance);
// Wait for GPU to catch up // Wait for GPU to catch up
while (fifo.CPReadWriteDistance > fifo.CPLoWatermark && !fifo.bFF_Breakpoint) while (fifo.CPReadWriteDistance > fifo.CPLoWatermark && fifo.bFF_GPReadEnable && (!fifo.bFF_BPEnable || (fifo.bFF_BPEnable && !fifo.bFF_Breakpoint)))
{
Fifo_RunLoop();
s_fifoIdleEvent.MsgWait(); s_fifoIdleEvent.MsgWait();
}
} }
// check if we are in sync // check if we are in sync
_assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == *(g_VideoInitialize.Fifo_CPUWritePointer), "FIFOs linked but out of sync"); _assert_msg_(COMMANDPROCESSOR, fifo.CPWritePointer == *(g_VideoInitialize.Fifo_CPUWritePointer), "FIFOs linked but out of sync");
@ -649,7 +661,9 @@ void CatchUpGPU()
{ {
if ( if (
(fifo.CPReadPointer == fifo.CPBreakpoint) || (fifo.CPReadPointer == fifo.CPBreakpoint) ||
(fifo.CPReadPointer == fifo.CPWritePointer) || //(fifo.CPReadPointer <= fifo.CPBreakpoint && fifo.CPReadPointer + 32 > fifo.CPBreakpoint) ||
(fifo.CPReadPointer <= fifo.CPWritePointer && fifo.CPWritePointer < fifo.CPBreakpoint) ||
(fifo.CPReadPointer <= fifo.CPWritePointer && fifo.CPReadPointer > fifo.CPBreakpoint) ||
(fifo.CPReadPointer > fifo.CPBreakpoint && fifo.CPBreakpoint > fifo.CPWritePointer) (fifo.CPReadPointer > fifo.CPBreakpoint && fifo.CPBreakpoint > fifo.CPWritePointer)
) )
{ {
@ -711,6 +725,7 @@ void UpdateFifoRegister()
dist = (wp - fifo.CPBase) + ((fifo.CPEnd + GATHER_PIPE_SIZE) - rp); dist = (wp - fifo.CPBase) + ((fifo.CPEnd + GATHER_PIPE_SIZE) - rp);
Common::AtomicStore(fifo.CPReadWriteDistance, dist); Common::AtomicStore(fifo.CPReadWriteDistance, dist);
Fifo_RunLoop();
if (!g_VideoInitialize.bOnThread) if (!g_VideoInitialize.bOnThread)
CatchUpGPU(); CatchUpGPU();

View File

@ -35,7 +35,7 @@ namespace
{ {
static volatile bool fifoStateRun = false; static volatile bool fifoStateRun = false;
static u8 *videoBuffer; static u8 *videoBuffer;
static Common::Event fifo_exit_event; static Common::Event fifo_run_event;
// STATE_TO_SAVE // STATE_TO_SAVE
static int size = 0; static int size = 0;
} // namespace } // namespace
@ -56,14 +56,14 @@ void Fifo_DoState(PointerWrap &p)
void Fifo_Init() void Fifo_Init()
{ {
videoBuffer = (u8*)AllocateMemoryPages(FIFO_SIZE); videoBuffer = (u8*)AllocateMemoryPages(FIFO_SIZE);
fifo_exit_event.Init(); fifo_run_event.Init();
fifoStateRun = false; fifoStateRun = false;
} }
void Fifo_Shutdown() void Fifo_Shutdown()
{ {
if (fifoStateRun) if (fifoStateRun) PanicAlert("Fifo shutting down while active");
PanicAlert("Fifo shutting down while active"); fifo_run_event.Shutdown();
FreeMemoryPages(videoBuffer, FIFO_SIZE); FreeMemoryPages(videoBuffer, FIFO_SIZE);
} }
@ -89,10 +89,7 @@ void Fifo_SetRendering(bool enabled)
// the loop. Switch to the video thread and investigate. // the loop. Switch to the video thread and investigate.
void Fifo_ExitLoop() void Fifo_ExitLoop()
{ {
fifoStateRun = false; Fifo_ExitLoopNonBlocking();
fifo_exit_event.MsgWait();
fifo_exit_event.Shutdown();
} }
// May be executed from any thread, even the graphics thread. // May be executed from any thread, even the graphics thread.
@ -100,6 +97,12 @@ void Fifo_ExitLoop()
void Fifo_ExitLoopNonBlocking() void Fifo_ExitLoopNonBlocking()
{ {
fifoStateRun = false; fifoStateRun = false;
fifo_run_event.Set();
}
void Fifo_RunLoop()
{
fifo_run_event.Set();
} }
// Description: Fifo_EnterLoop() sends data through this function. // Description: Fifo_EnterLoop() sends data through this function.
@ -156,7 +159,9 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
// so careful check is required // so careful check is required
if ( if (
(readPtr == _fifo.CPBreakpoint) || (readPtr == _fifo.CPBreakpoint) ||
(readPtr == _fifo.CPWritePointer) || //(readPtr <= _fifo.CPBreakpoint && readPtr + 32 > _fifo.CPBreakpoint) ||
(readPtr <= _fifo.CPWritePointer && _fifo.CPWritePointer < _fifo.CPBreakpoint) ||
(readPtr <= _fifo.CPWritePointer && readPtr > _fifo.CPBreakpoint) ||
(readPtr > _fifo.CPBreakpoint && _fifo.CPBreakpoint > _fifo.CPWritePointer) (readPtr > _fifo.CPBreakpoint && _fifo.CPBreakpoint > _fifo.CPWritePointer)
) )
{ {
@ -200,11 +205,12 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize)
// leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down. // leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down.
VideoFifo_CheckEFBAccess(); VideoFifo_CheckEFBAccess();
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
CommandProcessor::SetFifoIdleFromVideoPlugin();
} }
CommandProcessor::SetFifoIdleFromVideoPlugin(); CommandProcessor::SetFifoIdleFromVideoPlugin();
Common::YieldCPU(); fifo_run_event.MsgWait();
} }
fifo_exit_event.Set();
} }

View File

@ -36,6 +36,7 @@ void Fifo_SendFifoData(u8* _uData, u32 len);
void Fifo_EnterLoop(const SVideoInitialize &video_initialize); void Fifo_EnterLoop(const SVideoInitialize &video_initialize);
void Fifo_ExitLoop(); void Fifo_ExitLoop();
void Fifo_ExitLoopNonBlocking(); void Fifo_ExitLoopNonBlocking();
void Fifo_RunLoop();
void Fifo_DoState(PointerWrap &f); void Fifo_DoState(PointerWrap &f);