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 System.Threading;
|
||||
|
||||
namespace Ryujinx.HLE.Gpu
|
||||
{
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue