On Fri, 23 Dec 2011 15:18:23 -0800 "Ian Romanick" <[email protected]> wrote:
> From: Ian Romanick <[email protected]> > > Signed-off-by: Ian Romanick <[email protected]> > --- > glx/glxdri2.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > 1 files changed, 137 insertions(+), 6 deletions(-) > > diff --git a/glx/glxdri2.c b/glx/glxdri2.c > index 18b5aad..4f112b1 100644 > --- a/glx/glxdri2.c > +++ b/glx/glxdri2.c > @@ -47,6 +47,7 @@ > #include "glxserver.h" > #include "glxutil.h" > #include "glxdricommon.h" > +#include <GL/glxtokens.h> > > #include "glapitable.h" > #include "glapi.h" > @@ -383,6 +384,56 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) > free(screen); > } > > +static Bool > +dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs, > + unsigned *major_ver, unsigned *minor_ver, > + uint32_t *flags, unsigned *error) > +{ > + unsigned i; > + > + if (num_attribs == 0) > + return True; > + > + if (attribs == NULL) { > + *error = BadImplementation; > + return False; > + } > + > + *major_ver = 1; > + *minor_ver = 0; > + > + for (i = 0; i < num_attribs; i++) { > + switch (attribs[i * 2]) { > + case GLX_CONTEXT_MAJOR_VERSION_ARB: > + *major_ver = attribs[i * 2 + 1]; > + break; > + case GLX_CONTEXT_MINOR_VERSION_ARB: > + *minor_ver = attribs[i * 2 + 1]; > + break; > + case GLX_CONTEXT_FLAGS_ARB: > + *flags = attribs[i * 2 + 1]; > + break; > + case GLX_RENDER_TYPE: > + break; > + default: > + /* If an unknown attribute is received, fail. > + */ > + *error = BadValue; > + return False; > + } > + } Do you want to catch the case where multiple versions and/or flags are provided and error out? Pretty esoteric I guess but I'm not sure what the semantics are supposed to be. > + > + /* Unknown flag value. > + */ > + if (*flags & ~(__DRI_CTX_FLAG_DEBUG | > __DRI_CTX_FLAG_FORWARD_COMPATIBLE)) { > + *error = BadValue; > + return False; > + } > + > + *error = Success; > + return True; > +} > + > static __GLXcontext * > __glXDRIscreenCreateContext(__GLXscreen *baseScreen, > __GLXconfig *glxConfig, > @@ -403,8 +454,10 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, > driShare = NULL; > > context = calloc(1, sizeof *context); > - if (context == NULL) > + if (context == NULL) { > + *error = BadAlloc; > return NULL; > + } > > context->base.destroy = __glXDRIcontextDestroy; > context->base.makeCurrent = __glXDRIcontextMakeCurrent; > @@ -413,12 +466,82 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, > context->base.textureFromPixmap = &__glXDRItextureFromPixmap; > context->base.wait = __glXDRIcontextWait; > > - context->driContext = > - (*screen->dri2->createNewContext)(screen->driScreen, > - config->driConfig, > - driShare, context); > +#if __DRI_DRI2_VERSION >= 3 > + if (screen->dri2->base.version >= 3) { > + uint32_t ctx_attribs[3 * 2]; > + unsigned num_ctx_attribs = 0; > + unsigned dri_err = 0; > + unsigned major_ver; > + unsigned minor_ver; > + uint32_t flags; > + > + if (num_attribs != 0) { > + if (!dri2_convert_glx_attribs(num_attribs, attribs, > + &major_ver, &minor_ver, > + &flags, error)) > + return NULL; > + > + ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION; > + ctx_attribs[num_ctx_attribs++] = major_ver; > + ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MINOR_VERSION; > + ctx_attribs[num_ctx_attribs++] = minor_ver; > + > + if (flags != 0) { > + ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_FLAGS; > + > + /* The current __DRI_CTX_FLAG_* values are identical to the > + * GLX_CONTEXT_*_BIT values. > + */ > + ctx_attribs[num_ctx_attribs++] = flags; > + } > + } > + > + context->driContext = > + (*screen->dri2->createContextAttribs)(screen->driScreen, > + __DRI_API_OPENGL, > + config->driConfig, > + driShare, > + num_ctx_attribs / 2, > + ctx_attribs, > + &dri_err, > + context); > + > + switch (dri_err) { > + case __DRI_CTX_ERROR_SUCCESS: > + *error = Success; > + break; > + case __DRI_CTX_ERROR_NO_MEMORY: > + *error = BadAlloc; > + break; > + case __DRI_CTX_ERROR_BAD_API: > + *error = __glXError(GLXBadProfileARB); > + break; > + case __DRI_CTX_ERROR_BAD_VERSION: > + case __DRI_CTX_ERROR_BAD_FLAG: > + *error = __glXError(GLXBadFBConfig); > + break; > + case __DRI_CTX_ERROR_UNKNOWN_ATTRIBUTE: > + case __DRI_CTX_ERROR_UNKNOWN_FLAG: > + default: > + *error = BadValue; > + break; > + } > + } else > +#endif Maybe stuff this into a separate function that's a no-op in the < 3 case? That would clean things up a little and save an #ifdef in the middle of a function (always a nice thing). Or just require updated DRI2 bits to build and avoid the ifdefs altogether, since they tend to cause trouble anyway. -- Jesse Barnes, Intel Open Source Technology Center _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
