summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2016-01-19 00:08:18 +0100
committerdegasus <wickmarkus@web.de>2016-01-24 11:06:01 +0100
commitcf4478dc925b4c20a341bb29ea78a4be4054bcb1 (patch)
tree3df00f71b52bc2aa0e8a4692ab7b1c9335340d78 /Source/Core
parentaa39b0dab1bf435df690a5a8d41338824dacba53 (diff)
Fifo: Fix SyncGPU.
CBoot::BootUp() did call CoreTiming::Advance which itself blocks on the GPU, but the GPU thread wasn't started already. This commit moves the SyncGPU initialization into the Fifo.cpp file and call it after BootUp().
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/Core.cpp3
-rw-r--r--Source/Core/Core/CoreTiming.cpp2
-rw-r--r--Source/Core/Core/HW/SystemTimers.cpp17
-rw-r--r--Source/Core/VideoCommon/Fifo.cpp33
-rw-r--r--Source/Core/VideoCommon/Fifo.h2
5 files changed, 31 insertions, 26 deletions
diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp
index ee7e1141d7..d8af296679 100644
--- a/Source/Core/Core/Core.cpp
+++ b/Source/Core/Core/Core.cpp
@@ -498,6 +498,9 @@ void EmuThread()
CBoot::BootUp();
+ // This adds the SyncGPU handler to CoreTiming, so now CoreTiming::Advance might block.
+ Fifo::Prepare();
+
// Thread is no longer acting as CPU Thread
UndeclareAsCPUThread();
diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp
index 6a1c76b186..59d40727ae 100644
--- a/Source/Core/Core/CoreTiming.cpp
+++ b/Source/Core/Core/CoreTiming.cpp
@@ -446,7 +446,7 @@ void Idle()
//the VI will be desynchronized. So, We are waiting until the FIFO finish and
//while we process only the events required by the FIFO.
ProcessFifoWaitEvents();
- Fifo::Update(0);
+ Fifo::FlushGpu();
}
idledCycles += DowncountToCycles(PowerPC::ppcState.downcount);
diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp
index 82e6962bf2..e900e33762 100644
--- a/Source/Core/Core/HW/SystemTimers.cpp
+++ b/Source/Core/Core/HW/SystemTimers.cpp
@@ -66,7 +66,6 @@ namespace SystemTimers
static int et_Dec;
static int et_VI;
-static int et_CP;
static int et_AudioDMA;
static int et_DSP;
static int et_IPC_HLE;
@@ -74,7 +73,6 @@ static int et_PatchEngine; // PatchEngine updates every 1/60th of a second by de
static int et_Throttle;
static u32 s_cpu_core_clock = 486000000u; // 486 mhz (its not 485, stop bugging me!)
-static u64 s_last_sync_gpu_tick;
// These two are badly educated guesses.
// Feel free to experiment. Set them in Init below.
@@ -123,16 +121,6 @@ static void VICallback(u64 userdata, int cyclesLate)
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerHalfLine() - cyclesLate, et_VI);
}
-static void CPCallback(u64 userdata, int cyclesLate)
-{
- u64 now = CoreTiming::GetTicks();
- int next = Fifo::Update((int)(now - s_last_sync_gpu_tick));
- s_last_sync_gpu_tick = now;
-
- if (next > 0)
- CoreTiming::ScheduleEvent(next, et_CP);
-}
-
static void DecrementerCallback(u64 userdata, int cyclesLate)
{
PowerPC::ppcState.spr[SPR_DEC] = 0xFFFFFFFF;
@@ -238,8 +226,6 @@ void Init()
et_Dec = CoreTiming::RegisterEvent("DecCallback", DecrementerCallback);
et_VI = CoreTiming::RegisterEvent("VICallback", VICallback);
- if (SConfig::GetInstance().bCPUThread && SConfig::GetInstance().bSyncGPU)
- et_CP = CoreTiming::RegisterEvent("CPCallback", CPCallback);
et_DSP = CoreTiming::RegisterEvent("DSPCallback", DSPCallback);
et_AudioDMA = CoreTiming::RegisterEvent("AudioDMACallback", AudioDMACallback);
et_IPC_HLE = CoreTiming::RegisterEvent("IPC_HLE_UpdateCallback", IPC_HLE_UpdateCallback);
@@ -250,9 +236,6 @@ void Init()
CoreTiming::ScheduleEvent(0, et_DSP);
CoreTiming::ScheduleEvent(s_audio_dma_period, et_AudioDMA);
CoreTiming::ScheduleEvent(0, et_Throttle, Common::Timer::GetTimeMs());
- if (SConfig::GetInstance().bCPUThread && SConfig::GetInstance().bSyncGPU)
- CoreTiming::ScheduleEvent(0, et_CP);
- s_last_sync_gpu_tick = CoreTiming::GetTicks();
CoreTiming::ScheduleEvent(VideoInterface::GetTicksPerField(), et_PatchEngine);
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index acc43b8855..0ca6096de8 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -15,6 +15,7 @@
#include "Common/MsgHandler.h"
#include "Core/ConfigManager.h"
+#include "Core/CoreTiming.h"
#include "Core/NetPlayProto.h"
#include "Core/HW/Memmap.h"
@@ -45,6 +46,9 @@ static u8* s_fifo_aux_read_ptr;
bool g_use_deterministic_gpu_thread;
+static u64 s_last_sync_gpu_tick;
+static int s_et_syncGPU;
+
// STATE_TO_SAVE
static u8* s_video_buffer;
static u8* s_video_buffer_read_ptr;
@@ -79,6 +83,7 @@ void DoState(PointerWrap &p)
s_video_buffer_seen_ptr = s_video_buffer_pp_read_ptr = s_video_buffer_read_ptr;
}
p.Do(g_bSkipCurrentFrame);
+ p.Do(s_last_sync_gpu_tick);
}
void PauseAndLock(bool doLock, bool unpauseOnUnlock)
@@ -492,16 +497,10 @@ void UpdateWantDeterminism(bool want)
}
}
-int Update(int ticks)
+static int Update(int ticks)
{
const SConfig& param = SConfig::GetInstance();
- if (ticks == 0)
- {
- FlushGpu();
- return param.iSyncGpuMaxDistance;
- }
-
// GPU is sleeping, so no need for synchronization
if (s_gpu_mainloop.IsDone() || g_use_deterministic_gpu_thread)
{
@@ -529,4 +528,24 @@ int Update(int ticks)
return param.iSyncGpuMaxDistance - s_sync_ticks.load();
}
+static void SyncGPUCallback(u64 userdata, int cyclesLate)
+{
+ u64 now = CoreTiming::GetTicks();
+ int next = Fifo::Update((int)(now - s_last_sync_gpu_tick));
+ s_last_sync_gpu_tick = now;
+
+ if (next > 0)
+ CoreTiming::ScheduleEvent(next, s_et_syncGPU);
+}
+
+void Prepare()
+{
+ if (SConfig::GetInstance().bCPUThread && SConfig::GetInstance().bSyncGPU)
+ {
+ s_et_syncGPU = CoreTiming::RegisterEvent("SyncGPUCallback", SyncGPUCallback);
+ CoreTiming::ScheduleEvent(0, s_et_syncGPU);
+ s_last_sync_gpu_tick = CoreTiming::GetTicks();
+ }
+}
+
}
diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h
index d342b535df..b30d41069e 100644
--- a/Source/Core/VideoCommon/Fifo.h
+++ b/Source/Core/VideoCommon/Fifo.h
@@ -22,6 +22,7 @@ extern std::atomic<u8*> g_video_buffer_write_ptr_xthread;
void Init();
void Shutdown();
+void Prepare(); // Must be called from the CPU thread.
void DoState(PointerWrap &f);
void PauseAndLock(bool doLock, bool unpauseOnUnlock);
void UpdateWantDeterminism(bool want);
@@ -52,6 +53,5 @@ void EmulatorState(bool running);
bool AtBreakpoint();
void ResetVideoBuffer();
void SetRendering(bool bEnabled);
-int Update(int ticks);
};