glx/indirect: Validate the context version in CreateContextAttribs

This is Sort Of handled by nerfing GL_VERSION in __indirect_glGetString,
but that doesn't cover GLES contexts which we also don't have any
indirect support for. Xorg's GLX would reject this for us since it has
the same limitation, but NVIDIA's GLX seems to interpret a request for
ES 2.0 as desktop, despite having the ES2 profile bit set, leading to a
very confusing GL_VERSION string and probably not the ES2-compatible
context you were hoping for.

Since we may now return NULL from indirect_create_context_attribs for
reasons other than malloc failure, we need to reasonably handle the case
where gc == NULL by the time we get to the XCB call. We rely on the
server to generate correct return values in this case, but if it
succeeds despite our client-side failure we just throw GLXBadFBConfig
(chosen to keep piglit/glx-create-context-core-profile happy, since
nothing else seems to hit it).

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7369>
This commit is contained in:
Adam Jackson 2020-11-10 16:23:23 -05:00 committed by Marge Bot
parent 6a265420dd
commit f39fd3dce7
3 changed files with 44 additions and 7 deletions

View file

@ -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;

View file

@ -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 */

View file

@ -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)
{