From 9f3b0cd1efec8205397476561879fc66ded03fde Mon Sep 17 00:00:00 2001 From: Andy Adshead Date: Tue, 29 Jan 2019 04:35:08 +0000 Subject: [PATCH] Added support for timing flags --- Ryujinx.Profiler/InternalProfile.cs | 37 +++++++++++++++++++++++ Ryujinx.Profiler/Profile.cs | 14 ++++++++- Ryujinx.Profiler/TimingFlag.cs | 17 +++++++++++ Ryujinx.Profiler/UI/ProfileWindowGraph.cs | 17 +++++++++-- Ryujinx/Ui/GLScreen.cs | 2 ++ 5 files changed, 84 insertions(+), 3 deletions(-) create mode 100644 Ryujinx.Profiler/TimingFlag.cs diff --git a/Ryujinx.Profiler/InternalProfile.cs b/Ryujinx.Profiler/InternalProfile.cs index 2b263affb7..d50fc3d702 100644 --- a/Ryujinx.Profiler/InternalProfile.cs +++ b/Ryujinx.Profiler/InternalProfile.cs @@ -22,8 +22,16 @@ namespace Ryujinx.Profiler private bool _cleanupRunning; private readonly long _history; + // Timing flags + private TimingFlag[] _timingFlags; + private int _timingFlagCount; + private int _timingFlagIndex; + + private const int MaxFlags = 50; + public InternalProfile(long history) { + _timingFlags = new TimingFlag[MaxFlags]; Timers = new ConcurrentDictionary(); _history = history; _cleanupRunning = true; @@ -53,6 +61,20 @@ namespace Ryujinx.Profiler } } + public void FlagTime(TimingFlagType flagType) + { + _timingFlags[_timingFlagIndex] = new TimingFlag() + { + FlagType = flagType, + Timestamp = SW.ElapsedTicks + }; + + if (++_timingFlagIndex >= MaxFlags) + _timingFlagIndex = 0; + + _timingFlagCount = Math.Max(_timingFlagCount + 1, MaxFlags); + } + public void BeginProfile(ProfileConfig config) { Timers.GetOrAdd(config, profileConfig => new TimingInfo()).Begin(SW.ElapsedTicks); @@ -108,6 +130,21 @@ namespace Ryujinx.Profiler return outDict; } + public TimingFlag[] GetTimingFlags() + { + int count = Math.Max(_timingFlagCount, MaxFlags); + TimingFlag[] outFlags = new TimingFlag[count]; + + for (int i = 0, sourceIndex = _timingFlagIndex; i < count; i++, sourceIndex++) + { + if (sourceIndex >= MaxFlags) + sourceIndex = 0; + outFlags[i] = _timingFlags[sourceIndex]; + } + + return outFlags; + } + public void Dispose() { _cleanupRunning = false; diff --git a/Ryujinx.Profiler/Profile.cs b/Ryujinx.Profiler/Profile.cs index 0bfc3358e2..d45bd538a2 100644 --- a/Ryujinx.Profiler/Profile.cs +++ b/Ryujinx.Profiler/Profile.cs @@ -39,6 +39,13 @@ namespace Ryujinx.Profiler _profileInstance.Dispose(); } + public static void FlagTime(TimingFlagType flagType) + { + if (!ProfilingEnabled()) + return; + _profileInstance.FlagTime(flagType); + } + public static void Begin(ProfileConfig config) { if (!ProfilingEnabled()) @@ -96,7 +103,12 @@ namespace Ryujinx.Profiler return _profileInstance.GetProfilingData(); } - + public static TimingFlag[] GetTimingFlags() + { + if (!ProfilingEnabled()) + return new TimingFlag[0]; + return _profileInstance.GetTimingFlags(); + } public static long GetCurrentTime() { diff --git a/Ryujinx.Profiler/TimingFlag.cs b/Ryujinx.Profiler/TimingFlag.cs new file mode 100644 index 0000000000..4953b06815 --- /dev/null +++ b/Ryujinx.Profiler/TimingFlag.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Ryujinx.Profiler +{ + public enum TimingFlagType + { + FrameSwap, + } + + public struct TimingFlag + { + public TimingFlagType FlagType; + public long Timestamp; + } +} diff --git a/Ryujinx.Profiler/UI/ProfileWindowGraph.cs b/Ryujinx.Profiler/UI/ProfileWindowGraph.cs index f60afdf5cb..84fd2fc639 100644 --- a/Ryujinx.Profiler/UI/ProfileWindowGraph.cs +++ b/Ryujinx.Profiler/UI/ProfileWindowGraph.cs @@ -6,8 +6,8 @@ namespace Ryujinx.Profiler.UI { public partial class ProfileWindow { - private const float GraphMoveSpeed = 20000; - private const float GraphZoomSpeed = 10; + private const float GraphMoveSpeed = 40000; + private const float GraphZoomSpeed = 50; private float _graphZoom = 1; private float _graphPosition = 0; @@ -32,7 +32,20 @@ namespace Ryujinx.Profiler.UI _graphPosition = (float)Profile.ConvertTicksToMS(graphPositionTicks); } + // Draw timing flags + TimingFlag[] timingFlags = Profile.GetTimingFlags(); GL.Enable(EnableCap.ScissorTest); + GL.Color3(Color.Gray); + GL.Begin(PrimitiveType.Lines); + foreach (TimingFlag timingFlag in timingFlags) + { + int x = (int)(xOffset + width - ((float)(_captureTime - (timingFlag.Timestamp + graphPositionTicks)) / timeWidthTicks) * width); + GL.Vertex2(x, 0); + GL.Vertex2(x, Height); + } + GL.End(); + + // Draw bars GL.Begin(PrimitiveType.Triangles); foreach (var entry in _sortedProfileData) { diff --git a/Ryujinx/Ui/GLScreen.cs b/Ryujinx/Ui/GLScreen.cs index 23857d8a8b..fdd88da660 100644 --- a/Ryujinx/Ui/GLScreen.cs +++ b/Ryujinx/Ui/GLScreen.cs @@ -277,6 +277,8 @@ namespace Ryujinx _device.System.SignalVsync(); _device.VsyncEvent.Set(); + + Profile.FlagTime(TimingFlagType.FrameSwap); } protected override void OnUnload(EventArgs e)