[PATCH 05/11] glx: Optionally call DRI2 createContextAttribs from __glXDRIscreenCreateContext
Ian Romanick
idr at freedesktop.org
Tue Jan 3 16:45:49 PST 2012
On 01/03/2012 04:22 PM, Jesse Barnes wrote:
> 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.
The spec doesn't say anything about this case, so I don't think there's
any behavior that an application could rely on. It might be interesting
to see what the other guys do, but I'm not very concerned about that
right now.
>> +
>> + /* 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.
I had thought about both of these, and ultimately we just want at later.
However, that requires a new Mesa release. I thought it was better to
leave the "obvious" clutter of the #ifdef in the code for later clean-up
than an extra function.
What do you think?
More information about the xorg-devel
mailing list