diff --git a/Ryujinx.HLE/Gpu/NvGpu.cs b/Ryujinx.HLE/Gpu/NvGpu.cs index 87079a33b8..a8b8e9e834 100644 --- a/Ryujinx.HLE/Gpu/NvGpu.cs +++ b/Ryujinx.HLE/Gpu/NvGpu.cs @@ -1,5 +1,4 @@ using Ryujinx.Graphics.Gal; -using System.Threading; namespace Ryujinx.HLE.Gpu { diff --git a/Ryujinx.HLE/Gpu/NvGpuFifo.cs b/Ryujinx.HLE/Gpu/NvGpuFifo.cs index 9e2fa68b35..cf4e4f5e43 100644 --- a/Ryujinx.HLE/Gpu/NvGpuFifo.cs +++ b/Ryujinx.HLE/Gpu/NvGpuFifo.cs @@ -1,5 +1,4 @@ using System.Collections.Concurrent; -using System.Threading; namespace Ryujinx.HLE.Gpu { @@ -53,8 +52,6 @@ namespace Ryujinx.HLE.Gpu private int[] Mme; - private ManualResetEvent FifoWait; - public NvGpuFifo(NvGpu Gpu) { this.Gpu = Gpu; @@ -66,19 +63,10 @@ namespace Ryujinx.HLE.Gpu Macros = new CachedMacro[MacrosCount]; Mme = new int[MmeWords]; - - FifoWait = new ManualResetEvent(true); } public void PushBuffer(NvGpuVmm Vmm, NvGpuPBEntry[] Buffer) { - if (BufferQueue.Count + Buffer.Length > FifoCapacity) - { - FifoWait.Reset(); - } - - FifoWait.WaitOne(); - foreach (NvGpuPBEntry PBEntry in Buffer) { BufferQueue.Enqueue((Vmm, PBEntry)); @@ -88,8 +76,6 @@ namespace Ryujinx.HLE.Gpu public void DispatchCalls() { while (Step()); - - FifoWait.Set(); } public bool Step() diff --git a/Ryujinx.HLE/PerformanceStatistics.cs b/Ryujinx.HLE/PerformanceStatistics.cs index bbcdc64508..697d6e63ff 100644 --- a/Ryujinx.HLE/PerformanceStatistics.cs +++ b/Ryujinx.HLE/PerformanceStatistics.cs @@ -5,80 +5,106 @@ namespace Ryujinx.HLE { public class PerformanceStatistics { - Stopwatch ExecutionTime = new Stopwatch(); - Timer ResetTimer = new Timer(1000); + private const double FrameRateWeight = 0.5; - long CurrentGameFrameEnded; - long CurrentSystemFrameEnded; - long CurrentSystemFrameStart; - long LastGameFrameEnded; - long LastSystemFrameEnded; + private const int FrameTypeSystem = 0; + private const int FrameTypeGame = 1; - double AccumulatedGameFrameTime; - double AccumulatedSystemFrameTime; - double CurrentGameFrameTime; - double CurrentSystemFrameTime; - double PreviousGameFrameTime; - double PreviousSystemFrameTime; - public double GameFrameRate { get; private set; } - public double SystemFrameRate { get; private set; } - public long SystemFramesRendered; - public long GameFramesRendered; - public long ElapsedMilliseconds => ExecutionTime.ElapsedMilliseconds; - public long ElapsedMicroseconds => (long) - (((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000); - public long ElapsedNanoseconds => (long) - (((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000000); + private double[] AverageFrameRate; + private double[] AccumulatedFrameTime; + private double[] PreviousFrameTime; + + private long[] FramesRendered; + + private object[] FrameLock; + + private double TicksToSeconds; + + private Stopwatch ExecutionTime; + + private Timer ResetTimer; public PerformanceStatistics() { + AverageFrameRate = new double[2]; + AccumulatedFrameTime = new double[2]; + PreviousFrameTime = new double[2]; + + FramesRendered = new long[2]; + + ExecutionTime = new Stopwatch(); + ExecutionTime.Start(); + + ResetTimer = new Timer(1000); + ResetTimer.Elapsed += ResetTimerElapsed; + ResetTimer.AutoReset = true; + ResetTimer.Start(); + + TicksToSeconds = 1.0 / Stopwatch.Frequency; } private void ResetTimerElapsed(object sender, ElapsedEventArgs e) { - ResetStatistics(); + CalculateAverageFrameRate(FrameTypeSystem); + CalculateAverageFrameRate(FrameTypeGame); } - public void StartSystemFrame() + private void CalculateAverageFrameRate(int FrameType) { - PreviousSystemFrameTime = CurrentSystemFrameTime; - LastSystemFrameEnded = CurrentSystemFrameEnded; - CurrentSystemFrameStart = ElapsedMicroseconds; + double FrameRate = 0; + + if (AccumulatedFrameTime[FrameType] > 0) + { + FrameRate = FramesRendered[FrameType] / AccumulatedFrameTime[FrameType]; + } + + AverageFrameRate[FrameType] = Mix(AverageFrameRate[FrameType], FrameRate); + + FramesRendered[FrameType] = 0; + + AccumulatedFrameTime[FrameType] = 0; } - public void EndSystemFrame() + private double Mix(double Old, double New) { - CurrentSystemFrameEnded = ElapsedMicroseconds; - CurrentSystemFrameTime = CurrentSystemFrameEnded - CurrentSystemFrameStart; - AccumulatedSystemFrameTime += CurrentSystemFrameTime; - SystemFramesRendered++; + return Old * (1.0 - FrameRateWeight) + New * FrameRateWeight; + } + + public void RecordSystemFrameTime() + { + RecordFrameTime(FrameTypeSystem); } public void RecordGameFrameTime() { - CurrentGameFrameEnded = ElapsedMicroseconds; - CurrentGameFrameTime = CurrentGameFrameEnded - LastGameFrameEnded; - PreviousGameFrameTime = CurrentGameFrameTime; - LastGameFrameEnded = CurrentGameFrameEnded; - AccumulatedGameFrameTime += CurrentGameFrameTime; - GameFramesRendered++; + RecordFrameTime(FrameTypeGame); } - public void ResetStatistics() + private void RecordFrameTime(int FrameType) { - GameFrameRate = 1000 / ((AccumulatedGameFrameTime / GameFramesRendered) / 1000); - GameFrameRate = double.IsNaN(GameFrameRate) ? 0 : GameFrameRate; - SystemFrameRate = 1000 / ((AccumulatedSystemFrameTime / SystemFramesRendered) / 1000); - SystemFrameRate = double.IsNaN(SystemFrameRate) ? 0 : SystemFrameRate; + double CurrentFrameTime = ExecutionTime.ElapsedTicks * TicksToSeconds; - GameFramesRendered = 0; - SystemFramesRendered = 0; - AccumulatedGameFrameTime = 0; - AccumulatedSystemFrameTime = 0; + double ElapsedFrameTime = CurrentFrameTime - PreviousFrameTime[FrameType]; + + PreviousFrameTime[FrameType] = CurrentFrameTime; + + AccumulatedFrameTime[FrameType] += ElapsedFrameTime; + + FramesRendered[FrameType]++; + } + + public double GetSystemFrameRate() + { + return AverageFrameRate[FrameTypeSystem]; + } + + public double GetGameFrameRate() + { + return AverageFrameRate[FrameTypeGame]; } } } diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index 762e899fc5..1c899a8e72 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -179,27 +179,25 @@ namespace Ryujinx CurrentButton, LeftJoystick, RightJoystick); + + Ns.ProcessFrame(); + + Renderer.RunActions(); } protected override void OnRenderFrame(FrameEventArgs e) { - Renderer.RunActions(); - Renderer.FrameBuffer.Render(); - Ns.Statistics.EndSystemFrame(); + Ns.Statistics.RecordSystemFrameTime(); - double HostFps = Ns.Statistics.SystemFrameRate; - double GameFps = Ns.Statistics.GameFrameRate; + double HostFps = Ns.Statistics.GetSystemFrameRate(); + double GameFps = Ns.Statistics.GetGameFrameRate(); Title = $"Ryujinx | Host FPS: {HostFps:0.0} | Game FPS: {GameFps:0.0}"; SwapBuffers(); - Ns.Statistics.StartSystemFrame(); - - Ns.ProcessFrame(); - Ns.Os.SignalVsync(); }