Debugger.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 : Logger.Error?.Print(LogClass.Gpu, $"{severity}: {msg}\nCallStack={Environment.StackTrace}", "GLERROR"); break;
  55. case DebugType.DebugTypePerformance: Logger.Warning?.Print(LogClass.Gpu, $"{severity}: {msg}", "GLPERF"); break;
  56. case DebugType.DebugTypePushGroup : Logger.Info?.Print(LogClass.Gpu, $"{{ ({id}) {severity}: {msg}", "GLINFO"); break;
  57. case DebugType.DebugTypePopGroup : Logger.Info?.Print(LogClass.Gpu, $"}} ({id}) {severity}: {msg}", "GLINFO"); break;
  58. default:
  59. if (source == DebugSource.DebugSourceApplication)
  60. {
  61. Logger.Info?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLINFO");
  62. }
  63. else
  64. {
  65. Logger.Debug?.Print(LogClass.Gpu, $"{type} {severity}: {msg}", "GLDEBUG");
  66. }
  67. break;
  68. }
  69. }
  70. // Useful debug helpers
  71. public static void PushGroup(string dbgMsg)
  72. {
  73. int counter = Interlocked.Increment(ref _counter);
  74. GL.PushDebugGroup(DebugSourceExternal.DebugSourceApplication, counter, dbgMsg.Length, dbgMsg);
  75. }
  76. public static void PopGroup()
  77. {
  78. GL.PopDebugGroup();
  79. }
  80. public static void Print(string dbgMsg, DebugType type = DebugType.DebugTypeMarker, DebugSeverity severity = DebugSeverity.DebugSeverityNotification, int id = 999999)
  81. {
  82. GL.DebugMessageInsert(DebugSourceExternal.DebugSourceApplication, type, id, severity, dbgMsg.Length, dbgMsg);
  83. }
  84. }
  85. }