summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2015-03-05 21:14:46 +0100
committerdegasus <wickmarkus@web.de>2015-04-06 12:35:35 +0200
commitb020ae1c5db4e2e198d1beea91c75219a251a167 (patch)
treed9f7b069ffde368ecc0d47a5c2b0820f18bc2c80 /Source
parent9bdaa00e2dc18c06dcb9882d7f0caf372ed5990d (diff)
Fifo: rewrite sync on idle skipping hack
Now it's done without a busy loop
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/CoreTiming.cpp7
-rw-r--r--Source/Core/VideoBackends/Software/SWmain.cpp5
-rw-r--r--Source/Core/VideoBackends/Software/VideoBackend.h2
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.cpp17
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.h2
-rw-r--r--Source/Core/VideoCommon/Fifo.cpp26
-rw-r--r--Source/Core/VideoCommon/Fifo.h1
-rw-r--r--Source/Core/VideoCommon/MainBase.cpp4
-rw-r--r--Source/Core/VideoCommon/PixelEngine.cpp1
-rw-r--r--Source/Core/VideoCommon/VideoBackendBase.h4
10 files changed, 30 insertions, 39 deletions
diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp
index 5e75c27b05..d9872dcc3b 100644
--- a/Source/Core/Core/CoreTiming.cpp
+++ b/Source/Core/Core/CoreTiming.cpp
@@ -480,11 +480,8 @@ 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_IsPossibleWaitingSetDrawDone())
- {
- ProcessFifoWaitEvents();
- Common::YieldCPU();
- }
+ ProcessFifoWaitEvents();
+ g_video_backend->Video_Sync();
}
idledCycles += DowncountToCycles(PowerPC::ppcState.downcount);
diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp
index 497d26be00..784fe6d07b 100644
--- a/Source/Core/VideoBackends/Software/SWmain.cpp
+++ b/Source/Core/VideoBackends/Software/SWmain.cpp
@@ -360,11 +360,6 @@ void VideoSoftware::Video_GatherPipeBursted()
SWCommandProcessor::GatherPipeBursted();
}
-bool VideoSoftware::Video_IsPossibleWaitingSetDrawDone()
-{
- return false;
-}
-
void VideoSoftware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
{
SWCommandProcessor::RegisterMMIO(mmio, base);
diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h
index 0edb3bd4df..8697e27c98 100644
--- a/Source/Core/VideoBackends/Software/VideoBackend.h
+++ b/Source/Core/VideoBackends/Software/VideoBackend.h
@@ -45,7 +45,7 @@ class VideoSoftware : public VideoBackend
void Video_SetRendering(bool bEnabled) override;
void Video_GatherPipeBursted() override;
- bool Video_IsPossibleWaitingSetDrawDone() override;
+ void Video_Sync() override {}
void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;
diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp
index 21ef0be2a9..162e3a2d53 100644
--- a/Source/Core/VideoCommon/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/CommandProcessor.cpp
@@ -40,7 +40,6 @@ static u16 m_bboxright;
static u16 m_bboxbottom;
static u16 m_tokenReg;
-volatile bool isPossibleWaitingSetDrawDone = false;
volatile bool interruptSet= false;
volatile bool interruptWaiting= false;
volatile bool interruptTokenWaiting = false;
@@ -70,7 +69,6 @@ void DoState(PointerWrap &p)
p.Do(m_tokenReg);
p.Do(fifo);
- p.Do(isPossibleWaitingSetDrawDone);
p.Do(interruptSet);
p.Do(interruptWaiting);
p.Do(interruptTokenWaiting);
@@ -123,8 +121,6 @@ void Init()
interruptFinishWaiting = false;
interruptTokenWaiting = false;
- isPossibleWaitingSetDrawDone = false;
-
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
}
@@ -319,7 +315,7 @@ void GatherPipeBursted()
(ProcessorInterface::Fifo_CPUBase == fifo.CPBase) &&
fifo.CPReadWriteDistance > 0)
{
- ProcessFifoAllDistance();
+ FlushGpu();
}
}
RunGpu();
@@ -468,15 +464,6 @@ void SetCPStatusFromCPU()
}
}
-void ProcessFifoAllDistance()
-{
- if (IsOnThread())
- {
- while (!interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
- Common::YieldCPU();
- }
-}
-
void ProcessFifoEvents()
{
if (IsOnThread() && (interruptWaiting || interruptFinishWaiting || interruptTokenWaiting))
@@ -518,7 +505,7 @@ void SetCpControlRegister()
if (fifo.bFF_GPReadEnable && !m_CPCtrlReg.GPReadEnable)
{
fifo.bFF_GPReadEnable = m_CPCtrlReg.GPReadEnable;
- while (fifo.isGpuReadingData) Common::YieldCPU();
+ FlushGpu();
}
else
{
diff --git a/Source/Core/VideoCommon/CommandProcessor.h b/Source/Core/VideoCommon/CommandProcessor.h
index 0dad1578af..d25a5b7ef4 100644
--- a/Source/Core/VideoCommon/CommandProcessor.h
+++ b/Source/Core/VideoCommon/CommandProcessor.h
@@ -17,7 +17,6 @@ namespace CommandProcessor
extern SCPFifoStruct fifo; //This one is shared between 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;
@@ -145,7 +144,6 @@ void UpdateInterruptsFromVideoBackend(u64 userdata);
void SetCpClearRegister();
void SetCpControlRegister();
void SetCpStatusRegister();
-void ProcessFifoAllDistance();
void ProcessFifoEvents();
void Update();
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index 5f75deb672..0b65a56cd8 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -62,6 +62,9 @@ static u8* s_video_buffer_pp_read_ptr;
static Common::Flag s_gpu_is_running; // If this one is set, the gpu loop will be called at least once again
static Common::Event s_gpu_new_work_event;
+static Common::Flag s_gpu_is_pending; // If this one is set, there might still be work to do
+static Common::Event s_gpu_done_event;
+
void Fifo_DoState(PointerWrap &p)
{
p.DoArray(s_video_buffer, FIFO_SIZE);
@@ -85,7 +88,6 @@ void Fifo_PauseAndLock(bool doLock, bool unpauseOnUnlock)
EmulatorState(false);
if (!Core::IsGPUThread())
m_csHWVidOccupied.lock();
- _dbg_assert_(COMMON, !CommandProcessor::fifo.isGpuReadingData);
}
else
{
@@ -131,9 +133,8 @@ void ExitGpuLoop()
{
// This should break the wait loop in CPU thread
CommandProcessor::fifo.bFF_GPReadEnable = false;
- SCPFifoStruct &fifo = CommandProcessor::fifo;
- while (fifo.isGpuReadingData)
- Common::YieldCPU();
+ FlushGpu();
+
// Terminate GPU thread loop
GpuRunningState = false;
EmuRunningState = true;
@@ -317,7 +318,6 @@ void RunGpuLoop()
while (GpuRunningState && EmuRunningState && run_loop && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
{
fifo.isGpuReadingData = true;
- CommandProcessor::isPossibleWaitingSetDrawDone = fifo.bFF_GPLinkEnable ? true : false;
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU || Common::AtomicLoad(CommandProcessor::VITicks) > CommandProcessor::m_cpClockOrigin)
{
@@ -356,18 +356,21 @@ void RunGpuLoop()
// 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.
AsyncRequests::GetInstance()->PullEvents();
- CommandProcessor::isPossibleWaitingSetDrawDone = false;
}
// don't release the GPU running state on sync GPU waits
fifo.isGpuReadingData = !run_loop;
}
+ s_gpu_is_pending.Clear();
+ s_gpu_done_event.Set();
+
if (EmuRunningState)
{
if (s_gpu_is_running.IsSet())
{
// reset the atomic flag. But as the CPU thread might have pushed some new data, we have to rerun the GPU loop
+ s_gpu_is_pending.Set();
s_gpu_is_running.Clear();
}
else
@@ -393,6 +396,16 @@ void RunGpuLoop()
AsyncRequests::GetInstance()->SetPassthrough(true);
}
+void FlushGpu()
+{
+ if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread || g_use_deterministic_gpu_thread)
+ return;
+
+ while (s_gpu_is_running.IsSet() || s_gpu_is_pending.IsSet())
+ {
+ s_gpu_done_event.Wait();
+ }
+}
bool AtBreakpoint()
{
@@ -437,6 +450,7 @@ void RunGpu()
// wake up GPU thread
if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread && !s_gpu_is_running.IsSet())
{
+ s_gpu_is_pending.Set();
s_gpu_is_running.Set();
s_gpu_new_work_event.Set();
}
diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h
index 8cec0d824d..f8b4b5f625 100644
--- a/Source/Core/VideoCommon/Fifo.h
+++ b/Source/Core/VideoCommon/Fifo.h
@@ -41,6 +41,7 @@ void SyncGPU(SyncGPUReason reason, bool may_move_read_ptr = true);
void PushFifoAuxBuffer(void* ptr, size_t size);
void* PopFifoAuxBuffer(size_t size);
+void FlushGpu();
void RunGpu();
void RunGpuLoop();
void ExitGpuLoop();
diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp
index a8af71b31e..102e17db34 100644
--- a/Source/Core/VideoCommon/MainBase.cpp
+++ b/Source/Core/VideoCommon/MainBase.cpp
@@ -233,9 +233,9 @@ void VideoBackendHardware::Video_GatherPipeBursted()
CommandProcessor::GatherPipeBursted();
}
-bool VideoBackendHardware::Video_IsPossibleWaitingSetDrawDone()
+void VideoBackendHardware::Video_Sync()
{
- return CommandProcessor::isPossibleWaitingSetDrawDone;
+ FlushGpu();
}
void VideoBackendHardware::RegisterCPMMIO(MMIO::Mapping* mmio, u32 base)
diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp
index afe08c7d0a..da086924b1 100644
--- a/Source/Core/VideoCommon/PixelEngine.cpp
+++ b/Source/Core/VideoCommon/PixelEngine.cpp
@@ -287,7 +287,6 @@ void SetFinish_OnMainThread(u64 userdata, int cyclesLate)
Common::AtomicStore(*(volatile u32*)&g_bSignalFinishInterrupt, 1);
UpdateInterrupts();
CommandProcessor::interruptFinishWaiting = false;
- CommandProcessor::isPossibleWaitingSetDrawDone = false;
}
// SetToken
diff --git a/Source/Core/VideoCommon/VideoBackendBase.h b/Source/Core/VideoCommon/VideoBackendBase.h
index 4796a29b07..9aa6208e52 100644
--- a/Source/Core/VideoCommon/VideoBackendBase.h
+++ b/Source/Core/VideoCommon/VideoBackendBase.h
@@ -99,7 +99,7 @@ public:
virtual void Video_GatherPipeBursted() = 0;
- virtual bool Video_IsPossibleWaitingSetDrawDone() = 0;
+ virtual void Video_Sync() = 0;
// Registers MMIO handlers for the CommandProcessor registers.
virtual void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) = 0;
@@ -148,7 +148,7 @@ class VideoBackendHardware : public VideoBackend
void Video_GatherPipeBursted() override;
- bool Video_IsPossibleWaitingSetDrawDone() override;
+ void Video_Sync() override;
void RegisterCPMMIO(MMIO::Mapping* mmio, u32 base) override;