Fix PerformanceStatistics calculating the wrong host fps, remove wait event on PFIFO as this wasn't exactly was causing the freezes (may replace with an exception later)
This commit is contained in:
parent
88a38e9754
commit
4c3db79ebb
4 changed files with 80 additions and 71 deletions
|
@ -1,5 +1,4 @@
|
||||||
using Ryujinx.Graphics.Gal;
|
using Ryujinx.Graphics.Gal;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Gpu
|
namespace Ryujinx.HLE.Gpu
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace Ryujinx.HLE.Gpu
|
namespace Ryujinx.HLE.Gpu
|
||||||
{
|
{
|
||||||
|
@ -53,8 +52,6 @@ namespace Ryujinx.HLE.Gpu
|
||||||
|
|
||||||
private int[] Mme;
|
private int[] Mme;
|
||||||
|
|
||||||
private ManualResetEvent FifoWait;
|
|
||||||
|
|
||||||
public NvGpuFifo(NvGpu Gpu)
|
public NvGpuFifo(NvGpu Gpu)
|
||||||
{
|
{
|
||||||
this.Gpu = Gpu;
|
this.Gpu = Gpu;
|
||||||
|
@ -66,19 +63,10 @@ namespace Ryujinx.HLE.Gpu
|
||||||
Macros = new CachedMacro[MacrosCount];
|
Macros = new CachedMacro[MacrosCount];
|
||||||
|
|
||||||
Mme = new int[MmeWords];
|
Mme = new int[MmeWords];
|
||||||
|
|
||||||
FifoWait = new ManualResetEvent(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PushBuffer(NvGpuVmm Vmm, NvGpuPBEntry[] Buffer)
|
public void PushBuffer(NvGpuVmm Vmm, NvGpuPBEntry[] Buffer)
|
||||||
{
|
{
|
||||||
if (BufferQueue.Count + Buffer.Length > FifoCapacity)
|
|
||||||
{
|
|
||||||
FifoWait.Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
FifoWait.WaitOne();
|
|
||||||
|
|
||||||
foreach (NvGpuPBEntry PBEntry in Buffer)
|
foreach (NvGpuPBEntry PBEntry in Buffer)
|
||||||
{
|
{
|
||||||
BufferQueue.Enqueue((Vmm, PBEntry));
|
BufferQueue.Enqueue((Vmm, PBEntry));
|
||||||
|
@ -88,8 +76,6 @@ namespace Ryujinx.HLE.Gpu
|
||||||
public void DispatchCalls()
|
public void DispatchCalls()
|
||||||
{
|
{
|
||||||
while (Step());
|
while (Step());
|
||||||
|
|
||||||
FifoWait.Set();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Step()
|
public bool Step()
|
||||||
|
|
|
@ -5,80 +5,106 @@ namespace Ryujinx.HLE
|
||||||
{
|
{
|
||||||
public class PerformanceStatistics
|
public class PerformanceStatistics
|
||||||
{
|
{
|
||||||
Stopwatch ExecutionTime = new Stopwatch();
|
private const double FrameRateWeight = 0.5;
|
||||||
Timer ResetTimer = new Timer(1000);
|
|
||||||
|
|
||||||
long CurrentGameFrameEnded;
|
private const int FrameTypeSystem = 0;
|
||||||
long CurrentSystemFrameEnded;
|
private const int FrameTypeGame = 1;
|
||||||
long CurrentSystemFrameStart;
|
|
||||||
long LastGameFrameEnded;
|
|
||||||
long LastSystemFrameEnded;
|
|
||||||
|
|
||||||
double AccumulatedGameFrameTime;
|
private double[] AverageFrameRate;
|
||||||
double AccumulatedSystemFrameTime;
|
private double[] AccumulatedFrameTime;
|
||||||
double CurrentGameFrameTime;
|
private double[] PreviousFrameTime;
|
||||||
double CurrentSystemFrameTime;
|
|
||||||
double PreviousGameFrameTime;
|
private long[] FramesRendered;
|
||||||
double PreviousSystemFrameTime;
|
|
||||||
public double GameFrameRate { get; private set; }
|
private object[] FrameLock;
|
||||||
public double SystemFrameRate { get; private set; }
|
|
||||||
public long SystemFramesRendered;
|
private double TicksToSeconds;
|
||||||
public long GameFramesRendered;
|
|
||||||
public long ElapsedMilliseconds => ExecutionTime.ElapsedMilliseconds;
|
private Stopwatch ExecutionTime;
|
||||||
public long ElapsedMicroseconds => (long)
|
|
||||||
(((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000);
|
private Timer ResetTimer;
|
||||||
public long ElapsedNanoseconds => (long)
|
|
||||||
(((double)ExecutionTime.ElapsedTicks / Stopwatch.Frequency) * 1000000000);
|
|
||||||
|
|
||||||
public PerformanceStatistics()
|
public PerformanceStatistics()
|
||||||
{
|
{
|
||||||
|
AverageFrameRate = new double[2];
|
||||||
|
AccumulatedFrameTime = new double[2];
|
||||||
|
PreviousFrameTime = new double[2];
|
||||||
|
|
||||||
|
FramesRendered = new long[2];
|
||||||
|
|
||||||
|
ExecutionTime = new Stopwatch();
|
||||||
|
|
||||||
ExecutionTime.Start();
|
ExecutionTime.Start();
|
||||||
|
|
||||||
|
ResetTimer = new Timer(1000);
|
||||||
|
|
||||||
ResetTimer.Elapsed += ResetTimerElapsed;
|
ResetTimer.Elapsed += ResetTimerElapsed;
|
||||||
|
|
||||||
ResetTimer.AutoReset = true;
|
ResetTimer.AutoReset = true;
|
||||||
|
|
||||||
ResetTimer.Start();
|
ResetTimer.Start();
|
||||||
|
|
||||||
|
TicksToSeconds = 1.0 / Stopwatch.Frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetTimerElapsed(object sender, ElapsedEventArgs e)
|
private void ResetTimerElapsed(object sender, ElapsedEventArgs e)
|
||||||
{
|
{
|
||||||
ResetStatistics();
|
CalculateAverageFrameRate(FrameTypeSystem);
|
||||||
|
CalculateAverageFrameRate(FrameTypeGame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartSystemFrame()
|
private void CalculateAverageFrameRate(int FrameType)
|
||||||
{
|
{
|
||||||
PreviousSystemFrameTime = CurrentSystemFrameTime;
|
double FrameRate = 0;
|
||||||
LastSystemFrameEnded = CurrentSystemFrameEnded;
|
|
||||||
CurrentSystemFrameStart = ElapsedMicroseconds;
|
if (AccumulatedFrameTime[FrameType] > 0)
|
||||||
|
{
|
||||||
|
FrameRate = FramesRendered[FrameType] / AccumulatedFrameTime[FrameType];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndSystemFrame()
|
AverageFrameRate[FrameType] = Mix(AverageFrameRate[FrameType], FrameRate);
|
||||||
|
|
||||||
|
FramesRendered[FrameType] = 0;
|
||||||
|
|
||||||
|
AccumulatedFrameTime[FrameType] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double Mix(double Old, double New)
|
||||||
{
|
{
|
||||||
CurrentSystemFrameEnded = ElapsedMicroseconds;
|
return Old * (1.0 - FrameRateWeight) + New * FrameRateWeight;
|
||||||
CurrentSystemFrameTime = CurrentSystemFrameEnded - CurrentSystemFrameStart;
|
}
|
||||||
AccumulatedSystemFrameTime += CurrentSystemFrameTime;
|
|
||||||
SystemFramesRendered++;
|
public void RecordSystemFrameTime()
|
||||||
|
{
|
||||||
|
RecordFrameTime(FrameTypeSystem);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecordGameFrameTime()
|
public void RecordGameFrameTime()
|
||||||
{
|
{
|
||||||
CurrentGameFrameEnded = ElapsedMicroseconds;
|
RecordFrameTime(FrameTypeGame);
|
||||||
CurrentGameFrameTime = CurrentGameFrameEnded - LastGameFrameEnded;
|
|
||||||
PreviousGameFrameTime = CurrentGameFrameTime;
|
|
||||||
LastGameFrameEnded = CurrentGameFrameEnded;
|
|
||||||
AccumulatedGameFrameTime += CurrentGameFrameTime;
|
|
||||||
GameFramesRendered++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetStatistics()
|
private void RecordFrameTime(int FrameType)
|
||||||
{
|
{
|
||||||
GameFrameRate = 1000 / ((AccumulatedGameFrameTime / GameFramesRendered) / 1000);
|
double CurrentFrameTime = ExecutionTime.ElapsedTicks * TicksToSeconds;
|
||||||
GameFrameRate = double.IsNaN(GameFrameRate) ? 0 : GameFrameRate;
|
|
||||||
SystemFrameRate = 1000 / ((AccumulatedSystemFrameTime / SystemFramesRendered) / 1000);
|
|
||||||
SystemFrameRate = double.IsNaN(SystemFrameRate) ? 0 : SystemFrameRate;
|
|
||||||
|
|
||||||
GameFramesRendered = 0;
|
double ElapsedFrameTime = CurrentFrameTime - PreviousFrameTime[FrameType];
|
||||||
SystemFramesRendered = 0;
|
|
||||||
AccumulatedGameFrameTime = 0;
|
PreviousFrameTime[FrameType] = CurrentFrameTime;
|
||||||
AccumulatedSystemFrameTime = 0;
|
|
||||||
|
AccumulatedFrameTime[FrameType] += ElapsedFrameTime;
|
||||||
|
|
||||||
|
FramesRendered[FrameType]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetSystemFrameRate()
|
||||||
|
{
|
||||||
|
return AverageFrameRate[FrameTypeSystem];
|
||||||
|
}
|
||||||
|
|
||||||
|
public double GetGameFrameRate()
|
||||||
|
{
|
||||||
|
return AverageFrameRate[FrameTypeGame];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,27 +179,25 @@ namespace Ryujinx
|
||||||
CurrentButton,
|
CurrentButton,
|
||||||
LeftJoystick,
|
LeftJoystick,
|
||||||
RightJoystick);
|
RightJoystick);
|
||||||
|
|
||||||
|
Ns.ProcessFrame();
|
||||||
|
|
||||||
|
Renderer.RunActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnRenderFrame(FrameEventArgs e)
|
protected override void OnRenderFrame(FrameEventArgs e)
|
||||||
{
|
{
|
||||||
Renderer.RunActions();
|
|
||||||
|
|
||||||
Renderer.FrameBuffer.Render();
|
Renderer.FrameBuffer.Render();
|
||||||
|
|
||||||
Ns.Statistics.EndSystemFrame();
|
Ns.Statistics.RecordSystemFrameTime();
|
||||||
|
|
||||||
double HostFps = Ns.Statistics.SystemFrameRate;
|
double HostFps = Ns.Statistics.GetSystemFrameRate();
|
||||||
double GameFps = Ns.Statistics.GameFrameRate;
|
double GameFps = Ns.Statistics.GetGameFrameRate();
|
||||||
|
|
||||||
Title = $"Ryujinx | Host FPS: {HostFps:0.0} | Game FPS: {GameFps:0.0}";
|
Title = $"Ryujinx | Host FPS: {HostFps:0.0} | Game FPS: {GameFps:0.0}";
|
||||||
|
|
||||||
SwapBuffers();
|
SwapBuffers();
|
||||||
|
|
||||||
Ns.Statistics.StartSystemFrame();
|
|
||||||
|
|
||||||
Ns.ProcessFrame();
|
|
||||||
|
|
||||||
Ns.Os.SignalVsync();
|
Ns.Os.SignalVsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue