[PATCH 2/4] glx: Implement GLX_ARB_create_context_profile

Ian Romanick idr at freedesktop.org
Fri Jun 8 13:10:55 PDT 2012


From: Ian Romanick <ian.d.romanick at intel.com>

Most of the infrastructure was already in place.  This just adds:

    * Validate values specified with the GLX_CONTEXT_PROFILE_MASK_ARB
      attribute.

    * Select a DRI2 "api" based on the setting of
      GLX_CONTEXT_PROFILE_MASK_ARB.

    * Enable GLX_ARB_create_context_profile extension.

This change assumes that any DRI2 driver can handle (possibly by saying "no")
seeing an API setting other than __DRI_API_OPENGL.  This allows enabling this
extension any time GLX_ARB_create_context is enabled.

Also, the validation code in __glXDisp_CreateContextAttribsARB is structured
in a very verbose manner (using a switch-statement) to ease the addition of
GLX_EXT_create_context_es2_profile.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 glx/createcontext.c |   31 +++++++++++++++++++++++++++++++
 glx/glxdri2.c       |   33 ++++++++++++++++++++++++++++++---
 2 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/glx/createcontext.c b/glx/createcontext.c
index 025c423..6f580f0 100644
--- a/glx/createcontext.c
+++ b/glx/createcontext.c
@@ -90,6 +90,17 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
     __GLXconfig *config;
     int err;
 
+    /* The GLX_ARB_create_context_profile spec says:
+     *
+     *     "The default value for GLX_CONTEXT_PROFILE_MASK_ARB is
+     *     GLX_CONTEXT_CORE_PROFILE_BIT_ARB."
+     *
+     * The core profile only makes sense for OpenGL versions 3.2 and later.
+     * If the version ultimately specified is less than 3.2, the core profile
+     * bit is cleared (see below).
+     */
+    int profile = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
+
     /* Verify that the size of the packet matches the size inferred from the
      * sizes specified for the various fields.
      */
@@ -161,6 +172,10 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
             render_type = attribs[2 * i + 1];
             break;
 
+        case GLX_CONTEXT_PROFILE_MASK_ARB:
+            profile = attribs[2 * i + 1];
+            break;
+
         default:
             return BadValue;
         }
@@ -202,6 +217,22 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
     if ((flags & ~ALL_VALID_FLAGS) != 0)
         return BadValue;
 
+    /* The GLX_ARB_create_context_profile spec says:
+     *
+     *     "* If attribute GLX_CONTEXT_PROFILE_MASK_ARB has no bits set; has
+     *        any bits set other than GLX_CONTEXT_CORE_PROFILE_BIT_ARB and
+     *        GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; has more than one of
+     *        these bits set; or if the implementation does not support the
+     *        requested profile, then GLXBadProfileARB is generated."
+     */
+    switch (profile) {
+    case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+    case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+        break;
+    default:
+        return __glXError(GLXBadProfileARB);
+    }
+
     /* Allocate memory for the new context
      */
     if (req->isDirect) {
diff --git a/glx/glxdri2.c b/glx/glxdri2.c
index 46620a0..2827326 100644
--- a/glx/glxdri2.c
+++ b/glx/glxdri2.c
@@ -381,7 +381,7 @@ __glXDRIscreenDestroy(__GLXscreen * baseScreen)
 static Bool
 dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
                          unsigned *major_ver, unsigned *minor_ver,
-                         uint32_t *flags, unsigned *error)
+                         uint32_t *flags, int *api, unsigned *error)
 {
     unsigned i;
 
@@ -409,6 +409,19 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
             break;
         case GLX_RENDER_TYPE:
             break;
+        case GLX_CONTEXT_PROFILE_MASK_ARB:
+            switch (attribs[i * 2 + 1]) {
+            case GLX_CONTEXT_CORE_PROFILE_BIT_ARB:
+                *api = __DRI_API_OPENGL_CORE;
+                break;
+            case GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB:
+                *api = __DRI_API_OPENGL;
+                break;
+            default:
+                *error = __glXError(GLXBadProfileARB);
+                return False;
+            }
+            break;
         default:
             /* If an unknown attribute is received, fail.
              */
@@ -424,6 +437,16 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
         return False;
     }
 
+    /* If the core profile is requested for a GL version is less than 3.2,
+     * request the non-core profile from the DRI driver.  The core profile
+     * only makes sense for GL versions >= 3.2, and many DRI drivers that
+     * don't support OpenGL 3.2 may fail the request for a core profile.
+     */
+    if (*api == __DRI_API_OPENGL_CORE
+        && (*major_ver < 3 || (*major_ver < 3 && *minor_ver < 2))) {
+        *api == __DRI_API_OPENGL;
+    }
+
     *error = Success;
     return True;
 }
@@ -447,11 +470,12 @@ create_driver_context(__GLXDRIcontext * context,
         unsigned major_ver;
         unsigned minor_ver;
         uint32_t flags;
+        int api;
 
         if (num_attribs != 0) {
             if (!dri2_convert_glx_attribs(num_attribs, attribs,
                                           &major_ver, &minor_ver,
-                                          &flags, (unsigned *) error))
+                                          &flags, &api, (unsigned *) error))
                 return NULL;
 
             ctx_attribs[num_ctx_attribs++] = __DRI_CTX_ATTRIB_MAJOR_VERSION;
@@ -471,7 +495,7 @@ create_driver_context(__GLXDRIcontext * context,
 
         context->driContext =
             (*screen->dri2->createContextAttribs)(screen->driScreen,
-                                                  __DRI_API_OPENGL,
+                                                  api,
                                                   config->driConfig,
                                                   driShare,
                                                   num_ctx_attribs / 2,
@@ -788,7 +812,10 @@ initializeExtensions(__GLXDRIscreen * screen)
     if (screen->dri2->base.version >= 3) {
         __glXEnableExtension(screen->glx_enable_bits,
                              "GLX_ARB_create_context");
+        __glXEnableExtension(screen->glx_enable_bits,
+                             "GLX_ARB_create_context_profile");
         LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context\n");
+        LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_create_context_profile\n");
     }
 #endif
 
-- 
1.7.6.5



More information about the xorg-devel mailing list