[PATCH 05/11] glx: Optionally call DRI2 createContextAttribs from __glXDRIscreenCreateContext

Jesse Barnes jbarnes at virtuousgeek.org
Tue Jan 3 16:22:26 PST 2012


On Fri, 23 Dec 2011 15:18:23 -0800
"Ian Romanick" <idr at freedesktop.org> wrote:

> From: Ian Romanick <ian.d.romanick at intel.com>
> 
> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
> ---
>  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


More information about the xorg-devel mailing list