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

Ian Romanick idr at freedesktop.org
Fri Dec 23 15:18:23 PST 2011


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;
+	}
+    }
+
+    /* 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
+    {
+	if (num_attribs != 0) {
+	    *error = BadValue;
+	    return NULL;
+	}
+
+	context->driContext =
+	    (*screen->dri2->createNewContext)(screen->driScreen,
+					      config->driConfig,
+					      driShare, context);
+    }
+
     if (context->driContext == NULL) {
-	    free(context);
+	free(context);
         return NULL;
     }
 
@@ -655,6 +778,14 @@ initializeExtensions(__GLXDRIscreen *screen)
     __glXEnableExtension(screen->glx_enable_bits, "GLX_INTEL_swap_event");
     LogMessage(X_INFO, "AIGLX: enabled GLX_INTEL_swap_event\n");
 
+#if __DRI_DRI2_VERSION >= 3
+    if (screen->dri2->base.version >= 3) {
+	    __glXEnableExtension(screen->glx_enable_bits,
+				 "GLX_ARB_create_context");
+	    LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context\n");
+    }
+#endif
+
     if (DRI2HasSwapControl(pScreen)) {
 	__glXEnableExtension(screen->glx_enable_bits,
 			     "GLX_SGI_swap_control");
-- 
1.7.6.4



More information about the xorg-devel mailing list