From 86278642dcc80065297ba019d9adb60dbf11f868 Mon Sep 17 00:00:00 2001 From: Marcos Vitali Date: Thu, 10 Feb 2011 04:47:02 +0000 Subject: [PATCH] Experimental commit and one fix for my last commit. I think that isFifoBusy bring better sync with VI (video interface) because the CPU emulated threads are waiting for DrawDone in BP Register. So, I do some modifications. 1) Rename "IsFifoBusy" by "isPossibleWaitingSetDrawDone" 2) Only activate isPossibleWaitingSetDrawDone when bFF_GPLinkEnable is true in fifo loop "Inmediate mode" that is because in theory this drawsync function is using in this mode. 3) Deactivate isPossibleWaitingSetDrawDone also in SetFinish in PixelEngine, beside when 32 block is finish. Please regression in yours games thats can bring some FPS more above all with VPS frame limiter ON (Auto, 60, 50, etc). - Fix waiting in AbortFrame(), please test mp1/mp2 is fixed again. Good look! git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@7123 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/VideoBackendBase.h | 5 +++-- Source/Core/Core/Src/CoreTiming.cpp | 2 +- Source/Core/VideoCommon/Src/CommandProcessor.cpp | 7 ++++--- Source/Core/VideoCommon/Src/CommandProcessor.h | 2 +- Source/Core/VideoCommon/Src/Fifo.cpp | 16 +++++++++++----- Source/Core/VideoCommon/Src/Fifo.h | 1 + Source/Core/VideoCommon/Src/MainBase.cpp | 4 ++-- Source/Core/VideoCommon/Src/PixelEngine.cpp | 1 + .../Plugins/Plugin_VideoSoftware/Src/SWmain.cpp | 2 +- .../Plugin_VideoSoftware/Src/VideoBackend.h | 2 +- 10 files changed, 26 insertions(+), 16 deletions(-) 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*);