diff --git a/Ryujinx.Profiler/InternalProfile.cs b/Ryujinx.Profiler/InternalProfile.cs index 75f9581e54..1dcc4ed462 100644 --- a/Ryujinx.Profiler/InternalProfile.cs +++ b/Ryujinx.Profiler/InternalProfile.cs @@ -150,10 +150,11 @@ namespace Ryujinx.Profiler { _preserve = PerformanceCounter.ElapsedTicks; - // Make sure to clear queue - lock (_timerQueueClearLock) + // Skip clearing queue if already clearing + if (Monitor.TryEnter(_timerQueueClearLock)) { ClearTimerQueue(); + Monitor.Exit(_timerQueueClearLock); } return Timers; diff --git a/Ryujinx.Profiler/Profile.cs b/Ryujinx.Profiler/Profile.cs index a6127fe5d1..8869865e51 100644 --- a/Ryujinx.Profiler/Profile.cs +++ b/Ryujinx.Profiler/Profile.cs @@ -66,6 +66,8 @@ namespace Ryujinx.Profiler { if (!ProfilingEnabled()) return; + if (config.Level > _settings.MaxLevel) + return; _profileInstance.BeginProfile(config); } @@ -74,6 +76,8 @@ namespace Ryujinx.Profiler { if (!ProfilingEnabled()) return; + if (config.Level > _settings.MaxLevel) + return; _profileInstance.EndProfile(config); } diff --git a/Ryujinx.Profiler/ProfileConfig.cs b/Ryujinx.Profiler/ProfileConfig.cs index 0cda69c109..8a4a5ed88b 100644 --- a/Ryujinx.Profiler/ProfileConfig.cs +++ b/Ryujinx.Profiler/ProfileConfig.cs @@ -10,6 +10,8 @@ namespace Ryujinx.Profiler public string SessionGroup; public string SessionItem; + public int Level; + // Private cached variables private string _cachedTag; private string _cachedSession; diff --git a/Ryujinx.Profiler/Settings.cs b/Ryujinx.Profiler/Settings.cs index f74a3cda2d..a3c677d81a 100644 --- a/Ryujinx.Profiler/Settings.cs +++ b/Ryujinx.Profiler/Settings.cs @@ -11,6 +11,7 @@ namespace Ryujinx.Profiler public bool FileDumpEnabled { get; set; } = false; public string DumpLocation { get; set; } = ""; public float UpdateRate { get; set; } = 0.1f; + public int MaxLevel { get; set; } = 0; // 19531225 = 5 seconds in ticks public long History { get; set; } = 19531225; diff --git a/Ryujinx.Profiler/TimingInfo.cs b/Ryujinx.Profiler/TimingInfo.cs index 23d6a5173f..2dc3072340 100644 --- a/Ryujinx.Profiler/TimingInfo.cs +++ b/Ryujinx.Profiler/TimingInfo.cs @@ -157,7 +157,7 @@ namespace Ryujinx.Profiler if (toRemove > 0) { - _timestamps.RemoveRange(toPreserveStart + toPreserveLen, toRemove); + _timestamps.RemoveRange(toPreserveLen, toRemove); } } } diff --git a/Ryujinx.Profiler/UI/ProfileWindowGraph.cs b/Ryujinx.Profiler/UI/ProfileWindowGraph.cs index 19d676a597..137d09d5b9 100644 --- a/Ryujinx.Profiler/UI/ProfileWindowGraph.cs +++ b/Ryujinx.Profiler/UI/ProfileWindowGraph.cs @@ -22,26 +22,30 @@ namespace Ryujinx.Profiler.UI int left, right; float top, bottom; - int verticalIndex = 0; - float barHeight = (LineHeight - LinePadding); - long history = Profile.HistoryLength; - long timeWidthTicks = (long)(history / (double)_graphZoom); - long graphPositionTicks = (long)(_graphPosition * PerformanceCounter.TicksPerMillisecond); + int verticalIndex = 0; + float graphRight = xOffset + width; + float barHeight = (LineHeight - LinePadding); + long history = Profile.HistoryLength; + double timeWidthTicks = history / (double)_graphZoom; + long graphPositionTicks = (long)(_graphPosition * PerformanceCounter.TicksPerMillisecond); + long ticksPerPixel = (long)(timeWidthTicks / width); // Reset start point if out of bounds if (timeWidthTicks + graphPositionTicks > history) { - graphPositionTicks = history - timeWidthTicks; + graphPositionTicks = history - (long)timeWidthTicks; _graphPosition = (float)graphPositionTicks / PerformanceCounter.TicksPerMillisecond; } + graphPositionTicks = _captureTime - graphPositionTicks; + // Draw timing flags GL.Enable(EnableCap.ScissorTest); GL.Color3(0.25f, 0.25f, 0.25f); GL.Begin(PrimitiveType.Lines); foreach (TimingFlag timingFlag in _timingFlags) { - int x = (int)(xOffset + width - ((float)(_captureTime - (timingFlag.Timestamp + graphPositionTicks)) / timeWidthTicks) * width); + int x = (int)(graphRight - ((graphPositionTicks - timingFlag.Timestamp) / timeWidthTicks) * width); GL.Vertex2(x, 0); GL.Vertex2(x, Height); } @@ -51,30 +55,30 @@ namespace Ryujinx.Profiler.UI GL.Begin(PrimitiveType.Triangles); foreach (var entry in _sortedProfileData) { - int furthest = 0; + long furthest = 0; + + bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex); + top = bottom + barHeight; + + // Skip rendering out of bounds bars + if (top < 0 || bottom > Height) + continue; + GL.Color3(Color.Green); foreach (Timestamp timestamp in entry.Value.GetAllTimestamps()) { - right = (int)(xOffset + width - ((float)(_captureTime - (timestamp.EndTime + graphPositionTicks)) / timeWidthTicks) * width); - // Skip drawing multiple timestamps on same pixel - if (right <= furthest) + if (timestamp.EndTime < furthest) continue; + furthest = timestamp.EndTime + ticksPerPixel; - left = (int)(xOffset + width - ((float)(_captureTime - (timestamp.BeginTime + graphPositionTicks)) / timeWidthTicks) * width); - bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex); - top = bottom + barHeight; + left = (int)(graphRight - ((graphPositionTicks - timestamp.BeginTime) / timeWidthTicks) * width); + right = (int)(graphRight - ((graphPositionTicks - timestamp.EndTime) / timeWidthTicks) * width); // Make sure width is at least 1px right = Math.Max(left + 1, right); - furthest = right; - - // Skip rendering out of bounds bars - if (top < 0 || bottom > Height) - continue; - GL.Vertex2(left, bottom); GL.Vertex2(left, top); GL.Vertex2(right, top); @@ -84,30 +88,23 @@ namespace Ryujinx.Profiler.UI GL.Vertex2(left, bottom); } - GL.Color3(Color.Red); // Currently capturing timestamp + GL.Color3(Color.Red); long entryBegin = entry.Value.BeginTime; if (entryBegin != -1) { - left = (int)(xOffset + width + _graphPosition - (((float)_captureTime - entryBegin) / timeWidthTicks) * width); - bottom = GetLineY(yOffset, LineHeight, LinePadding, true, verticalIndex); - top = bottom + barHeight; - right = (int)(xOffset + width); + left = (int)(graphRight - ((graphPositionTicks - entryBegin) / timeWidthTicks) * width); // Make sure width is at least 1px - left = Math.Min(left - 1, right); + left = Math.Min(left - 1, (int)graphRight); - // Skip rendering out of bounds bars - if (top < 0 || bottom > Height) - continue; + GL.Vertex2(left, bottom); + GL.Vertex2(left, top); + GL.Vertex2(graphRight, top); - GL.Vertex2(left, bottom); - GL.Vertex2(left, top); - GL.Vertex2(right, top); - - GL.Vertex2(right, top); - GL.Vertex2(right, bottom); - GL.Vertex2(left, bottom); + GL.Vertex2(graphRight, top); + GL.Vertex2(graphRight, bottom); + GL.Vertex2(left, bottom); } verticalIndex++; @@ -120,7 +117,7 @@ namespace Ryujinx.Profiler.UI // Dummy draw for measure float labelWidth = _fontService.DrawText(label, 0, 0, LineHeight, false); - _fontService.DrawText(label, xOffset + width - labelWidth - LinePadding, FilterHeight + LinePadding, LineHeight); + _fontService.DrawText(label, graphRight - labelWidth - LinePadding, FilterHeight + LinePadding, LineHeight); _fontService.DrawText($"-{MathF.Round((float)((timeWidthTicks / PerformanceCounter.TicksPerMillisecond) + _graphPosition), 2)} ms", xOffset + LinePadding, FilterHeight + LinePadding, LineHeight); } diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs index da6b934614..fdff2e8aa2 100644 --- a/Ryujinx/Config.cs +++ b/Ryujinx/Config.cs @@ -75,6 +75,7 @@ namespace Ryujinx DumpLocation = profilePath, UpdateRate = (float)((updateRateHz <= 0) ? -1 : 1.0f / updateRateHz), History = (long)(Convert.ToDouble(parser.Value("Profiling_History")) * PerformanceCounter.TicksPerSecond), + MaxLevel = Convert.ToInt32(parser.Value("Profiling_Max_Level")), }); SystemLanguage SetLanguage = Enum.Parse(parser.Value("System_Language")); diff --git a/Ryujinx/Ryujinx.conf b/Ryujinx/Ryujinx.conf index 2f1436bf18..e3c854cc80 100644 --- a/Ryujinx/Ryujinx.conf +++ b/Ryujinx/Ryujinx.conf @@ -34,6 +34,9 @@ Profiling_Update_Rate = 4 #Set how long to keep profiling data in seconds, reduce if profiling is taking too much RAM Profiling_History = 5 +#Set the maximum profiling level. Higher values may cause a heavy load on your system but will allow you to profile in more detail. +Profiling_Max_Level = 0 + #System Language list: https://gist.github.com/HorrorTroll/b6e4a88d774c3c9b3bdf54d79a7ca43b #Change System Language System_Language = AmericanEnglish