Fifo: Fix SyncGPU.

This commit is contained in:
degasus 2016-10-01 13:16:50 +02:00
parent d139659ea2
commit 12f050bb8e
1 changed files with 18 additions and 27 deletions

View File

@ -371,7 +371,8 @@ void RunGpuLoop()
{ {
cyclesExecuted = (int)(cyclesExecuted / param.fSyncGpuOverclock); cyclesExecuted = (int)(cyclesExecuted / param.fSyncGpuOverclock);
int old = s_sync_ticks.fetch_sub(cyclesExecuted); int old = s_sync_ticks.fetch_sub(cyclesExecuted);
if (old > 0 && old - (int)cyclesExecuted <= 0) if (old >= param.iSyncGpuMaxDistance &&
old - (int)cyclesExecuted < param.iSyncGpuMaxDistance)
s_sync_wakeup_event.Set(); s_sync_wakeup_event.Set();
} }
@ -386,7 +387,7 @@ void RunGpuLoop()
if (s_sync_ticks.load() > 0) if (s_sync_ticks.load() > 0)
{ {
int old = s_sync_ticks.exchange(0); int old = s_sync_ticks.exchange(0);
if (old > 0) if (old >= param.iSyncGpuMaxDistance)
s_sync_wakeup_event.Set(); s_sync_wakeup_event.Set();
} }
@ -554,36 +555,26 @@ static int WaitForGpuThread(int ticks)
{ {
const SConfig& param = SConfig::GetInstance(); const SConfig& param = SConfig::GetInstance();
// GPU is sleeping, so no need for synchronization int old = s_sync_ticks.fetch_add(ticks);
if (s_gpu_mainloop.IsDone() || s_use_deterministic_gpu_thread) int now = old + ticks;
{
if ((s_sync_ticks.load() + ticks) < 0) // GPU is idle, so stop polling.
{ if (old >= 0 && s_gpu_mainloop.IsDone())
s_sync_ticks.store(s_sync_ticks.load() + ticks);
return 0 - s_sync_ticks.load();
}
else
{
s_sync_ticks.store(0);
return -1; return -1;
}
}
// Wakeup GPU // Wakeup GPU
int old = s_sync_ticks.fetch_add(ticks); if (old < param.iSyncGpuMinDistance && now >= param.iSyncGpuMinDistance)
if (old < param.iSyncGpuMinDistance && old + ticks >= param.iSyncGpuMinDistance)
RunGpu(); RunGpu();
// Wait for GPU // If the GPU is still sleeping, wait for a longer time
if (s_sync_ticks.load() >= param.iSyncGpuMaxDistance) if (now < param.iSyncGpuMinDistance)
{ return GPU_TIME_SLOT_SIZE + param.iSyncGpuMinDistance - now;
while (s_sync_ticks.load() > 0)
{
s_sync_wakeup_event.Wait();
}
}
return param.iSyncGpuMaxDistance - s_sync_ticks.load(); // Wait for GPU
if (now >= param.iSyncGpuMaxDistance)
s_sync_wakeup_event.Wait();
return GPU_TIME_SLOT_SIZE;
} }
static void SyncGPUCallback(u64 ticks, s64 cyclesLate) static void SyncGPUCallback(u64 ticks, s64 cyclesLate)