2019-10-13 08:02:07 +02:00
|
|
|
using OpenTK.Graphics.OpenGL;
|
2020-08-02 16:41:24 +02:00
|
|
|
using Ryujinx.Common.Configuration;
|
2019-12-29 00:45:33 +01:00
|
|
|
using Ryujinx.Common.Logging;
|
2019-10-13 08:02:07 +02:00
|
|
|
using System;
|
|
|
|
using System.Runtime.InteropServices;
|
2020-08-02 16:41:24 +02:00
|
|
|
using System.Threading;
|
2019-10-13 08:02:07 +02:00
|
|
|
|
|
|
|
namespace Ryujinx.Graphics.OpenGL
|
|
|
|
{
|
|
|
|
public static class Debugger
|
|
|
|
{
|
|
|
|
private static DebugProc _debugCallback;
|
|
|
|
|
2020-08-02 16:41:24 +02:00
|
|
|
private static int _counter;
|
|
|
|
|
|
|
|
public static void Initialize(GraphicsDebugLevel logLevel)
|
2019-10-13 08:02:07 +02:00
|
|
|
{
|
2020-08-02 16:41:24 +02:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2019-10-13 08:02:07 +02:00
|
|
|
GL.Enable(EnableCap.DebugOutputSynchronous);
|
|
|
|
|
2020-08-02 16:41:24 +02:00
|
|
|
if (logLevel == GraphicsDebugLevel.Error)
|
|
|
|
{
|
|
|
|
GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
|
|
|
|
}
|
2020-08-07 15:30:06 +02:00
|
|
|
else if (logLevel == GraphicsDebugLevel.Slowdowns)
|
2020-08-02 16:41:24 +02:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2019-10-13 08:02:07 +02:00
|
|
|
|
2020-08-02 16:41:24 +02:00
|
|
|
_counter = 0;
|
2019-12-29 00:45:33 +01:00
|
|
|
_debugCallback = GLDebugHandler;
|
2019-10-13 08:02:07 +02:00
|
|
|
|
|
|
|
GL.DebugMessageCallback(_debugCallback, IntPtr.Zero);
|
2020-08-02 16:41:24 +02:00
|
|
|
|
2020-08-04 01:32:53 +02:00
|
|
|
Logger.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
|
2019-10-13 08:02:07 +02:00
|
|
|
}
|
|
|
|
|
2019-12-29 00:45:33 +01:00
|
|
|
private static void GLDebugHandler(
|
2019-10-13 08:02:07 +02:00
|
|
|
DebugSource source,
|
|
|
|
DebugType type,
|
|
|
|
int id,
|
|
|
|
DebugSeverity severity,
|
|
|
|
int length,
|
|
|
|
IntPtr message,
|
|
|
|
IntPtr userParam)
|
|
|
|
{
|
2020-08-02 16:41:24 +02:00
|
|
|
string msg = Marshal.PtrToStringUTF8(message).Replace('\n', ' ');
|
2019-10-13 08:02:07 +02:00
|
|
|
|
2019-12-29 00:45:33 +01:00
|
|
|
switch (type)
|
2019-10-13 08:02:07 +02:00
|
|
|
{
|
2023-06-28 18:10:55 +02:00
|
|
|
case DebugType.DebugTypeError:
|
|
|
|
Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR");
|
|
|
|
break;
|
|
|
|
case DebugType.DebugTypePerformance:
|
|
|
|
Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF");
|
|
|
|
break;
|
|
|
|
case DebugType.DebugTypePushGroup:
|
|
|
|
Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO");
|
|
|
|
break;
|
|
|
|
case DebugType.DebugTypePopGroup:
|
|
|
|
Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO");
|
|
|
|
break;
|
2019-12-29 00:45:33 +01:00
|
|
|
default:
|
2020-08-02 16:41:24 +02:00
|
|
|
if (source == DebugSource.DebugSourceApplication)
|
|
|
|
{
|
2020-08-04 01:32:53 +02:00
|
|
|
Logger.Info?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLINFO");
|
2020-08-02 16:41:24 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-08-04 01:32:53 +02:00
|
|
|
Logger.Debug?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLDEBUG");
|
2020-08-02 16:41:24 +02:00
|
|
|
}
|
2019-12-29 00:45:33 +01:00
|
|
|
break;
|
2019-10-13 08:02:07 +02:00
|
|
|
}
|
|
|
|
}
|
2020-08-02 16:41:24 +02:00
|
|
|
|
|
|
|
// 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);
|
|
|
|
}
|
2019-10-13 08:02:07 +02:00
|
|
|
}
|
|
|
|
}
|