Explorar o código

Added OpenGL debug callback support and context changes.

1. We no longer hardcode a 3.2 profile. It chooses the latest profile that fits out description.
2. I added three tables and macros to help with the offsets compared to the variables to help reading. Read comments for more info.
3. I added glewExperimental being set. What a dumb "feature". It doesn't help anything...
Zachary Lund %!s(int64=11) %!d(string=hai) anos
pai
achega
94f88c82cf
Modificáronse 2 ficheiros con 80 adicións e 13 borrados
  1. 72 6
      libobs-opengl/gl-subsystem.c
  2. 8 7
      libobs-opengl/gl-x11.c

+ 72 - 6
libobs-opengl/gl-subsystem.c

@@ -18,6 +18,74 @@
 #include <graphics/matrix3.h>
 #include "gl-subsystem.h"
 
+/* Tables for OpenGL debug */
+static const char* debug_source_table[] = {
+	"API",
+	"Window System",
+	"Shader Compiler",
+	"Third Party"
+	"Application",
+	"Other"
+};
+
+static const char* debug_type_table[] = {
+	"Error",
+	"Deprecated Behavior",
+	"Undefined Behavior",
+	"Portability",
+	"Performance",
+	"Other"
+};
+
+static const char* debug_severity_table[] = {
+	"High",
+	"Medium",
+	"Low"
+};
+
+/* ARB and core values are the same. They'll always be linear so no hardcoding. */
+/* The values subtracted are the lowest value in the list of valid values. */
+#define GL_DEBUG_SOURCE_OFFSET(x) (x - GL_DEBUG_SOURCE_API_ARB)
+#define GL_DEBUG_TYPE_OFFSET(x) (x - GL_DEBUG_TYPE_ERROR_ARB)
+#define GL_DEBUG_SEVERITY_OFFSET(x) (x - GL_DEBUG_SEVERITY_HIGH_ARB)
+
+#ifdef _DEBUG
+static void gl_debug_proc(
+	GLenum source, GLenum type, GLuint id, GLenum severity, 
+	GLsizei length, const GLchar *message, GLvoid *data )
+{
+	blog(	LOG_DEBUG,
+		"[%s][%s]{%}: %.*s",
+		debug_source_table[GL_DEBUG_SOURCE_OFFSET(source)],
+		debug_type_table[GL_DEBUG_TYPE_OFFSET(type)],
+		debug_severity_table[GL_DEBUG_SEVERITY_OFFSET(severity)],
+		length, message
+	);
+}
+
+static void gl_enable_debug()
+{
+	 /* Perhaps we should create GLEW contexts? */
+
+	if (GLEW_VERSION_4_0)
+		glDebugMessageCallback(gl_debug_proc, NULL);
+	else if (GLEW_ARB_debug_output) {
+		glDebugMessageCallbackARB(gl_debug_proc, NULL);
+	} else {
+		blog(LOG_DEBUG, "Failed to set GL debug callback as it is not supported.");
+		return;
+	}
+
+	glEnable(GL_DEBUG_OUTPUT);
+	if (glGetError() == GL_INVALID_ENUM)
+		blog(LOG_DEBUG, "OpenGL debug information not available"); /* Debug callback simply won't be called. */
+	else
+		blog(LOG_DEBUG, "Successfully hooked into OpenGL debug message callback.");
+}
+#else
+static void gl_enable_debug() {}
+#endif
+
 static void clear_textures(struct gs_device *device)
 {
 	GLenum i;
@@ -69,6 +137,9 @@ device_t device_create(struct gs_init_data *info)
 	if (!device->plat)
 		goto fail;
 
+	/* We expect platform specific code to initialize GLEW as they might use it themselves anyways. */
+	/* Also, that code needs to set glewExperimental to true (since it fails to set core functionality like a dum dum) */
+	
 	glGenProgramPipelines(1, &device->pipeline);
 	if (!gl_success("glGenProgramPipelines"))
 		goto fail;
@@ -77,12 +148,7 @@ device_t device_create(struct gs_init_data *info)
 	if (!gl_success("glBindProgramPipeline"))
 		goto fail;
 
-#ifdef _DEBUG
-	glEnable(GL_DEBUG_OUTPUT);
-	if (glGetError() == GL_INVALID_ENUM)
-		blog(LOG_DEBUG, "OpenGL debug information not available");
-#endif
-
+	gl_enable_debug();
 	gl_enable(GL_CULL_FACE);
 
 	device_leavecontext(device);

+ 8 - 7
libobs-opengl/gl-x11.c

@@ -19,12 +19,11 @@ static const GLenum fb_attribs[] = {
 };
 
 static const GLenum ctx_attribs[] = {
-	GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
-	GLX_CONTEXT_MINOR_VERSION_ARB, 2,
-	GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB |
-	                       GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+#ifdef _DEBUG
+	GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
+#endif
 	GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
-	0, 0
+	None, 
 };
 
 static const char* __GLX_error_table[] = {
@@ -169,17 +168,19 @@ struct gl_platform *gl_platform_create(device_t device,
 		goto fail2;
 	}
 
-	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));
-
 	/* Initialize GLEW */
 	{
 		GLenum err = glewInit();
+		glewExperimental = true;
+		
 		if (GLEW_OK != err) {
 			blog(LOG_ERROR, glewGetErrorString(err));
 			goto fail2;
 		}
 	}
 	
+	blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));
+	
 	glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
 	glEnable(GL_DEBUG_OUTPUT);
 	glEnable(GL_CULL_FACE);