diff --git a/src/glx/create_context.c b/src/glx/create_context.c index 38e949ab4cd..11c1466ddcd 100644 --- a/src/glx/create_context.c +++ b/src/glx/create_context.c @@ -47,7 +47,7 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, xcb_generic_error_t *err; xcb_void_cookie_t cookie; unsigned dummy_err = 0; - + uint32_t xid, share_xid; if (dpy == NULL || cfg == NULL) return NULL; @@ -90,8 +90,8 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, #endif } - gc->xid = xcb_generate_id(c); - gc->share_xid = (share != NULL) ? share->xid : 0; + xid = xcb_generate_id(c); + share_xid = (share != NULL) ? share->xid : 0; /* The manual pages for glXCreateContext and glXCreateNewContext say: * @@ -103,21 +103,31 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, */ cookie = xcb_glx_create_context_attribs_arb_checked(c, - gc->xid, + xid, cfg->fbconfigID, cfg->screen, - gc->share_xid, - gc->isDirect, + share_xid, + gc ? gc->isDirect : direct, num_attribs, (const uint32_t *) attrib_list); err = xcb_request_check(c, cookie); if (err != NULL) { - gc->vtable->destroy(gc); + if (gc) + gc->vtable->destroy(gc); gc = NULL; __glXSendErrorForXcb(dpy, err); free(err); + } else if (!gc) { + /* the server thought the context description was okay, but we failed + * somehow on the client side. clean up the server resource and panic. + */ + xcb_glx_destroy_context(c, xid); + __glXSendError(dpy, GLXBadFBConfig, xid, 0, False); + } else { + gc->xid = xid; + gc->share_xid = share_xid; } return (GLXContext) gc; diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c index a7a6ba5f13b..5c8e71beb39 100644 --- a/src/glx/indirect_glx.c +++ b/src/glx/indirect_glx.c @@ -382,6 +382,9 @@ indirect_create_context_attribs(struct glx_screen *psc, CARD8 opcode; __GLXattribute *state; int i, renderType = GLX_RGBA_TYPE; + uint32_t mask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + uint32_t major = 1; + uint32_t minor = 0; opcode = __glXSetupForCommand(psc->dpy); if (!opcode) { @@ -393,6 +396,21 @@ indirect_create_context_attribs(struct glx_screen *psc, if (attr == GLX_RENDER_TYPE) renderType = val; + if (attr == GLX_CONTEXT_PROFILE_MASK_ARB) + mask = val; + if (attr == GLX_CONTEXT_MAJOR_VERSION_ARB) + major = val; + if (attr == GLX_CONTEXT_MINOR_VERSION_ARB) + minor = val; + } + + /* We have no indirect support for core or ES contexts, and our compat + * context support is limited to GL 1.4. + */ + if (mask != GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB || + major != 1 || + minor > 4) { + return NULL; } /* Allocate our context record */ diff --git a/src/glx/tests/create_context_unittest.cpp b/src/glx/tests/create_context_unittest.cpp index a2590589db2..448dbea10f6 100644 --- a/src/glx/tests/create_context_unittest.cpp +++ b/src/glx/tests/create_context_unittest.cpp @@ -101,6 +101,15 @@ xcb_glx_create_context_attribs_arb_checked(xcb_connection_t *c, return cookie; } +extern "C" xcb_void_cookie_t +xcb_glx_destroy_context(xcb_connection_t *c, xcb_glx_context_t context) +{ + xcb_void_cookie_t cookie; + cookie.sequence = 0xbadc0de; + + return cookie; +} + extern "C" xcb_generic_error_t * xcb_request_check(xcb_connection_t *c, xcb_void_cookie_t cookie) {