[Mesa-dev] [PATCH] [mesa-dev][fe] Float fbconfigs frontend patch [1/3] Correct handling of RENDER_TYPE property.

Tomasz lis listom at gmail.com
Fri Jan 4 07:45:26 PST 2013


From: Tomasz Lis <tomasz.lis at intel.com>

The change is to correctly handle the value of renderType in both
fbconfig and context. Uses of renderType are commented, where needed,
to avoid confusion between the two types. The fact that float configs
can be only used for pbuffers is correctly addressed.

Signed-off-by: Tomasz Lis <tomasz.lis at intel.com>
---
 src/gallium/state_trackers/egl/x11/glxinit.c  |   11 ++--
 src/gallium/state_trackers/glx/xlib/glx_api.c |   87 ++++++++++++++++++++-----
 src/glx/applegl_glx.c                         |   15 +++++
 src/glx/create_context.c                      |    4 +-
 src/glx/dri2_glx.c                            |   45 ++++++++++++-
 src/glx/dri_common.c                          |    8 +--
 src/glx/dri_common.h                          |    2 +-
 src/glx/dri_glx.c                             |    8 +++
 src/glx/drisw_glx.c                           |   19 +++++-
 src/glx/glx_pbuffer.c                         |   67 ++++++++++++++++---
 src/glx/glxclient.h                           |    9 +++
 src/glx/glxcmds.c                             |   83 +++++++++++++++++++----
 src/glx/glxext.c                              |   35 ++++++++--
 src/glx/indirect_glx.c                        |   35 ++++++++--
 src/mesa/drivers/x11/fakeglx.c                |   24 ++++++-
 15 files changed, 391 insertions(+), 61 deletions(-)

diff --git a/src/gallium/state_trackers/egl/x11/glxinit.c b/src/gallium/state_trackers/egl/x11/glxinit.c
index b9c5127..40fade0 100644
--- a/src/gallium/state_trackers/egl/x11/glxinit.c
+++ b/src/gallium/state_trackers/egl/x11/glxinit.c
@@ -19,6 +19,8 @@
 #include "GL/glxtokens.h"
 #include "GL/gl.h" /* for GL types needed by __GLcontextModes */
 #include "glcore.h"  /* for __GLcontextModes */
+#include "GL/glx.h"  /* allows including glxext.h */
+#include "GL/glxext.h"  /* for defines related to extensions */
 
 #include "glxinit.h"
 
@@ -392,8 +394,10 @@ __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
       case GLX_DRAWABLE_TYPE:
          config->drawableType = *bp++;
          break;
-      case GLX_RENDER_TYPE:
-         config->renderType = *bp++;
+      case GLX_RENDER_TYPE: /* fbconfig render type bits */
+          config->renderType = *bp++;
+          if (config->renderType & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT))
+              config->floatMode = GL_TRUE;
          break;
       case GLX_X_RENDERABLE:
          config->xRenderable = *bp++;
@@ -451,9 +455,6 @@ __glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
       }
    }
 
