diff options
| author | Marcos Vitali <marcosvitali@gmail.com> | 2010-06-24 13:28:54 +0000 |
|---|---|---|
| committer | Marcos Vitali <marcosvitali@gmail.com> | 2010-06-24 13:28:54 +0000 |
| commit | 10b5d2371c97c63cf12b3d88bdd40b341c4fa8ac (patch) | |
| tree | e0e6562b985c5572fd84bbb0cd0d6789d2dc5cf3 /Source/Core/VideoCommon | |
| parent | 2faae384b3c265d1538be08e785f9f6ac73257de (diff) | |
My first commit :D
Dual Core sync fix.
When the FIFO is processing data we must not advance the cpu cycles in CoreTiming because in this way the VI will be desynchronized. So, We are waiting until the FIFO finish and while we process only the events required by the FIFO.
This should fix Issue 2072 .
This affect to all games in dual core mode.
Please, You can test all games with VPS limiter auto, 60, 50 depending of the game and compare with prev revision.
For example now NSMB in the video Intro has 60 fps (prev 30 fps) :D or SMG does't need anymore FPS Limitter Hack to get 55-60 fps
Beside the slowdowns now are more softly and the fps more stables because the VI sync is almost perfect.
The Core Timing and Fifo modifications are delicated. Please report if this hang any game. Don't forget check with prev revision.
Enjoy it! Thanks to Rodolfo for teach me all about dolphin.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5777 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/VideoCommon')
| -rw-r--r-- | Source/Core/VideoCommon/Src/CommandProcessor.cpp | 8 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/CommandProcessor.h | 5 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/Fifo.cpp | 13 | ||||
| -rw-r--r-- | Source/Core/VideoCommon/Src/PixelEngine.cpp | 4 |
4 files changed, 21 insertions, 9 deletions
diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index c59f9b7b40..21c9919393 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -110,6 +110,8 @@ static u32 fake_GPWatchdogLastToken = 0; static Common::EventEx s_fifoIdleEvent; static Common::CriticalSection sFifoCritical; +volatile bool isFifoBusy = false; //This state is changed when the FIFO is processing data. + void FifoCriticalEnter() { sFifoCritical.Enter(); @@ -597,8 +599,8 @@ void STACKALIGN GatherPipeBursted() if (g_VideoInitialize.bOnThread) { // A little trick to prevent FIFO from overflown in dual core mode (n < 100 to avoid dead lock) - for (int cnt = 0; fifo.CPReadWriteDistance > fifo.CPEnd - fifo.CPBase && cnt < 100; cnt++) - Common::SwitchCurrentThread(); + //for (int cnt = 0; fifo.CPReadWriteDistance > fifo.CPEnd - fifo.CPBase && cnt < 100; cnt++) + // Common::SwitchCurrentThread(); } else { @@ -683,7 +685,7 @@ void UpdateInterrupts() void UpdateInterruptsFromVideoPlugin() { - g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0); + g_VideoInitialize.pScheduleEvent_Threadsafe(0, et_UpdateInterrupts, 0, true); } void SetFifoIdleFromVideoPlugin() diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h index 40771ecb54..4c29d46ca6 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.h +++ b/Source/Core/VideoCommon/Src/CommandProcessor.h @@ -25,11 +25,12 @@ class PointerWrap; extern bool MT; + namespace CommandProcessor { -extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread - +extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread. +extern volatile bool isFifoBusy; //This one is used for sync gfx thread and emulator thread. // internal hardware addresses enum { diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index ab8bf897c2..166d7a027f 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -147,9 +147,13 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) VideoFifo_CheckEFBAccess(); VideoFifo_CheckSwapRequest(); - // check if we are able to run this buffer + // check if we are able to run this buffer + while (_fifo.bFF_GPReadEnable && _fifo.CPReadWriteDistance) { + // while the FIFO is processing data we activate this for sync with emulator thread. + CommandProcessor::isFifoBusy = true; + if (!fifoStateRun) break; @@ -170,6 +174,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) if (_fifo.bFF_BPInt) CommandProcessor::UpdateInterruptsFromVideoPlugin(); CommandProcessor::FifoCriticalLeave(); + CommandProcessor::isFifoBusy = false; break; } @@ -205,15 +210,19 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) // Those two are pretty important and must be called in the FIFO Loop. // If we don't, s_swapRequested (OGL only) or s_efbAccessRequested won't be set to false // leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down. + VideoFifo_CheckEFBAccess(); VideoFifo_CheckSwapRequest(); + CommandProcessor::isFifoBusy = false; } - + + if (!_fifo.CPReadIdle && _fifo.CPReadWriteDistance < _fifo.CPLoWatermark) { Common::AtomicStore(_fifo.CPReadIdle, true); CommandProcessor::UpdateInterruptsFromVideoPlugin(); } + _fifo.CPCmdIdle = true; CommandProcessor::SetFifoIdleFromVideoPlugin(); if (EmuRunning) diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index 920041912b..8bfe6a314e 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -354,7 +354,7 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge) // This seems smelly... CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack since PEToken seems to be a frame-finish too g_VideoInitialize.pScheduleEvent_Threadsafe( - 0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16)); + 0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16), true); } else // set token value { @@ -373,7 +373,7 @@ void SetFinish() { CommandProcessor::IncrementGPWDToken(); // for DC watchdog hack g_VideoInitialize.pScheduleEvent_Threadsafe( - 0, et_SetFinishOnMainThread, 0); + 0, et_SetFinishOnMainThread, 0, true); INFO_LOG(PIXELENGINE, "VIDEO Set Finish"); } |
