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

Reply via email to