summaryrefslogtreecommitdiff
path: root/src/video/opengl.cpp
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2021-01-16 16:43:07 +0100
committerMichael Lutz <michi@icosahedron.de>2021-02-22 22:16:07 +0100
commit3a77ade6b25d34890f51931e874fbe0e3b48a744 (patch)
tree3b6c800294613b9446fd5713e21db456f1a9ae60 /src/video/opengl.cpp
parentd7b96a424fdd939aa7de65153e3b9baa20edf626 (diff)
downloadopenttd-3a77ade6b25d34890f51931e874fbe0e3b48a744.tar.xz
Codechange: [OpenGL] Enable driver debug messages if supported.
Diffstat (limited to 'src/video/opengl.cpp')
-rw-r--r--src/video/opengl.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/video/opengl.cpp b/src/video/opengl.cpp
index c811be2ef..dbb5ee01a 100644
--- a/src/video/opengl.cpp
+++ b/src/video/opengl.cpp
@@ -30,6 +30,9 @@
#include "../safeguards.h"
+static PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
+static PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
+
/* static */ OpenGLBackend *OpenGLBackend::instance = nullptr;
GetOGLProcAddressProc GetOGLProcAddress;
@@ -109,6 +112,59 @@ bool IsOpenGLVersionAtLeast(byte major, byte minor)
return (_gl_major_ver > major) || (_gl_major_ver == major && _gl_minor_ver >= minor);
}
+/** Callback to receive OpenGL debug messages. */
+void APIENTRY DebugOutputCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
+{
+ /* Make severity human readable. */
+ const char *severity_str = "";
+ switch (severity) {
+ case GL_DEBUG_SEVERITY_HIGH: severity_str = "high"; break;
+ case GL_DEBUG_SEVERITY_MEDIUM: severity_str = "medium"; break;
+ case GL_DEBUG_SEVERITY_LOW: severity_str = "low"; break;
+ }
+
+ /* Make type human readable.*/
+ const char *type_str = "Other";
+ switch (type) {
+ case GL_DEBUG_TYPE_ERROR: type_str = "Error"; break;
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: type_str = "Deprecated"; break;
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: type_str = "Undefined behaviour"; break;
+ case GL_DEBUG_TYPE_PERFORMANCE: type_str = "Performance"; break;
+ case GL_DEBUG_TYPE_PORTABILITY: type_str = "Portability"; break;
+ }
+
+ DEBUG(driver, 6, "OpenGL: %s (%s) - %s", type_str, severity_str, message);
+}
+
+/** Enable OpenGL debug messages if supported. */
+void SetupDebugOutput()
+{
+#ifndef NO_DEBUG_MESSAGES
+ if (_debug_driver_level < 6) return;
+
+ if (IsOpenGLVersionAtLeast(4, 3)) {
+ _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)GetOGLProcAddress("glDebugMessageControl");
+ _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)GetOGLProcAddress("glDebugMessageCallback");
+ } else if (IsOpenGLExtensionSupported("GL_ARB_debug_output")) {
+ _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)GetOGLProcAddress("glDebugMessageControlARB");
+ _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)GetOGLProcAddress("glDebugMessageCallbackARB");
+ }
+
+ if (_glDebugMessageControl != nullptr && _glDebugMessageCallback != nullptr) {
+ /* Enable debug output. As synchronous debug output costs performance, we only enable it with a high debug level. */
+ glEnable(GL_DEBUG_OUTPUT);
+ if (_debug_driver_level >= 8) glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
+
+ _glDebugMessageCallback(&DebugOutputCallback, nullptr);
+ /* Enable all messages on highest debug level.*/
+ _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, _debug_driver_level >= 9 ? GL_TRUE : GL_FALSE);
+ /* Get debug messages for errors and undefined/deprecated behaviour. */
+ _glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
+ _glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
+ _glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE);
+ }
+#endif
+}
/**
* Create and initialize the singleton back-end class.
@@ -169,6 +225,8 @@ const char *OpenGLBackend::Init()
_gl_major_ver = atoi(ver);
_gl_minor_ver = minor != nullptr ? atoi(minor + 1) : 0;
+ SetupDebugOutput();
+
/* OpenGL 1.3 is the absolute minimum. */
if (!IsOpenGLVersionAtLeast(1, 3)) return "OpenGL version >= 1.3 required";
/* Check for non-power-of-two texture support. */