diff --git a/libobs-opengl/gl-subsystem.c b/libobs-opengl/gl-subsystem.c index d72cb229da099b3400c93a3f3b488c5e7d58d6e4..7457e15eb22d8570c54ada0ec518d9396f70cc89 100644 --- a/libobs-opengl/gl-subsystem.c +++ b/libobs-opengl/gl-subsystem.c @@ -18,6 +18,74 @@ #include #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); diff --git a/libobs-opengl/gl-x11.c b/libobs-opengl/gl-x11.c index 223641ae1c9b1ad02b7fb5f8e1a7661d6a4bcbd1..55acc0119d4b63f0a44fe925f24a34a0682556f6 100644 --- a/libobs-opengl/gl-x11.c +++ b/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);