Debugger.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. using OpenTK.Graphics.OpenGL;
  2. using Ryujinx.Common.Configuration;
  3. using Ryujinx.Common.Logging;
  4. using System;
  5. using System.Runtime.InteropServices;
  6. using System.Threading;
  7. namespace Ryujinx.Graphics.OpenGL
  8. {
  9. public static class Debugger
  10. {
  11. private static DebugProc _debugCallback;
  12. private static int _counter;
  13. public static void Initialize(GraphicsDebugLevel logLevel)
  14. {
  15. // Disable everything
  16. GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, false);
  17. if (logLevel == GraphicsDebugLevel.None)
  18. {
  19. GL.Disable(EnableCap.DebugOutputSynchronous);
  20. GL.DebugMessageCallback(null, IntPtr.Zero);
  21. return;
  22. }
  23. GL.Enable(EnableCap.DebugOutputSynchronous);
  24. if (logLevel == GraphicsDebugLevel.Error)
  25. {
  26. GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
  27. }
  28. else if (logLevel == GraphicsDebugLevel.Slowdowns)
  29. {
  30. GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypeError, DebugSeverityControl.DontCare, 0, (int[])null, true);
  31. GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DebugTypePerformance, DebugSeverityControl.DontCare, 0, (int[])null, true);
  32. }
  33. else
  34. {
  35. GL.DebugMessageControl(DebugSourceControl.DontCare, DebugTypeControl.DontCare, DebugSeverityControl.DontCare, 0, (int[])null, true);
  36. }
  37. _counter = 0;
  38. _debugCallback = GLDebugHandler;
  39. GL.DebugMessageCallback(_debugCallback, IntPtr.Zero);
  40. Logger.Warning?.Print(LogClass.Gpu, "OpenGL Debugging is enabled. Performance will be negatively impacted.");
  41. }
  42. private static void GLDebugHandler(
  43. DebugSource source,
  44. DebugType type,
  45. int id,
  46. DebugSeverity severity,
  47. int length,
  48. IntPtr message,
  49. IntPtr userParam)
  50. {
  51. string msg = Marshal.PtrToStringUTF8(message).Replace('\n', ' ');
  52. switch (type)
  53. {
  54. case DebugType.DebugTypeError:
  55. Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR");
  56. break;
  57. case DebugType.DebugTypePerformance:
  58. Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF");
  59. break;
  60. case DebugType.DebugTypePushGroup:
  61. Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO");
  62. break;
  63. case DebugType.DebugTypePopGroup:
  64. Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO");
  65. break;
  66. default:
  67. if (source == DebugSource.DebugSourceApplication)
  68. {
  69. Logger.Info?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLINFO");
  70. }
  71. else
  72. {
  73. Logger.Debug?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLDEBUG");
  74. }
  75. break;
  76. }
  77. }
  78. // Useful debug helpers
  79. public static void PushGroup(string dbgMsg)
  80. {
  81. int counter = Interlocked.Increment(ref _counter);
  82. GL.PushDebugGroup(DebugSourceExternal.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg);
  83. }
  84. public static void PopGroup()
  85. {
  86. GL.PopDebugGroup();
  87. }
  88. public static void Print(string dbgMsg, DebugType type = DebugType.DebugTypeMarker, DebugSeverity severity = DebugSeverity.DebugSeverityNotification, int id = 999999)
  89. {
  90. GL.DebugMessageInsert(DebugSourceExternal.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg);
  91. }
  92. }
  93. }