[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