-   config->renderType =
-      (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
-
    config->haveAccumBuffer = ((config->accumRedBits +
                                config->accumGreenBits +
                                config->accumBlueBits +
diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 8e3c6b8..f70ae4b 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_api.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -853,6 +853,9 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             else if (*parselist & GLX_COLOR_INDEX_BIT) {
                rgb_flag = GL_FALSE;
             }
+            else if (*parselist & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) {
+               rgb_flag = GL_TRUE;
+            }
             else if (*parselist == 0) {
                rgb_flag = GL_TRUE;
             }
@@ -1031,7 +1034,7 @@ glXChooseVisual( Display *dpy, int screen, int *list )
 static GLXContext
 create_context(Display *dpy, XMesaVisual xmvis,
                XMesaContext shareCtx, Bool direct,
-               unsigned major, unsigned minor,
+               unsigned major, unsigned minor, int renderType,
                unsigned profileMask, unsigned contextFlags)
 {
    GLXContext glxCtx;
@@ -1058,16 +1061,42 @@ create_context(Display *dpy, XMesaVisual xmvis,
    glxCtx->isDirect = DEFAULT_DIRECT;
    glxCtx->currentDpy = dpy;
    glxCtx->xid = (XID) glxCtx;  /* self pointer */
+   glxCtx->renderType = renderType;
 
    return glxCtx;
 }
 
+/**
+ * Verifies context's GLX_RENDER_TYPE value with config.
+ * \param config GLX FBConfig which will support the returned renderType.
+ * \param renderType The context render type to be verified.
+ * \return Gives the approved value of context renderType, or 0 if no valid value was found.
+ */
+int
+verifyContextRenderType(const GLXFBConfig config, int renderType)
+{
+    switch (renderType)
+    {
+    case GLX_RGBA_TYPE:
+        return (config->renderType & GLX_RGBA_BIT) ? GLX_RGBA_TYPE : 0;
+    case GLX_COLOR_INDEX_TYPE:
+        return (config->renderType & GLX_COLOR_INDEX_BIT) ? GLX_COLOR_INDEX_TYPE : 0;
+    case GLX_RGBA_FLOAT_TYPE_ARB:
+        return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) ? GLX_RGBA_FLOAT_TYPE_ARB : 0;
+    case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT:
+        return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) ? GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT : 0;
+    default:
+        break;
+    }
+    return 0;
+}
 
 PUBLIC GLXContext
 glXCreateContext( Display *dpy, XVisualInfo *visinfo,
                   GLXContext shareCtx, Bool direct )
 {
    XMesaVisual xmvis;
+   int renderType;
 
    xmvis = find_glx_visual( dpy, visinfo );
    if (!xmvis) {
@@ -1078,11 +1107,16 @@ glXCreateContext( Display *dpy, XVisualInfo *visinfo,
          return NULL;
       }
    }
+   /* This API supports only integer RGBA and Color Index modes */
+   if (xmvis.mesa_visual.floatMode)
+       return NULL;
+   renderType = (xmvis.mesa_visual.rgbMode) ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE;
 
    return create_context(dpy, xmvis,
                          shareCtx ? shareCtx->xmesaContext : NULL,
                          direct,
-                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
+                         1, 0, renderType,
+                         GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
@@ -1548,12 +1582,21 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
       case GLX_DRAWABLE_TYPE: /*SGIX too */
          if (!fbconfig)
             return GLX_BAD_ATTRIBUTE;
-         *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
+         if (xmvis->mesa_visual.floatMode)
+             /* GLX_ARB_fbconfig_float spec: "Note that floating point rendering
+              * is only supported for GLXPbuffer drawables." */
+             *value = GLX_PBUFFER_BIT;
+         else
+            *value = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
          break;
       case GLX_RENDER_TYPE_SGIX:
          if (!fbconfig)
             return GLX_BAD_ATTRIBUTE;
-         if (xmvis->mesa_visual.rgbMode)
+
+         if (xmvis->mesa_visual.floatMode)
+             /* There shouldn't even be any float visual, but just in case */
+            *value = GLX_RGBA_FLOAT_BIT_ARB;
+         else if (xmvis->mesa_visual.rgbMode)
             *value = GLX_RGBA_BIT;
          else
             *value = GLX_COLOR_INDEX_BIT;
@@ -2113,14 +2156,19 @@ glXCreateNewContext( Display *dpy, GLXFBConfig config,
 {
    XMesaVisual xmvis = (XMesaVisual) config;
 
-   if (!dpy || !config ||
-       (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
-      return 0;
+   if (!dpy || !config)
+      return NULL;
+
+   /* Check the renderType value */
+   renderType = verifyContextRenderType(config, renderType);
+   if (!renderType)
+       return NULL;
 
    return create_context(dpy, xmvis,
                          shareCtx ? shareCtx->xmesaContext : NULL,
                          direct,
-                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
+                         1, 0, renderType,
+                         GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
@@ -2138,7 +2186,9 @@ glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
       *value = xmctx->xm_visual->visinfo->visualid;
       break;
    case GLX_RENDER_TYPE:
-      if (xmctx->xm_visual->mesa_visual.rgbMode)
+      if (xmctx->xm_visual->mesa_visual.floatMode)
+         *value = GLX_RGBA_FLOAT_TYPE_ARB;
+      else if (xmctx->xm_visual->mesa_visual.rgbMode)
          *value = GLX_RGBA_TYPE;
       else
          *value = GLX_COLOR_INDEX_TYPE;
@@ -2328,14 +2378,19 @@ glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config,
 {
    XMesaVisual xmvis = (XMesaVisual) config;
 
-   if (!dpy || !config ||
-       (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
-      return 0;
+   if (!dpy || !config)
+      return NULL;
+
+   /* Check the renderType value */
+   renderType = verifyContextRenderType(config, renderType);
+   if (!renderType)
+       return NULL;
 
    return create_context(dpy, xmvis,
                          shareCtx ? shareCtx->xmesaContext : NULL,
                          direct,
-                         1, 0, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
+                         1, 0, renderType,
+                         GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, 0x0);
 }
 
 
@@ -2735,12 +2790,14 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
        majorVersion < 3)
       return NULL; /* generate GLXBadProfileARB */
 
-   if (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3)
+   /* Check the renderType value */
+   renderType = verifyContextRenderType(config, renderType);
+   if ((!renderType) || (renderType == GLX_COLOR_INDEX_TYPE && majorVersion >= 3))
       return NULL; /* generate BadMatch */
 
    return create_context(dpy, xmvis,
                          shareCtx ? shareCtx->xmesaContext : NULL,
                          direct,
-                         majorVersion, minorVersion,
+                         majorVersion, minorVersion, renderType,
                          profileMask, contextFlags);
 }
diff --git a/src/glx/applegl_glx.c b/src/glx/applegl_glx.c
index a67416e..72d9ec1 100644
--- a/src/glx/applegl_glx.c
+++ b/src/glx/applegl_glx.c
@@ -120,6 +120,14 @@ static const struct glx_context_vtable applegl_context_vtable = {
    applegl_get_proc_address,
 };
 
+/**
+ * Creates GLX context on Apple machines.
+ * \param psc
+ * \param config
+ * \param shareList
+ * \param renderType Type of the render buffer in GLX type style; correct values are defines GLX_*_TYPE and GLX_*_TYPE_ARB.
+ * \return Gives the created context, or NULL pointer if context couldn't be created.
+ */
 struct glx_context *
 applegl_create_context(struct glx_screen *psc,
 		       struct glx_config *config,
@@ -131,6 +139,12 @@ applegl_create_context(struct glx_screen *psc,
    Display *dpy = psc->dpy;
    int screen = psc->scr;
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(config, renderType);
+   if (!renderType) {
+       return NULL;
+   }
+
    /* TODO: Integrate this with apple_glx_create_context and make
     * struct apple_glx_context inherit from struct glx_context. */
 
@@ -145,6 +159,7 @@ applegl_create_context(struct glx_screen *psc,
 
    gc->vtable = &applegl_context_vtable;
    gc->driContext = NULL;
+   gc->renderType = renderType;
 
    /* TODO: darwin: Integrate with above to do indirect */
    if(apple_glx_create_context(&gc->driContext, dpy, screen, config, 
diff --git a/src/glx/create_context.c b/src/glx/create_context.c
index a755e83..38e949a 100644
--- a/src/glx/create_context.c
+++ b/src/glx/create_context.c
@@ -84,7 +84,9 @@ glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config,
 #ifdef GLX_USE_APPLEGL
       gc = applegl_create_context(psc, cfg, share, 0);
 #else
-      gc = indirect_create_context(psc, cfg, share, 0);
+      gc = indirect_create_context_attribs(psc, cfg, share, num_attribs,
+              (const uint32_t *) attrib_list,
+              &dummy_err);
 #endif
    }
 
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 1b3cf2b..912e07f 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -205,6 +205,12 @@ dri2_create_context(struct glx_screen *base,
    __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
    __DRIcontext *shared = NULL;
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(config_base, renderType);
+   if (!renderType) {
+       return NULL;
+   }
+
    if (shareList) {
       /* If the shareList context is not a DRI2 context, we cannot possibly
        * create a DRI2 context that shares it.
@@ -226,6 +232,8 @@ dri2_create_context(struct glx_screen *base,
       return NULL;
    }
 
+   pcp->base.renderType = renderType;
+
    pcp->driContext =
       (*psc->dri2->createNewContext) (psc->driScreen,
                                       config->driConfig, shared, pcp);
@@ -256,6 +264,7 @@ dri2_create_context_attribs(struct glx_screen *base,
 
    uint32_t minor_ver = 1;
    uint32_t major_ver = 2;
+   uint32_t renderType = GLX_RGBA_TYPE;
    uint32_t flags = 0;
    unsigned api;
    int reset = __DRI_CTX_RESET_NO_NOTIFICATION;
@@ -270,10 +279,15 @@ dri2_create_context_attribs(struct glx_screen *base,
    /* Remap the GLX tokens to DRI2 tokens.
     */
    if (!dri2_convert_glx_attribs(num_attribs, attribs,
-				 &major_ver, &minor_ver, &flags, &api, &reset,
+				 &major_ver, &minor_ver, &renderType, &flags, &api, &reset,
                                  error))
       goto error_exit;
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(config_base, renderType);
+   if (!renderType)
+       goto error_exit;
+
    if (shareList) {
       pcp_shared = (struct dri2_context *) shareList;
       shared = pcp_shared->driContext;
@@ -311,6 +325,11 @@ dri2_create_context_attribs(struct glx_screen *base,
       ctx_attribs[num_ctx_attribs++] = flags;
    }
 
+   /* The renderType is retrieved from attribs, or set to default
+    *  of GLX_RGBA_TYPE.
+    */
+   pcp->base.renderType = renderType;
+
    pcp->driContext =
       (*psc->dri2->createContextAttribs) (psc->driScreen,
 					  api,
@@ -358,6 +377,15 @@ dri2DestroyDrawable(__GLXDRIdrawable *base)
    free(pdraw);
 }
 
+/**
+ * Creates a DRI Drawable based on given X drawable, GLX drawable and GLX config.
+ * \param base The GLX Screen on which the drawable should be based.
+ * \param xDrawable The corresponding X drawable.
+ * \param drawable The corresponding GLX drawable.
+ * \param config_base The GLX config on which drawable is to be based.
+ * \note The xDrawable may be 0 if the drawable being created is a PBuffer.
+ * \return Gives the new drawable, or NULL.
+ */
 static __GLXDRIdrawable *
 dri2CreateDrawable(struct glx_screen *base, XID xDrawable,
 		   GLXDrawable drawable, struct glx_config *config_base)
@@ -416,7 +444,7 @@ dri2CreateDrawable(struct glx_screen *base, XID xDrawable,
       (*psc->core->destroyDrawable) (pdraw->driDrawable);
       DRI2DestroyDrawable(psc->base.dpy, xDrawable);
       free(pdraw);
-      return None;
+      return NULL;
    }
 
    /*
@@ -879,6 +907,19 @@ dri2GetBuffers(__DRIdrawable * driDrawable,
    return pdraw->buffers;
 }
 
+/**
+ * Get list of buffers from the server.
+ * This is the \c __DRIdri2LoaderExtensionRec::getBuffersWithFormat() implementation for \c dri2LoaderExtension.
+ * \param driDrawable Drawable whose buffers are being queried.
+ * \param width Output where the width of the buffers is stored.
+ * \param height Output where the height of the buffers is stored.
+ * \param attachments List of pairs of attachment ID and opaque format requested for the drawable.
+ * \param count Number of attachment / format pairs stored in \c attachments.
+ * \param out_count
+ * \param loaderPrivate Loader's private data that was previously passed into \c __DRIdri2ExtensionRec::createNewDrawable().
+ * \return
+ * \see __DRIdri2LoaderExtensionRec::getBuffersWithFormat()
+ */
 static __DRIbuffer *
 dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
                          int *width, int *height,
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 1bf20ec..7ab303e 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -456,14 +456,13 @@ driReleaseDrawables(struct glx_context *gc)
 
 _X_HIDDEN bool
 dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
-			 unsigned *major_ver, unsigned *minor_ver,
+			 unsigned *major_ver, unsigned *minor_ver, int *render_type,
 			 uint32_t *flags, unsigned *api, int *reset,
                          unsigned *error)
 {
    unsigned i;
    bool got_profile = false;
    uint32_t profile;
-   int render_type = GLX_RGBA_TYPE;
 
    if (num_attribs == 0) {
       *api = __DRI_API_OPENGL;
@@ -479,6 +478,7 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
 
    *major_ver = 1;
    *minor_ver = 0;
+   *render_type = GLX_RGBA_TYPE;
    *reset = __DRI_CTX_RESET_NO_NOTIFICATION;
 
    for (i = 0; i < num_attribs; i++) {
@@ -497,7 +497,7 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
 	 got_profile = true;
 	 break;
       case GLX_RENDER_TYPE:
-	 render_type = attribs[i * 2 + 1];
+	 *render_type = attribs[i * 2 + 1];
 	 break;
       case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB:
          switch (attribs[i * 2 + 1]) {
@@ -568,7 +568,7 @@ dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
       return false;
    }
 
-   if (*major_ver >= 3 && render_type == GLX_COLOR_INDEX_TYPE) {
+   if (*major_ver >= 3 && *render_type == GLX_COLOR_INDEX_TYPE) {
       *error = __DRI_CTX_ERROR_BAD_FLAG;
       return false;
    }
diff --git a/src/glx/dri_common.h b/src/glx/dri_common.h
index 93cd744..86b0eba 100644
--- a/src/glx/dri_common.h
+++ b/src/glx/dri_common.h
@@ -71,7 +71,7 @@ extern void *driOpenDriver(const char *driverName);
 
 extern bool
 dri2_convert_glx_attribs(unsigned num_attribs, const uint32_t *attribs,
-			 unsigned *major_ver, unsigned *minor_ver,
+			 unsigned *major_ver, unsigned *minor_ver, int *render_type,
 			 uint32_t *flags, unsigned *api, int *reset,
 			 unsigned *error);
 
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index ba8fda2..de44451 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -581,6 +581,12 @@ dri_create_context(struct glx_screen *base,
    if (!psc->base.driScreen)
       return NULL;
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(config_base, renderType);
+   if (!renderType) {
+       return NULL;
+   }
+
    if (shareList) {
       /* If the shareList context is not a DRI context, we cannot possibly
        * create a DRI context that shares it.
@@ -602,6 +608,8 @@ dri_create_context(struct glx_screen *base,
       return NULL;
    }
 
+   pcp->base.renderType = renderType;
+
    if (!XF86DRICreateContextWithConfig(psc->base.dpy, psc->base.scr,
                                        config->base.visualID,
                                        &pcp->hwContextID, &hwContext)) {
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index 832e964..0e45607 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -380,6 +380,12 @@ drisw_create_context(struct glx_screen *base,
    if (!psc->base.driScreen)
       return NULL;
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(config_base, renderType);
+   if (!renderType) {
+       return NULL;
+   }
+
    if (shareList) {
       /* If the shareList context is not a DRISW context, we cannot possibly
        * create a DRISW context that shares it.
@@ -401,6 +407,8 @@ drisw_create_context(struct glx_screen *base,
       return NULL;
    }
 
+   pcp->base.renderType = renderType;
+
    pcp->driContext =
       (*psc->core->createNewContext) (psc->driScreen,
 				      config->driConfig, shared, pcp);
@@ -429,6 +437,7 @@ drisw_create_context_attribs(struct glx_screen *base,
 
    uint32_t minor_ver = 1;
    uint32_t major_ver = 0;
+   uint32_t renderType = GLX_RGBA_TYPE;
    uint32_t flags = 0;
    unsigned api;
    int reset = __DRI_CTX_RESET_NO_NOTIFICATION;
@@ -444,10 +453,16 @@ drisw_create_context_attribs(struct glx_screen *base,
    /* Remap the GLX tokens to DRI2 tokens.
     */
    if (!dri2_convert_glx_attribs(num_attribs, attribs,
-				 &major_ver, &minor_ver, &flags, &api, &reset,
+				 &major_ver, &minor_ver, &renderType, &flags, &api, &reset,
 				 error))
       return NULL;
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(config_base, renderType);
+   if (!renderType) {
+       return NULL;
+   }
+
    if (reset != __DRI_CTX_RESET_NO_NOTIFICATION)
       return NULL;
 
@@ -479,6 +494,8 @@ drisw_create_context_attribs(struct glx_screen *base,
       ctx_attribs[num_ctx_attribs++] = flags;
    }
 
+   pcp->base.renderType = renderType;
+
    pcp->driContext =
       (*psc->swrast->createContextAttribs) (psc->driScreen,
 					    api,
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index e4b2c86..841d555 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -187,6 +187,23 @@ determineTextureFormat(const int *attribs, int numAttribs)
    return 0;
 }
 
+/** \private \internal
+ * Creates a DRI Drawable based on given X drawable, GLX drawable and GLX config.
+ * Uses attributes to determine texture parameters, and associates the new drawable
+ * to given display.
+ * This function is eventually called when creating all kinds of drawables:
+ *  Window, Pixmap and PBuffer.
+ * \param dpy Display which should contain the drawable.
+ * \param config The GLX config on which drawable is to be based.
+ * \param drawable The corresponding X drawable.
+ * \param glxdrawable The corresponding GLX drawable.
+ * \param attrib_list Drawable attributes list.
+ * \param num_attribs Length of drawable attributes list.
+ * \return Gives GL_TRUE if the drawable was created and added to Display.
+ * \see glXCreatePixmap()
+ * \see glXCreateWindow()
+ * \see glXCreatePbuffer()
+ */
 static GLboolean
 CreateDRIDrawable(Display *dpy, struct glx_config *config,
 		  XID drawable, XID glxdrawable,
@@ -389,7 +406,15 @@ protocolDestroyDrawable(Display *dpy, GLXDrawable drawable, CARD32 glxCode)
 }
 
 /**
- * Create a non-pbuffer GLX drawable.
+ * Create a non-pbuffer (window or pixmap) GLX drawable (including DRI drawable).
+ *
+ * \param dpy Display which should contain the drawable.
+ * \param config The GLX config on which drawable is to be based.
+ * \param drawable The corresponding X drawable (mandatory).
+ * \param attrib_list Drawable attributes list. 0-terminated.
+ * \param glxCode The code to be used for creation; select whether Pixmap or Window is to be created.
+ * \return The new GLX drawable XID, or None on error.
+ * \see CreatePbuffer()
  */
 static GLXDrawable
 CreateDrawable(Display *dpy, struct glx_config *config,
@@ -418,7 +443,7 @@ CreateDrawable(Display *dpy, struct glx_config *config,
 
    LockDisplay(dpy);
    GetReqExtra(GLXCreateWindow, 8 * i, req);
-   data = (CARD32 *) (req + 1);
+   data = (CARD32 *) (req + 1); /* extra attributes are following the request */
 
    req->reqType = opcode;
    req->glxCode = glxCode;
@@ -471,15 +496,24 @@ DestroyDrawable(Display * dpy, GLXDrawable drawable, CARD32 glxCode)
 }
 
 
-/**
- * Create a pbuffer.
+/** \private \internal
+ * Create a pbuffer GLX drawable (including DRI drawable).
  *
  * This function is used to implement \c glXCreatePbuffer and
- * \c glXCreateGLXPbufferSGIX.
+ * \c glXCreateGLXPbufferSGIX. It is an alternative to \c CreateDrawable(),
+ * used only for PBuffers.
+ *
+ * \param dpy Display which should contain the drawable.
+ * \param config The GLX config on which drawable is to be based.
+ * \param attrib_list Drawable attributes list, 0-terminated.
+ * \param size_in_attribs Informs whether the attributes list contains
+ *     requested buffer width and height.
+ * \return The new GLX drawable XID, or None on error.
  *
  * \note
  * This function dynamically determines whether to use the SGIX_pbuffer
  * version of the protocol or the GLX 1.3 version of the protocol.
+ * \see CreateDrawable()
  */
 static GLXDrawable
 CreatePbuffer(Display * dpy, struct glx_config *config,
@@ -496,7 +530,7 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
 
    i = 0;
    if (attrib_list) {
-      while (attrib_list[i * 2])
+      while (attrib_list[i * 2] != None)
          i++;
    }
 
@@ -514,7 +548,7 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
       glx_1_3 = GL_TRUE;
 
       GetReqExtra(GLXCreatePbuffer, (8 * (i + extra)), req);
-      data = (CARD32 *) (req + 1);
+      data = (CARD32 *) (req + 1); /* extra attributes are following the request */
 
       req->reqType = opcode;
       req->glxCode = X_GLXCreatePbuffer;
@@ -554,8 +588,23 @@ CreatePbuffer(Display * dpy, struct glx_config *config,
    UnlockDisplay(dpy);
    SyncHandle();
 
-   pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
-			  width, height, config->rgbBits);
+   /* From SGIX_pbuffer spec:
+    * GLXPbuffers are equivalent to GLXPixmaps with the following exceptions:
+    * There is no associated X pixmap. Also, since a GLXPbuffer is a GLX
+    * resource, it may not be possible to render to it using X or an
+    * X extension other than GLX.
+    */
+   if (config->floatMode) {
+       /* There are no float X pixmaps - create a dummy one, with 1 BPP.
+        * The 1 BPP is a special value which disables BPP verification
+        * in XServer. */
+       pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
+                  width, height, 1);
+   } else {
+       /* If it is possible to associate an X pixmap, do it. */
+       pixmap = XCreatePixmap(dpy, RootWindow(dpy, config->screen),
+                  width, height, config->rgbBits);
+   }
 
    if (!CreateDRIDrawable(dpy, config, pixmap, id, attrib_list, i)) {
       CARD32 o = glx_1_3 ? X_GLXDestroyPbuffer : X_GLXvop_DestroyGLXPbufferSGIX;
diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h
index 3e9b730..0e78584 100644
--- a/src/glx/glxclient.h
+++ b/src/glx/glxclient.h
@@ -803,6 +803,8 @@ extern int
 applegl_create_display(struct glx_display *display);
 #endif
 
+extern int verifyContextRenderTypeGLX(const struct glx_config *config, int renderType);
+
 
 extern struct glx_drawable *GetGLXDrawable(Display *dpy, GLXDrawable drawable);
 extern int InitGLXDrawable(Display *dpy, struct glx_drawable *glxDraw,
@@ -817,5 +819,12 @@ extern struct glx_context *
 indirect_create_context(struct glx_screen *psc,
 			struct glx_config *mode,
 			struct glx_context *shareList, int renderType);
+extern struct glx_context *
+indirect_create_context_attribs(struct glx_screen *base,
+				struct glx_config *config_base,
+				struct glx_context *shareList,
+				unsigned num_attribs,
+				const uint32_t *attribs,
+				unsigned *error);
 
 #endif /* !__GLX_client_h__ */
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 8874e3b..0ffb9af 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -224,6 +224,31 @@ ValidateGLXFBConfig(Display * dpy, GLXFBConfig fbconfig)
    return NULL;
 }
 
+/**
+ * Verifies context's GLX_RENDER_TYPE value with config.
+ * \param config GLX FBConfig which will support the returned renderType.
+ * \param renderType The context render type to be verified.
+ * \return Gives the approved value of context renderType, or 0 if no valid value was found.
+ */
+int
+verifyContextRenderTypeGLX(const struct glx_config *config, int renderType)
+{
+    switch (renderType)
+    {
+    case GLX_RGBA_TYPE:
+        return (config->renderType & GLX_RGBA_BIT) ? GLX_RGBA_TYPE : 0;
+    case GLX_COLOR_INDEX_TYPE:
+        return (config->renderType & GLX_COLOR_INDEX_BIT) ? GLX_COLOR_INDEX_TYPE : 0;
+    case GLX_RGBA_FLOAT_TYPE_ARB:
+        return (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) ? GLX_RGBA_FLOAT_TYPE_ARB : 0;
+    case GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT:
+        return (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) ? GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT : 0;
+    default:
+        break;
+    }
+    return 0;
+}
+
 _X_HIDDEN Bool
 glx_context_init(struct glx_context *gc,
 		 struct glx_screen *psc, struct glx_config *config)
@@ -243,11 +268,20 @@ glx_context_init(struct glx_context *gc,
 
 
 /**
- * Create a new context.
+ * Create a new GLX context, either by X request or by indirect creation.
  *
- * \param renderType   For FBConfigs, what is the rendering type?
+ * \param dpy The X Display on which the context is to be created.
+ * \param generic_id
+ * \param config
+ * \param shareList_user
+ * \param allowDirect
+ * \param code
+ * \param renderType Type of the render buffer; GLX_RGBA_TYPE, GLX_COLOR_INDEX_TYPE,
+ *     GLX_RGBA_FLOAT_TYPE_ARB or GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT.
+ *     Note that this is not fbconfig renderType, which stores GLX_*_BIT constants.
+ * \param screen
+ * \return The newly created context, or NULL pointer if the context couldn't be created.
  */
-
 static GLXContext
 CreateContext(Display *dpy, int generic_id, struct glx_config *config,
               GLXContext shareList_user, Bool allowDirect,
@@ -344,7 +378,6 @@ CreateContext(Display *dpy, int generic_id, struct glx_config *config,
 
    gc->share_xid = shareList ? shareList->xid : None;
    gc->imported = GL_FALSE;
-   gc->renderType = renderType;
 
    return (GLXContext) gc;
 }
@@ -354,7 +387,7 @@ glXCreateContext(Display * dpy, XVisualInfo * vis,
                  GLXContext shareList, Bool allowDirect)
 {
    struct glx_config *config = NULL;
-   int renderType = 0;
+   int renderType = GLX_RGBA_TYPE;
 
 #if defined(GLX_DIRECT_RENDERING) || defined(GLX_USE_APPLEGL)
    struct glx_screen *const psc = GetGLXScreenConfigs(dpy, vis->screen);
@@ -373,7 +406,25 @@ glXCreateContext(Display * dpy, XVisualInfo * vis,
       return None;
    }
 
-   renderType = config->rgbMode ? GLX_RGBA_TYPE : GLX_COLOR_INDEX_TYPE;
+   /* Choose the context render type based on DRI config values.
+    * It is unusual to set this type from config, but we have no other choice,
+    * as this old API does not provide renderType parameter. */
+   if (config->renderType & GLX_RGBA_FLOAT_BIT_ARB) {
+       renderType = GLX_RGBA_FLOAT_TYPE_ARB;
+   } else if (config->renderType & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) {
+       renderType = GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT;
+   } else if (config->renderType & GLX_RGBA_BIT) {
+       renderType = GLX_RGBA_TYPE;
+   } else if (config->renderType & GLX_COLOR_INDEX_BIT) {
+       renderType = GLX_COLOR_INDEX_TYPE;
+   } else if (config->rgbMode == GL_TRUE) {
+       /* If we're here, then renderType is not set correctly.
+        * Let's use a safeguard - any TrueColor or DirectColor mode is RGB mode */
+       renderType = GLX_RGBA_TYPE;
+   } else {
+       /* Safeguard - only one option left, all non-RGB modes are indexed modes */
+       renderType = GLX_COLOR_INDEX_TYPE;
+   }
 #endif
 
    return CreateContext(dpy, vis->visualid, config, shareList, allowDirect,
@@ -853,6 +904,12 @@ glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
 
 /************************************************************************/
 
+/**
+ * Initializes values of glx_config struct used for selecting matching fbconfigs.
+ * \param config The config struct to be initialized.
+ * \param fbconfig_style_tags The parameter is true if the matching function
+ *        being executed is glXChooseFBConfig().
+ */
 static void
 init_fbconfig_for_chooser(struct glx_config * config,
                           GLboolean fbconfig_style_tags)
@@ -861,12 +918,17 @@ init_fbconfig_for_chooser(struct glx_config * config,
    config->visualID = (XID) GLX_DONT_CARE;
    config->visualType = GLX_DONT_CARE;
 
-   /* glXChooseFBConfig specifies different defaults for these two than
+   /* glXChooseFBConfig specifies different defaults for these than
     * glXChooseVisual.
     */
    if (fbconfig_style_tags) {
       config->rgbMode = GL_TRUE;
       config->doubleBufferMode = GLX_DONT_CARE;
+      /* allow any kind of drawable, including those for off-screen buffers */
+      config->drawableType = 0;
+   } else {
+       /* allow configs which support on-screen drawing */
+       config->drawableType = GLX_WINDOW_BIT;
    }
 
    config->visualRating = GLX_DONT_CARE;
@@ -877,9 +939,8 @@ init_fbconfig_for_chooser(struct glx_config * config,
    config->transparentAlpha = GLX_DONT_CARE;
    config->transparentIndex = GLX_DONT_CARE;
 
-   config->drawableType = GLX_WINDOW_BIT;
-   config->renderType =
-      (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+   /* Set GLX_RENDER_TYPE property to not expect any flags by default. */
+   config->renderType = 0;
    config->xRenderable = GLX_DONT_CARE;
    config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
 
@@ -1440,7 +1501,7 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID)
    numProps = nPropListBytes / (2 * sizeof(propList[0]));
    share = None;
    mode = NULL;
-   renderType = 0;
+   renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */
    pProp = propList;
 
    for (i = 0, pProp = propList; i < numProps; i++, pProp += 2)
diff --git a/src/glx/glxext.c b/src/glx/glxext.c
index ef1e7ad..83580d4 100644
--- a/src/glx/glxext.c
+++ b/src/glx/glxext.c
@@ -337,6 +337,7 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
                                     Bool fbconfig_style_tags)
 {
    int i;
+   GLint renderType = 0;
 
    if (!tagged_only) {
       /* Copy in the first set of properties */
@@ -471,8 +472,8 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
          config->drawableType |= GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;              
 #endif
          break;
-      case GLX_RENDER_TYPE:
-         config->renderType = *bp++;
+      case GLX_RENDER_TYPE: /* fbconfig render type bits */
+         renderType = *bp++;
          break;
       case GLX_X_RENDERABLE:
          config->xRenderable = *bp++;
@@ -555,8 +556,34 @@ __glXInitializeVisualConfigFromTags(struct glx_config * config, int count,
       }
    }
 
-   config->renderType =
-      (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+   if (renderType) {
+       config->renderType = renderType;
+       config->floatMode = (renderType &
+           (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) ?
+           GL_TRUE : GL_FALSE;
+   } else if (!tagged_only) {
+       /* If there wasn't GLX_RENDER_TYPE property, set it based on config->*Mode
+        * It is not always explicit, but we have no other choice. We will not know
+        * if the float mode should be signed or unsigned, and we won't know if
+        * the mode supports both integer and float RGBA. */
+       config->renderType =
+          ((config->floatMode==GL_TRUE) ? GLX_RGBA_FLOAT_BIT_ARB : 0) |
+          ((config->rgbMode==GL_TRUE && config->floatMode!=GL_TRUE) ? GLX_RGBA_BIT : 0) |
+          ((config->rgbMode!=GL_TRUE) ? GLX_COLOR_INDEX_BIT : 0);
+   } else {
+       /* If there wasn't such property and we should return fbconfig with only part of
+        * properties set, then don't change (allow zero) renderType. This will allow matching
+        * the generated fbconfig with fbconfigs_compatible(), no matter which flags are set
+        * in the fbconfig being compared. */
+   }
+   /* cannot create window out of float fbconfigs, these are offscreen only */
+   if (config->floatMode == GL_TRUE) {
+       /* GLX_ARB_fbconfig_float specs:
+        * Note that floating point rendering is only supported for
+        * GLXPbuffer drawables.
+        */
+       config->drawableType &= ~(GLX_WINDOW_BIT|GLX_PIXMAP_BIT);
+   }
 }
 
 static struct glx_config *
diff --git a/src/glx/indirect_glx.c b/src/glx/indirect_glx.c
index ff869e2..9725049 100644
--- a/src/glx/indirect_glx.c
+++ b/src/glx/indirect_glx.c
@@ -32,6 +32,7 @@
 
 #include "glapi.h"
 #include "glxclient.h"
+#include "dri_common.h"
 
 extern struct _glapi_table *__glXNewIndirectAPI(void);
 
@@ -332,9 +333,15 @@ static const struct glx_context_vtable indirect_context_vtable = {
 };
 
 /**
+ * Creates GLX context indirectly.
  * \todo Eliminate \c __glXInitVertexArrayState.  Replace it with a new
  * function called \c __glXAllocateClientState that allocates the memory and
  * does all the initialization (including the pixel pack / unpack).
+ * \param psc
+ * \param mode The mode, or GLX Config, in which the context is to be created.
+ * \param shareList
+ * \param renderType Type of the render buffer in GLX style; correct values are defines GLX_*_TYPE and GLX_*_TYPE_ARB.
+ * \return Gives the created context, or NULL pointer if context couldn't be created.
  */
 _X_HIDDEN struct glx_context *
 indirect_create_context(struct glx_screen *psc,
@@ -351,6 +358,12 @@ indirect_create_context(struct glx_screen *psc,
       return NULL;
    }
 
+   /* Check the renderType value */
+   renderType = verifyContextRenderTypeGLX(mode, renderType);
+   if (!renderType) {
+       return NULL;
+   }
+
    /* Allocate our context record */
    gc = calloc(1, sizeof *gc);
    if (!gc) {
@@ -362,6 +375,8 @@ indirect_create_context(struct glx_screen *psc,
    gc->isDirect = GL_FALSE;
    gc->vtable = &indirect_context_vtable;
    state = calloc(1, sizeof(struct __GLXattributeRec));
+   gc->renderType = renderType;
+
    if (state == NULL) {
       /* Out of memory */
       free(gc);
@@ -430,7 +445,7 @@ indirect_create_context(struct glx_screen *psc,
    return gc;
 }
 
-static struct glx_context *
+_X_HIDDEN struct glx_context *
 indirect_create_context_attribs(struct glx_screen *base,
 				struct glx_config *config_base,
 				struct glx_context *shareList,
@@ -438,18 +453,28 @@ indirect_create_context_attribs(struct glx_screen *base,
 				const uint32_t *attribs,
 				unsigned *error)
 {
+    uint32_t minor_ver = 1;
+    uint32_t major_ver = 2;
+    uint32_t renderType = GLX_RGBA_TYPE;
+    uint32_t flags = 0;
+    unsigned api;
+    int reset = __DRI_CTX_RESET_NO_NOTIFICATION;
    /* All of the attribute validation for indirect contexts is handled on the
-    * server, so there's not much to do here.
+    * server, so there's not much to do here. Still, we need to parse the attributes
+    * to correctly set renderType.
     */
-   (void) num_attribs;
-   (void) attribs;
+    if (!dri2_convert_glx_attribs(num_attribs, attribs,
+ 				 &major_ver, &minor_ver, &renderType, &flags, &api, &reset,
+                                  error)) {
+        return NULL;
+    }
 
    /* The error parameter is only used on the server so that correct GLX
     * protocol errors can be generated.  On the client, it can be ignored.
     */
    (void) error;
 
-   return indirect_create_context(base, config_base, shareList, 0);
+   return indirect_create_context(base, config_base, shareList, renderType);
 }
 
 struct glx_screen_vtable indirect_screen_vtable = {
diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
index 3dca405..608bb88 100644
--- a/src/mesa/drivers/x11/fakeglx.c
+++ b/src/mesa/drivers/x11/fakeglx.c
@@ -1076,6 +1076,9 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
             else if (*parselist & GLX_COLOR_INDEX_BIT) {
                rgb_flag = GL_FALSE;
             }
+            else if (*parselist & (GLX_RGBA_FLOAT_BIT_ARB|GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT)) {
+               rgb_flag = GL_TRUE;
+            }
             else if (*parselist == 0) {
                rgb_flag = GL_TRUE;
             }
@@ -1745,7 +1748,9 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
       case GLX_RENDER_TYPE_SGIX:
          if (!fbconfig)
             return GLX_BAD_ATTRIBUTE;
-         if (xmvis->mesa_visual.rgbMode)
+         if (xmvis->mesa_visual.floatMode)
+            *value = GLX_RGBA_FLOAT_BIT_ARB;
+         else if (xmvis->mesa_visual.rgbMode)
             *value = GLX_RGBA_BIT;
          else
             *value = GLX_COLOR_INDEX_BIT;
@@ -2294,7 +2299,17 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
    }
 }
 
-
+/**
+ * Creates new GLX context - fake.
+ *
+ * @param dpy
+ * @param config
+ * @param renderType Type of rendering context requested. This is not the value
+ *     of fbconfig GLX_RENDER_TYPE bits, it's context render type (GLX_*_TYPE or GLX_*_TYPE_ARB/EXT).
+ * @param shareList
+ * @param direct
+ * @return
+ */
 static GLXContext
 Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
                           int renderType, GLXContext shareList, Bool direct )
@@ -2304,7 +2319,10 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
    XMesaVisual xmvis = (XMesaVisual) config;
 
    if (!dpy || !config ||
-       (renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
+       (renderType != GLX_RGBA_TYPE &&
+   	   renderType != GLX_COLOR_INDEX_TYPE &&
+       renderType != GLX_RGBA_FLOAT_TYPE_ARB &&
+   	   renderType != GLX_RGBA_UNSIGNED_FLOAT_TYPE_EXT))
       return 0;
 
    glxCtx = CALLOC_STRUCT(fake_glx_context);
-- 
1.7.9.5



More information about the mesa-dev mailing list