diff --git a/Source/Core/Common/Src/VideoBackendBase.h b/Source/Core/Common/Src/VideoBackendBase.h index 0a83d127f2..2d2b71b79d 100644 --- a/Source/Core/Common/Src/VideoBackendBase.h +++ b/Source/Core/Common/Src/VideoBackendBase.h @@ -55,6 +55,7 @@ struct SCPFifoStruct // So no possiblity to ack the Token irq by the scheduler until some sort of PPC watchdog do its mess. volatile u16 PEToken; + volatile u32 bFF_GPLinkEnable; volatile u32 bFF_GPReadEnable; volatile u32 bFF_BPEnable; volatile u32 bFF_BPInt; @@ -113,7 +114,7 @@ public: static void Video_GatherPipeBursted(); virtual void Video_WaitForFrameFinish() = 0; - virtual bool Video_IsFifoBusy() = 0; + virtual bool Video_IsPossibleWaitingSetDrawDone() = 0; virtual void Video_AbortFrame() = 0; static void PopulateList(); @@ -145,7 +146,7 @@ class VideoBackendHLE : public VideoBackend void Video_SetRendering(bool bEnabled); void Video_WaitForFrameFinish(); - bool Video_IsFifoBusy(); + bool Video_IsPossibleWaitingSetDrawDone(); void Video_AbortFrame(); }; diff --git a/Source/Core/Core/Src/CoreTiming.cpp b/Source/Core/Core/Src/CoreTiming.cpp index 6bf967ff1e..c1b6b2225f 100644 --- a/Source/Core/Core/Src/CoreTiming.cpp +++ b/Source/Core/Core/Src/CoreTiming.cpp @@ -520,7 +520,7 @@ void Idle() //When the FIFO is processing data we must not advance 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. - while (g_video_backend->Video_IsFifoBusy()) + while (g_video_backend->Video_IsPossibleWaitingSetDrawDone()) { ProcessFifoWaitEvents(); Common::YieldCPU(); diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.cpp b/Source/Core/VideoCommon/Src/CommandProcessor.cpp index d19192db38..d2c746c400 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/Src/CommandProcessor.cpp @@ -111,7 +111,7 @@ static Common::CriticalSection sFifoCritical; static bool bProcessFifoToLoWatermark = false; static bool bProcessFifoAllDistance = false; -volatile bool isFifoBusy = false; //This state is changed when the FIFO is processing data. +volatile bool isPossibleWaitingSetDrawDone = false; //This state is changed when the FIFO is processing data. volatile bool interruptSet= false; volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; @@ -153,7 +153,7 @@ void DoState(PointerWrap &p) p.Do(bProcessFifoToLoWatermark); p.Do(bProcessFifoAllDistance); - p.Do(isFifoBusy); + p.Do(isPossibleWaitingSetDrawDone); p.Do(interruptSet); p.Do(interruptWaiting); p.Do(interruptTokenWaiting); @@ -477,6 +477,7 @@ void Write16(const u16 _Value, const u32 _Address) fifo.bFF_GPReadEnable = tmpCtrl.GPReadEnable; fifo.bFF_HiWatermarkInt = tmpCtrl.FifoOverflowIntEnable; fifo.bFF_LoWatermarkInt = tmpCtrl.FifoUnderflowIntEnable; + fifo.bFF_GPLinkEnable = tmpCtrl.GPLinkEnable; if(tmpCtrl.GPReadEnable && tmpCtrl.GPLinkEnable) { @@ -816,7 +817,7 @@ void SetFifoIdleFromVideoPlugin() void AbortFrame() { fifo.bFF_GPReadEnable = false; - s_fifoIdleEvent.Wait(); + while(IsFifoProcesingData()) Common::YieldCPU(); GPFifo::ResetGatherPipe(); ResetVideoBuffer(); fifo.CPReadPointer = fifo.CPWritePointer; diff --git a/Source/Core/VideoCommon/Src/CommandProcessor.h b/Source/Core/VideoCommon/Src/CommandProcessor.h index 720b43d81b..dc49cdf9fe 100644 --- a/Source/Core/VideoCommon/Src/CommandProcessor.h +++ b/Source/Core/VideoCommon/Src/CommandProcessor.h @@ -30,7 +30,7 @@ namespace CommandProcessor { 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. +extern volatile bool isPossibleWaitingSetDrawDone; //This one is used for sync gfx thread and emulator thread. extern volatile bool interruptSet; extern volatile bool interruptWaiting; extern volatile bool interruptTokenWaiting; diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 29c8b99c04..e8391c5f2f 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -33,6 +33,7 @@ namespace { static volatile bool fifoStateRun = false; static volatile bool EmuRunning = false; +static volatile bool isFifoProcesingData = false; static u8 *videoBuffer; // STATE_TO_SAVE static int size = 0; @@ -95,6 +96,11 @@ void Fifo_RunLoop(bool run) EmuRunning = run; } +bool IsFifoProcesingData() +{ + return isFifoProcesingData; +} + // Description: Fifo_EnterLoop() sends data through this function. void Fifo_SendFifoData(u8* _uData, u32 len) { @@ -142,9 +148,8 @@ void Fifo_EnterLoop() while (!CommandProcessor::interruptWaiting && _fifo.bFF_GPReadEnable && _fifo.CPReadWriteDistance && (!AtBreakpoint() || CommandProcessor::OnOverflow)) { - // while the FIFO is processing data we activate this for sync with emulator thread. - - CommandProcessor::isFifoBusy = true; + isFifoProcesingData = true; + CommandProcessor::isPossibleWaitingSetDrawDone = _fifo.bFF_GPLinkEnable; if (!fifoStateRun) break; @@ -180,9 +185,10 @@ void Fifo_EnterLoop() // If we don't, s_swapRequested 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_CheckAsyncRequest(); - CommandProcessor::isFifoBusy = false; + CommandProcessor::isPossibleWaitingSetDrawDone = false; } - + + isFifoProcesingData = false; CommandProcessor::SetFifoIdleFromVideoPlugin(); diff --git a/Source/Core/VideoCommon/Src/Fifo.h b/Source/Core/VideoCommon/Src/Fifo.h index 81bc3c1d09..c4470b7208 100644 --- a/Source/Core/VideoCommon/Src/Fifo.h +++ b/Source/Core/VideoCommon/Src/Fifo.h @@ -41,6 +41,7 @@ bool AtBreakpoint(); void Fifo_DoState(PointerWrap &f); void ResetVideoBuffer(); void Fifo_SetRendering(bool bEnabled); +bool IsFifoProcesingData(); // Implemented by the Video Plugin void VideoFifo_CheckAsyncRequest(); diff --git a/Source/Core/VideoCommon/Src/MainBase.cpp b/Source/Core/VideoCommon/Src/MainBase.cpp index 2a3f0b2564..e84f4356d5 100644 --- a/Source/Core/VideoCommon/Src/MainBase.cpp +++ b/Source/Core/VideoCommon/Src/MainBase.cpp @@ -240,9 +240,9 @@ void VideoBackendHLE::Video_WaitForFrameFinish() CommandProcessor::WaitForFrameFinish(); } -bool VideoBackendHLE::Video_IsFifoBusy() +bool VideoBackendHLE::Video_IsPossibleWaitingSetDrawDone() { - return CommandProcessor::isFifoBusy; + return CommandProcessor::isPossibleWaitingSetDrawDone; } void VideoBackendHLE::Video_AbortFrame() diff --git a/Source/Core/VideoCommon/Src/PixelEngine.cpp b/Source/Core/VideoCommon/Src/PixelEngine.cpp index cf7d0da83e..05fc65ae12 100644 --- a/Source/Core/VideoCommon/Src/PixelEngine.cpp +++ b/Source/Core/VideoCommon/Src/PixelEngine.cpp @@ -356,6 +356,7 @@ void SetFinish_OnMainThread(u64 userdata, int cyclesLate) g_bSignalFinishInterrupt = 1; UpdateInterrupts(); CommandProcessor::interruptFinishWaiting = false; + CommandProcessor::isPossibleWaitingSetDrawDone = false; } // SetToken diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp index 4ebc164250..902ed3c9be 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp +++ b/Source/Plugins/Plugin_VideoSoftware/Src/SWmain.cpp @@ -178,7 +178,7 @@ void VideoBackend::Video_WaitForFrameFinish(void) { } -bool VideoBackend::Video_IsFifoBusy(void) +bool VideoBackend::Video_IsPossibleWaitingSetDrawDone(void) { return false; } diff --git a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h index 2d77d85eb2..8430e681ff 100644 --- a/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h +++ b/Source/Plugins/Plugin_VideoSoftware/Src/VideoBackend.h @@ -36,7 +36,7 @@ class VideoBackend : public VideoBackendLLE void Video_SetRendering(bool bEnabled); void Video_WaitForFrameFinish(); - bool Video_IsFifoBusy(); + bool Video_IsPossibleWaitingSetDrawDone(); void Video_AbortFrame(); void UpdateFPSDisplay(const char*);