From d2c62b17445b666b81a19cb3a6c46f9ee2d1388e Mon Sep 17 00:00:00 2001 From: degasus Date: Fri, 13 Mar 2015 23:36:31 +0100 Subject: [PATCH] Fifo: only sleep once within every ms of emulated time --- Source/Core/Core/HW/SystemTimers.cpp | 3 +++ Source/Core/VideoCommon/CommandProcessor.cpp | 2 ++ Source/Core/VideoCommon/CommandProcessor.h | 2 ++ Source/Core/VideoCommon/Fifo.cpp | 11 ++++++++--- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index 72d1dc8715..e69c3c1e78 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -199,6 +199,9 @@ static void PatchEngineCallback(u64 userdata, int cyclesLate) static void ThrottleCallback(u64 last_time, int cyclesLate) { + // Allow the GPU thread to sleep. Setting this flag here limits the wakeups to 1 kHz. + CommandProcessor::s_gpuMaySleep.Set(); + u32 time = Common::Timer::GetTimeMs(); int diff = (u32)last_time - time; diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp index 162e3a2d53..2c6660e1f8 100644 --- a/Source/Core/VideoCommon/CommandProcessor.cpp +++ b/Source/Core/VideoCommon/CommandProcessor.cpp @@ -45,6 +45,8 @@ volatile bool interruptWaiting= false; volatile bool interruptTokenWaiting = false; volatile bool interruptFinishWaiting = false; +Common::Flag s_gpuMaySleep; + volatile u32 VITicks = CommandProcessor::m_cpClockOrigin; static bool IsOnThread() diff --git a/Source/Core/VideoCommon/CommandProcessor.h b/Source/Core/VideoCommon/CommandProcessor.h index d25a5b7ef4..6d177844a6 100644 --- a/Source/Core/VideoCommon/CommandProcessor.h +++ b/Source/Core/VideoCommon/CommandProcessor.h @@ -5,6 +5,7 @@ #pragma once #include "Common/CommonTypes.h" +#include "Common/Flag.h" #include "VideoCommon/VideoBackendBase.h" class PointerWrap; @@ -21,6 +22,7 @@ extern volatile bool interruptSet; extern volatile bool interruptWaiting; extern volatile bool interruptTokenWaiting; extern volatile bool interruptFinishWaiting; +extern Common::Flag s_gpuMaySleep; // internal hardware addresses enum diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp index 0b65a56cd8..add7618d5d 100644 --- a/Source/Core/VideoCommon/Fifo.cpp +++ b/Source/Core/VideoCommon/Fifo.cpp @@ -369,9 +369,13 @@ void RunGpuLoop() { 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(); + if (CommandProcessor::s_gpuMaySleep.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(); + CommandProcessor::s_gpuMaySleep.Clear(); + } } else { @@ -403,6 +407,7 @@ void FlushGpu() while (s_gpu_is_running.IsSet() || s_gpu_is_pending.IsSet()) { + CommandProcessor::s_gpuMaySleep.Set(); s_gpu_done_event.Wait(); } }