From f5d96416ad0e2d09f222c25fa7e8bb0d8399b0f1 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 6 Mar 2015 16:03:40 +0000 Subject: [PATCH] Allow setting of GL_CONTEXT_RELEASE_BEHAVIOR when creating the GL context when GLX_ARB_context_flush_control is available. This extension allows the user to specify whether a full flush is performed when making a context not current. The only way to set this currently is at context creation, so this patch provides that functionality. Defualt behaviour is set at FLUSH, as per the spec. This patch does not contain the changes to WGL, appleGL or other platforms as I do not have access to GL 4.5 hardware on those platforms. Full details on the use of KHR_context_flush_control can be found here: https://www.opengl.org/registry/specs/KHR/context_flush_control.txt --- include/SDL_opengl_glext.h | 5 +++++ include/SDL_video.h | 9 ++++++++- src/video/SDL_sysvideo.h | 1 + src/video/SDL_video.c | 11 +++++++++++ src/video/x11/SDL_x11opengl.c | 25 +++++++++++++++++++++++-- src/video/x11/SDL_x11opengl.h | 1 + 6 files changed, 49 insertions(+), 3 deletions(-) diff --git a/include/SDL_opengl_glext.h b/include/SDL_opengl_glext.h index 7e840f72a83a4..cd3869fe7f1e5 100644 --- a/include/SDL_opengl_glext.h +++ b/include/SDL_opengl_glext.h @@ -2988,6 +2988,11 @@ GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); #define GL_ARB_framebuffer_sRGB 1 #endif /* GL_ARB_framebuffer_sRGB */ +#ifndef GL_KHR_context_flush_control +#define GL_CONTEXT_RELEASE_BEHAVIOR 0x82FB +#define GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH 0x82FC +#endif /* GL_KHR_context_flush_control */ + #ifndef GL_ARB_geometry_shader4 #define GL_ARB_geometry_shader4 1 #define GL_LINES_ADJACENCY_ARB 0x000A diff --git a/include/SDL_video.h b/include/SDL_video.h index 4a2fb04588386..782fcb0fb663f 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -189,7 +189,8 @@ typedef enum SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_SHARE_WITH_CURRENT_CONTEXT, - SDL_GL_FRAMEBUFFER_SRGB_CAPABLE + SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR } SDL_GLattr; typedef enum @@ -207,6 +208,12 @@ typedef enum SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008 } SDL_GLcontextFlag; +typedef enum +{ + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, + SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001 +} SDL_GLcontextReleaseFlag; + /* Function prototypes */ diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index 2f07255507a6d..6966f2bd331e7 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -303,6 +303,7 @@ struct SDL_VideoDevice int flags; int profile_mask; int share_with_current_context; + int release_behavior; int framebuffer_srgb_capable; int retained_backing; int driver_loaded; diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 1dcfabf08cc21..ebe102c3d435e 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -2637,6 +2637,7 @@ SDL_GL_ResetAttributes() #endif _this->gl_config.flags = 0; _this->gl_config.framebuffer_srgb_capable = 0; + _this->gl_config.release_behavior = SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH; _this->gl_config.share_with_current_context = 0; } @@ -2743,6 +2744,9 @@ SDL_GL_SetAttribute(SDL_GLattr attr, int value) case SDL_GL_FRAMEBUFFER_SRGB_CAPABLE: _this->gl_config.framebuffer_srgb_capable = value; break; + case SDL_GL_CONTEXT_RELEASE_BEHAVIOR: + _this->gl_config.release_behavior = value; + break; default: retval = SDL_SetError("Unknown OpenGL attribute"); break; @@ -2843,6 +2847,13 @@ SDL_GL_GetAttribute(SDL_GLattr attr, int *value) attrib = GL_SAMPLES_ARB; #else attrib = GL_SAMPLES; +#endif + break; + case SDL_GL_CONTEXT_RELEASE_BEHAVIOR: +#if SDL_VIDEO_OPENGL + attrib = GL_CONTEXT_RELEASE_BEHAVIOR; +#else + attrib = GL_CONTEXT_RELEASE_BEHAVIOR_KHR; #endif break; case SDL_GL_BUFFER_SIZE: diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index f89a9cc0acc5d..df6008ccd9bcf 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -122,6 +122,13 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display * dpy, #define GLX_LATE_SWAPS_TEAR_EXT 0x20F3 #endif +#ifndef GLX_ARB_context_flush_control +#define GLX_ARB_context_flush_control +#define GLX_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0x0000 +#define GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098 +#endif + #define OPENGL_REQUIRES_DLOPEN #if defined(OPENGL_REQUIRES_DLOPEN) && defined(SDL_LOADSO_DLOPEN) #include @@ -375,6 +382,11 @@ X11_GL_InitExtensions(_THIS) if (HasExtension("GLX_EXT_create_context_es2_profile", extensions)) { _this->gl_data->HAS_GLX_EXT_create_context_es2_profile = SDL_TRUE; } + + /* Check for GLX_ARB_context_flush_control */ + if (HasExtension("GLX_ARB_context_flush_control", extensions)) { + _this->gl_data->HAS_GLX_ARB_context_flush_control = SDL_TRUE; + } } /* glXChooseVisual and glXChooseFBConfig have some small differences in @@ -581,8 +593,8 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) context = _this->gl_data->glXCreateContext(display, vinfo, share_context, True); } else { - /* max 8 attributes plus terminator */ - int attribs[9] = { + /* max 10 attributes plus terminator */ + int attribs[11] = { GLX_CONTEXT_MAJOR_VERSION_ARB, _this->gl_config.major_version, GLX_CONTEXT_MINOR_VERSION_ARB, @@ -603,6 +615,15 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) attribs[iattr++] = _this->gl_config.flags; } + /* only set if glx extension is available */ + if( _this->gl_data->HAS_GLX_ARB_context_flush_control ) { + attribs[iattr++] = GLX_CONTEXT_RELEASE_BEHAVIOR_ARB; + attribs[iattr++] = + _this->gl_config.release_behavior ? + GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB : + GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB; + } + attribs[iattr++] = 0; /* Get a pointer to the context creation function for GL 3.0 */ diff --git a/src/video/x11/SDL_x11opengl.h b/src/video/x11/SDL_x11opengl.h index b3410fd46242e..5856c9b79d4a6 100644 --- a/src/video/x11/SDL_x11opengl.h +++ b/src/video/x11/SDL_x11opengl.h @@ -35,6 +35,7 @@ struct SDL_GLDriverData SDL_bool HAS_GLX_EXT_visual_info; SDL_bool HAS_GLX_EXT_swap_control_tear; SDL_bool HAS_GLX_EXT_create_context_es2_profile; + SDL_bool HAS_GLX_ARB_context_flush_control; Bool (*glXQueryExtension) (Display*,int*,int*); void *(*glXGetProcAddress) (const GLubyte*);