101 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 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
 | |
| {
 | |
|     public static class Debugger
 | |
|     {
 | |
|         private static DebugProc _debugCallback;
 | |
| 
 | |
|         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);
 | |
| 
 | |
|             if (logLevel == GraphicsDebugLevel.Error)
 | |
|             {
 | |
|                 GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
 | |
|             }
 | |
|             else if (logLevel == GraphicsDebugLevel.Slowdowns)
 | |
|             {
 | |
|                 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.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
 | |
|         }
 | |
| 
 | |
|         private static void GLDebugHandler(
 | |
|             DebugSource source,
 | |
|             DebugType type,
 | |
|             int id,
 | |
|             DebugSeverity severity,
 | |
|             int length,
 | |
|             IntPtr message,
 | |
|             IntPtr userParam)
 | |
|         {
 | |
|             string msg = Marshal.PtrToStringUTF8(message).Replace('\n', ' ');
 | |
| 
 | |
|             switch (type)
 | |
|             {
 | |
|                 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;
 | |
|                 default:
 | |
|                     if (source == DebugSource.DebugSourceApplication)
 | |
|                     {
 | |
|                         Logger.Info?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLINFO");
 | |
|                     }
 | |
|                     else
 | |
|                     {
 | |
|                         Logger.Debug?.Print(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);
 | |
|         }
 | |
|     }
 | |
| }
 | 
