Fixed bug 1749 - SDL_GL_CreateContext() causes fatal X11 protocol errors that should just be caught instead
Lee Salzman When using SDL_GL_CreateContext() to create a >= 3.0 version or core/forward-compatible context, internally glXCreateContextAttribsARB is used. Mesa in particular seems to be having trouble with this call and returning all sorts of errors, so it is dangerous to poll for the highest GL version by using calls to SDL_GL_CreateContext unless you are sure, a priori, that the call will suceed, defeating the point of its use. X11 protocol errors are of the following form, with varying details depending on user, but the cause is always SDL_GL_CreateContext as above... X Error of failed request: GLXBadFBConfig Major opcode of failed request: 153 (GLX) Minor opcode of failed request: 34 () Serial number of failed request: 215 Current serial number in output stream: 221 These sorts of errors can be temporarily filtered out by setting an X11 error handler to catch and ignore them, which is safe with respect to SDL_GL_CreateContext behavior because this function is allowed to return NULL to indicate failure. A patch is attached to do this temporary filtering/catching of errors generated by trying to use glXCreateContextAttribs and friends...
This commit is contained in:
parent
1bb2a06fc7
commit
2422c520ac
1 changed files with 31 additions and 5 deletions
|
@ -496,6 +496,33 @@ X11_GL_GetVisual(_THIS, Display * display, int screen)
|
||||||
return vinfo;
|
return vinfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLXBadContext
|
||||||
|
#define GLXBadContext 0
|
||||||
|
#endif
|
||||||
|
#ifndef GLXBadFBConfig
|
||||||
|
#define GLXBadFBConfig 9
|
||||||
|
#endif
|
||||||
|
#ifndef GLXBadProfileARB
|
||||||
|
#define GLXBadProfileARB 13
|
||||||
|
#endif
|
||||||
|
static int (*handler) (Display *, XErrorEvent *) = NULL;
|
||||||
|
static int
|
||||||
|
X11_GL_CreateContextErrorHandler(Display * d, XErrorEvent * e)
|
||||||
|
{
|
||||||
|
switch (e->error_code) {
|
||||||
|
case GLXBadContext:
|
||||||
|
case GLXBadFBConfig:
|
||||||
|
case GLXBadProfileARB:
|
||||||
|
case BadRequest:
|
||||||
|
case BadMatch:
|
||||||
|
case BadValue:
|
||||||
|
case BadAlloc:
|
||||||
|
return (0);
|
||||||
|
default:
|
||||||
|
return (handler(d, e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_GLContext
|
SDL_GLContext
|
||||||
X11_GL_CreateContext(_THIS, SDL_Window * window)
|
X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
{
|
{
|
||||||
|
@ -516,6 +543,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
|
|
||||||
/* We do this to create a clean separation between X and GLX errors. */
|
/* We do this to create a clean separation between X and GLX errors. */
|
||||||
XSync(display, False);
|
XSync(display, False);
|
||||||
|
handler = XSetErrorHandler(X11_GL_CreateContextErrorHandler);
|
||||||
XGetWindowAttributes(display, data->xwindow, &xattr);
|
XGetWindowAttributes(display, data->xwindow, &xattr);
|
||||||
v.screen = screen;
|
v.screen = screen;
|
||||||
v.visualid = XVisualIDFromVisual(xattr.visual);
|
v.visualid = XVisualIDFromVisual(xattr.visual);
|
||||||
|
@ -532,10 +560,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
context to grab the new context creation function */
|
context to grab the new context creation function */
|
||||||
GLXContext temp_context =
|
GLXContext temp_context =
|
||||||
_this->gl_data->glXCreateContext(display, vinfo, NULL, True);
|
_this->gl_data->glXCreateContext(display, vinfo, NULL, True);
|
||||||
if (!temp_context) {
|
if (temp_context) {
|
||||||
SDL_SetError("Could not create GL context");
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
/* max 8 attributes plus terminator */
|
/* max 8 attributes plus terminator */
|
||||||
int attribs[9] = {
|
int attribs[9] = {
|
||||||
GLX_CONTEXT_MAJOR_VERSION_ARB,
|
GLX_CONTEXT_MAJOR_VERSION_ARB,
|
||||||
|
@ -609,7 +634,8 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
XFree(vinfo);
|
XFree(vinfo);
|
||||||
}
|
}
|
||||||
XSync(display, False);
|
XSync(display, False);
|
||||||
|
XSetErrorHandler(handler);
|
||||||
|
|
||||||
if (!context) {
|
if (!context) {
|
||||||
SDL_SetError("Could not create GL context");
|
SDL_SetError("Could not create GL context");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue