aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormageven <62494521+mageven@users.noreply.github.com>2020-08-02 20:11:24 +0530
committerGitHub <noreply@github.com>2020-08-02 16:41:24 +0200
commitf0c91d9efb7eff0b8bbe8fc8d4901af5a9d59005 (patch)
treedadfcd28cc2a0e26cd4a776bf93074db17488de4
parent1457ab54560a9e76a8ade68879d710f7cc533294 (diff)
Facilitate OpenGL debug logging via GUI (#1373)
* Allow printing GL Debug logs with GUI options Improve GL Debugger Make the new option persistent Address gdkchan's comments - Rename enum to GraphicsDebugLevel - Move Debugger Init to Renderer Init - Fix formatting * nit: newlines
-rw-r--r--Ryujinx.Common/Configuration/ConfigurationFileFormat.cs8
-rw-r--r--Ryujinx.Common/Configuration/ConfigurationState.cs37
-rw-r--r--Ryujinx.Common/Configuration/GraphicsDebugLevel.cs10
-rw-r--r--Ryujinx.Graphics.GAL/IRenderer.cs3
-rw-r--r--Ryujinx.Graphics.OpenGL/Debugger.cs73
-rw-r--r--Ryujinx.Graphics.OpenGL/Renderer.cs5
-rw-r--r--Ryujinx/Ui/GLRenderer.cs13
-rw-r--r--Ryujinx/Ui/MainWindow.cs2
-rw-r--r--Ryujinx/Ui/SettingsWindow.cs10
-rw-r--r--Ryujinx/Ui/SettingsWindow.glade114
10 files changed, 231 insertions, 44 deletions
diff --git a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
index 13dad62c..ae3fa493 100644
--- a/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationFileFormat.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.IO;
+using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
using Ryujinx.Common.Utilities;
@@ -13,7 +14,7 @@ namespace Ryujinx.Configuration
/// <summary>
/// The current version of the file format
/// </summary>
- public const int CurrentVersion = 11;
+ public const int CurrentVersion = 12;
public int Version { get; set; }
@@ -78,6 +79,11 @@ namespace Ryujinx.Configuration
public LogClass[] LoggingFilteredClasses { get; set; }
/// <summary>
+ /// Change Graphics API debug log level
+ /// </summary>
+ public GraphicsDebugLevel LoggingGraphicsDebugLevel { get; set; }
+
+ /// <summary>
/// Enables or disables logging to a file on disk
/// </summary>
public bool EnableFileLog { get; set; }
diff --git a/Ryujinx.Common/Configuration/ConfigurationState.cs b/Ryujinx.Common/Configuration/ConfigurationState.cs
index 3149f250..dc9dd659 100644
--- a/Ryujinx.Common/Configuration/ConfigurationState.cs
+++ b/Ryujinx.Common/Configuration/ConfigurationState.cs
@@ -1,4 +1,5 @@
using Ryujinx.Common;
+using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Common.Logging;
using Ryujinx.Configuration.Hid;
@@ -141,17 +142,23 @@ namespace Ryujinx.Configuration
/// </summary>
public ReactiveObject<bool> EnableFileLog { get; private set; }
+ /// <summary>
+ /// Controls which OpenGL log messages are recorded in the log
+ /// </summary>
+ public ReactiveObject<GraphicsDebugLevel> GraphicsDebugLevel { get; private set; }
+
public LoggerSection()
{
- EnableDebug = new ReactiveObject<bool>();
- EnableStub = new ReactiveObject<bool>();
- EnableInfo = new ReactiveObject<bool>();
- EnableWarn = new ReactiveObject<bool>();
- EnableError = new ReactiveObject<bool>();
- EnableGuest = new ReactiveObject<bool>();
- EnableFsAccessLog = new ReactiveObject<bool>();
- FilteredClasses = new ReactiveObject<LogClass[]>();
- EnableFileLog = new ReactiveObject<bool>();
+ EnableDebug = new ReactiveObject<bool>();
+ EnableStub = new ReactiveObject<bool>();
+ EnableInfo = new ReactiveObject<bool>();
+ EnableWarn = new ReactiveObject<bool>();
+ EnableError = new ReactiveObject<bool>();
+ EnableGuest = new ReactiveObject<bool>();
+ EnableFsAccessLog = new ReactiveObject<bool>();
+ FilteredClasses = new ReactiveObject<LogClass[]>();
+ EnableFileLog = new ReactiveObject<bool>();
+ GraphicsDebugLevel = new ReactiveObject<GraphicsDebugLevel>();
}
}
@@ -378,6 +385,7 @@ namespace Ryujinx.Configuration
LoggingEnableGuest = Logger.EnableGuest,
LoggingEnableFsAccessLog = Logger.EnableFsAccessLog,
LoggingFilteredClasses = Logger.FilteredClasses,
+ LoggingGraphicsDebugLevel = Logger.GraphicsDebugLevel,
EnableFileLog = Logger.EnableFileLog,
SystemLanguage = System.Language,
SystemRegion = System.Region,
@@ -436,6 +444,7 @@ namespace Ryujinx.Configuration
Logger.EnableGuest.Value = true;
Logger.EnableFsAccessLog.Value = false;
Logger.FilteredClasses.Value = new LogClass[] { };
+ Logger.GraphicsDebugLevel.Value = GraphicsDebugLevel.None;
Logger.EnableFileLog.Value = true;
System.Language.Value = Language.AmericanEnglish;
System.Region.Value = Region.USA;
@@ -678,6 +687,15 @@ namespace Ryujinx.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 12)
+ {
+ Common.Logging.Logger.PrintWarning(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 12.");
+
+ configurationFileFormat.LoggingGraphicsDebugLevel = GraphicsDebugLevel.None;
+
+ configurationFileUpdated = true;
+ }
+
List<InputConfig> inputConfig = new List<InputConfig>();
inputConfig.AddRange(configurationFileFormat.ControllerConfig);
inputConfig.AddRange(configurationFileFormat.KeyboardConfig);
@@ -694,6 +712,7 @@ namespace Ryujinx.Configuration
Logger.EnableGuest.Value = configurationFileFormat.LoggingEnableGuest;
Logger.EnableFsAccessLog.Value = configurationFileFormat.LoggingEnableFsAccessLog;
Logger.FilteredClasses.Value = configurationFileFormat.LoggingFilteredClasses;
+ Logger.GraphicsDebugLevel.Value = configurationFileFormat.LoggingGraphicsDebugLevel;
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
System.Language.Value = configurationFileFormat.SystemLanguage;
System.Region.Value = configurationFileFormat.SystemRegion;
diff --git a/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs b/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
new file mode 100644
index 00000000..1bef4a7e
--- /dev/null
+++ b/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
@@ -0,0 +1,10 @@
+namespace Ryujinx.Common.Configuration
+{
+ public enum GraphicsDebugLevel
+ {
+ None,
+ Error,
+ Performance,
+ All
+ }
+}
diff --git a/Ryujinx.Graphics.GAL/IRenderer.cs b/Ryujinx.Graphics.GAL/IRenderer.cs
index 6fd3feba..fec8d3be 100644
--- a/Ryujinx.Graphics.GAL/IRenderer.cs
+++ b/Ryujinx.Graphics.GAL/IRenderer.cs
@@ -1,3 +1,4 @@
+using Ryujinx.Common.Configuration;
using Ryujinx.Graphics.Shader;
using System;
@@ -32,6 +33,6 @@ namespace Ryujinx.Graphics.GAL
void ResetCounter(CounterType type);
- void Initialize();
+ void Initialize(GraphicsDebugLevel logLevel);
}
}
diff --git a/Ryujinx.Graphics.OpenGL/Debugger.cs b/Ryujinx.Graphics.OpenGL/Debugger.cs
index ff9fcd85..9d0a1f59 100644
--- a/Ryujinx.Graphics.OpenGL/Debugger.cs
+++ b/Ryujinx.Graphics.OpenGL/Debugger.cs
@@ -1,7 +1,9 @@
using OpenTK.Graphics.OpenGL;
+using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using System;
using System.Runtime.InteropServices;
+using System.Threading;
namespace Ryujinx.Graphics.OpenGL
{
@@ -9,15 +11,43 @@ namespace Ryujinx.Graphics.OpenGL
{
private static DebugProc _debugCallback;
- public static void Initialize()
+ private static int _counter;
+
+ public static void Initialize(GraphicsDebugLevel logLevel)
{
+ // Disable everything
+ GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, false);
+
+ if (logLevel == GraphicsDebugLevel.None)
+ {
+ GL.Disable(EnableCap.DebugOutputSynchronous);
+ GL.DebugMessageCallback(null, IntPtr.Zero);
+
+ return;
+ }
+
GL.Enable(EnableCap.DebugOutputSynchronous);
- GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, true);
+ if (logLevel == GraphicsDebugLevel.Error)
+ {
+ GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
+ }
+ else if (logLevel == GraphicsDebugLevel.Performance)
+ {
+ GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
+ GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypePerformance, DebugSeverityControl.DontCare, 0, (int[])null, true);
+ }
+ else
+ {
+ GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, true);
+ }
+ _counter = 0;
_debugCallback = GLDebugHandler;
GL.DebugMessageCallback(_debugCallback, IntPtr.Zero);
+
+ Logger.PrintWarning(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
}
private static void GLDebugHandler(
@@ -29,20 +59,43 @@ namespace Ryujinx.Graphics.OpenGL
IntPtr message,
IntPtr userParam)
{
- string fullMessage = $"{type} {severity} {source} {Marshal.PtrToStringAnsi(message)}";
+ string msg = Marshal.PtrToStringUTF8(message).Replace('\n', ' ');
switch (type)
{
- case DebugType.DebugTypeError:
- Logger.PrintError(LogClass.Gpu, fullMessage);
- break;
- case DebugType.DebugTypePerformance:
- Logger.PrintWarning(LogClass.Gpu, fullMessage);
- break;
+ case DebugType.DebugTypeError : Logger.PrintError(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR"); break;
+ case DebugType.DebugTypePerformance: Logger.PrintWarning(LogClass.Gpu, $"{severity}: {msg}", "GLPERF"); break;
+ case DebugType.DebugTypePushGroup : Logger.PrintInfo(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO"); break;
+ case DebugType.DebugTypePopGroup : Logger.PrintInfo(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO"); break;
default:
- Logger.PrintDebug(LogClass.Gpu, fullMessage);
+ if (source == DebugSource.DebugSourceApplication)
+ {
+ Logger.PrintInfo(LogClass.Gpu, $"{type} {severity}: {msg}", "GLINFO");
+ }
+ else
+ {
+ Logger.PrintDebug(LogClass.Gpu, $"{type} {severity}: {msg}", "GLDEBUG");
+ }
break;
}
}
+
+ // Useful debug helpers
+ public static void PushGroup(string dbgMsg)
+ {
+ int counter = Interlocked.Increment(ref _counter);
+
+ GL.PushDebugGroup(DebugSourceExternal.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg);
+ }
+
+ public static void PopGroup()
+ {
+ GL.PopDebugGroup();
+ }
+
+ public static void Print(string dbgMsg, DebugType type = DebugType.DebugTypeMarker, DebugSeverity severity = DebugSeverity.DebugSeverityNotification, int id = 999999)
+ {
+ GL.DebugMessageInsert(DebugSourceExternal.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg);
+ }
}
}
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index 49324637..e7a8a96b 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL;
+using Ryujinx.Common.Configuration;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image;
@@ -96,8 +97,10 @@ namespace Ryujinx.Graphics.OpenGL
return _counters.QueueReport(type, resultHandler);
}
- public void Initialize()
+ public void Initialize(GraphicsDebugLevel glLogLevel)
{
+ Debugger.Initialize(glLogLevel);
+
PrintGpuInformation();
_counters.Initialize();
diff --git a/Ryujinx/Ui/GLRenderer.cs b/Ryujinx/Ui/GLRenderer.cs
index a8ed9156..867401ad 100644
--- a/Ryujinx/Ui/GLRenderer.cs
+++ b/Ryujinx/Ui/GLRenderer.cs
@@ -5,6 +5,7 @@ using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;
using Ryujinx.Configuration;
+using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Graphics.OpenGL;
using Ryujinx.HLE;
@@ -47,10 +48,14 @@ namespace Ryujinx.Ui
private HotkeyButtons _prevHotkeyButtons;
- public GlRenderer(Switch device)
+ private GraphicsDebugLevel _glLogLevel;
+
+ public GlRenderer(Switch device, GraphicsDebugLevel glLogLevel)
: base (GetGraphicsMode(),
3, 3,
- GraphicsContextFlags.ForwardCompatible)
+ glLogLevel == GraphicsDebugLevel.None
+ ? GraphicsContextFlags.ForwardCompatible
+ : GraphicsContextFlags.ForwardCompatible | GraphicsContextFlags.Debug)
{
WaitEvent = new ManualResetEvent(false);
@@ -73,6 +78,8 @@ namespace Ryujinx.Ui
| EventMask.KeyReleaseMask));
this.Shown += Renderer_Shown;
+
+ _glLogLevel = glLogLevel;
}
private static GraphicsMode GetGraphicsMode()
@@ -304,7 +311,7 @@ namespace Ryujinx.Ui
// First take exclusivity on the OpenGL context.
GraphicsContext.MakeCurrent(WindowInfo);
- _renderer.Initialize();
+ _renderer.Initialize(_glLogLevel);
// Make sure the first frame is not transparent.
GL.ClearColor(OpenTK.Color.Black);
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index 92e0c956..42870107 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -501,7 +501,7 @@ namespace Ryujinx.Ui
}
).ToArray());
- _glWidget = new GlRenderer(_emulationContext);
+ _glWidget = new GlRenderer(_emulationContext, ConfigurationState.Instance.Logger.GraphicsDebugLevel);
Application.Invoke(delegate
{
diff --git a/Ryujinx/Ui/SettingsWindow.cs b/Ryujinx/Ui/SettingsWindow.cs
index b488fdbb..5fe51854 100644
--- a/Ryujinx/Ui/SettingsWindow.cs
+++ b/Ryujinx/Ui/SettingsWindow.cs
@@ -1,6 +1,7 @@
using Gtk;
using Ryujinx.Audio;
using Ryujinx.Configuration;
+using Ryujinx.Common.Configuration;
using Ryujinx.Common.Configuration.Hid;
using Ryujinx.Configuration.System;
using Ryujinx.HLE.HOS.Services.Time.TimeZone;
@@ -35,6 +36,7 @@ namespace Ryujinx.Ui
[GUI] CheckButton _guestLogToggle;
[GUI] CheckButton _fsAccessLogToggle;
[GUI] Adjustment _fsLogSpinAdjustment;
+ [GUI] ComboBoxText _graphicsDebugLevel;
[GUI] CheckButton _dockedModeToggle;
[GUI] CheckButton _discordToggle;
[GUI] CheckButton _vSyncToggle;
@@ -149,6 +151,13 @@ namespace Ryujinx.Ui
_fsAccessLogToggle.Click();
}
+ foreach (GraphicsDebugLevel level in Enum.GetValues(typeof(GraphicsDebugLevel)))
+ {
+ _graphicsDebugLevel.Append(level.ToString(), level.ToString());
+ }
+
+ _graphicsDebugLevel.SetActiveId(ConfigurationState.Instance.Logger.GraphicsDebugLevel.Value.ToString());
+
if (ConfigurationState.Instance.System.EnableDockedMode)
{
_dockedModeToggle.Click();
@@ -496,6 +505,7 @@ namespace Ryujinx.Ui
ConfigurationState.Instance.Logger.EnableGuest.Value = _guestLogToggle.Active;
ConfigurationState.Instance.Logger.EnableFsAccessLog.Value = _fsAccessLogToggle.Active;
ConfigurationState.Instance.Logger.EnableFileLog.Value = _fileLogToggle.Active;
+ ConfigurationState.Instance.Logger.GraphicsDebugLevel.Value = Enum.Parse<GraphicsDebugLevel>(_graphicsDebugLevel.ActiveId);
ConfigurationState.Instance.System.EnableDockedMode.Value = _dockedModeToggle.Active;
ConfigurationState.Instance.EnableDiscordIntegration.Value = _discordToggle.Active;
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
diff --git a/Ryujinx/Ui/SettingsWindow.glade b/Ryujinx/Ui/SettingsWindow.glade
index 384fed4d..33ea05b7 100644
--- a/Ryujinx/Ui/SettingsWindow.glade
+++ b/Ryujinx/Ui/SettingsWindow.glade
@@ -2008,24 +2008,6 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="_debugLogToggle">
- <property name="label" translatable="yes">Enable Debug Logs</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="tooltip_text" translatable="yes">Enables printing debug log messages</property>
- <property name="halign">start</property>
- <property name="margin_top">5</property>
- <property name="margin_bottom">5</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
<object class="GtkCheckButton" id="_stubLogToggle">
<property name="label" translatable="yes">Enable Stub Logs</property>
<property name="visible">True</property>
@@ -2188,6 +2170,102 @@
<property name="position">0</property>
</packing>
</child>
+ <child>
+ <object class="GtkBox" id="CatDevLogging">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_left">5</property>
+ <property name="margin_right">5</property>
+ <property name="margin_top">10</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="margin_bottom">5</property>
+ <property name="tooltip_text" translatable="yes">Use with care</property>
+ <property name="label" translatable="yes">Developer Options</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">20</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox" id="DevLoggingOptions">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="valign">start</property>
+ <property name="margin_left">10</property>
+ <property name="margin_right">10</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkCheckButton" id="_debugLogToggle">
+ <property name="label" translatable="yes">Enable Debug Logs</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="tooltip_text" translatable="yes">Enables printing debug log messages</property>
+ <property name="halign">start</property>
+ <property name="margin_top">5</property>
+ <property name="margin_bottom">5</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">21</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="margin_top">5</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Requires appropriate log levels enabled. Not persistent across restarts.</property>
+ <property name="label" translatable="yes">OpenGL Log Level</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">5</property>
+ <property name="position">22</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="_graphicsDebugLevel">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="tooltip_text" translatable="yes">Requires appropriate log levels enabled. Not persistent across restarts.</property>
+ <property name="margin_left">5</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">22</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="padding">5</property>
+ <property name="position">22</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="position">4</property>