Mesa (master): Fix DRI2 accelerated EXT_texture_from_pixmap with GL_RGB format.

Eric Anholt anholt at kemper.freedesktop.org
Fri Mar 20 17:45:41 UTC 2009


Module: Mesa
Branch: master
Commit: 66175aac7609ad314f25fbdff0d3958af310dc24
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=66175aac7609ad314f25fbdff0d3958af310dc24

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Mar 18 12:07:09 2009 -0700

Fix DRI2 accelerated EXT_texture_from_pixmap with GL_RGB format.

This requires upgrading the interface so that the argument to
glXBindTexImageEXT isn't just dropped on the floor.  Note that this only
fixes the accelerated path on Intel, as Mesa's texture format support is
missing x8r8g8b8 support (right now, GL_RGB textures get uploaded as a8r8gb8,
but in this case we're not doing the upload so we can't really work around it
that way).

Fixes bugs with compositors trying to use shaders that use alpha channels, on
windows without a valid alpha channel.  Bug #19910 and likely others as well.

Reviewed-by:	Ian Romanick <ian.d.romanick at intel.com>

---

 include/GL/internal/dri_interface.h              |   16 ++++++++++++-
 include/GL/internal/glcore.h                     |    4 +++
 src/glx/x11/glx_pbuffer.c                        |   19 +++++++++++++++++
 src/glx/x11/glxclient.h                          |    1 +
 src/glx/x11/glxcmds.c                            |   18 +++++++++++----
 src/mesa/drivers/dri/i915/i830_texstate.c        |   10 ++++++--
 src/mesa/drivers/dri/i915/i915_texstate.c        |   11 +++++++--
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c |   24 +++++++++++++++------
 src/mesa/drivers/dri/intel/intel_screen.c        |    1 +
 src/mesa/drivers/dri/intel/intel_tex.h           |    2 +
 src/mesa/drivers/dri/intel/intel_tex_image.c     |   18 ++++++++++++++-
 11 files changed, 102 insertions(+), 22 deletions(-)

diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index a726b93..a83602b 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -231,7 +231,7 @@ struct __DRItexOffsetExtensionRec {
 
 
 #define __DRI_TEX_BUFFER "DRI_TexBuffer"
-#define __DRI_TEX_BUFFER_VERSION 1
+#define __DRI_TEX_BUFFER_VERSION 2
 struct __DRItexBufferExtensionRec {
     __DRIextension base;
 
@@ -239,11 +239,23 @@ struct __DRItexBufferExtensionRec {
      * Method to override base texture image with the contents of a
      * __DRIdrawable. 
      *
-     * For GLX_EXT_texture_from_pixmap with AIGLX.
+     * For GLX_EXT_texture_from_pixmap with AIGLX.  Deprecated in favor of
+     * setTexBuffer2 in version 2 of this interface
      */
     void (*setTexBuffer)(__DRIcontext *pDRICtx,
 			 GLint target,
 			 __DRIdrawable *pDraw);
+
+    /**
+     * Method to override base texture image with the contents of a
+     * __DRIdrawable, including the required texture format attribute.
+     *
+     * For GLX_EXT_texture_from_pixmap with AIGLX.
+     */
+    void (*setTexBuffer2)(__DRIcontext *pDRICtx,
+			  GLint target,
+			  GLint format,
+			  __DRIdrawable *pDraw);
 };
 
 /**
diff --git a/include/GL/internal/glcore.h b/include/GL/internal/glcore.h
index 547b111..18f6576 100644
--- a/include/GL/internal/glcore.h
+++ b/include/GL/internal/glcore.h
@@ -178,4 +178,8 @@ typedef struct __GLcontextModesRec {
 #define GLX_TEXTURE_2D_BIT_EXT             0x00000002
 #define GLX_TEXTURE_RECTANGLE_BIT_EXT      0x00000004
 
+#define GLX_TEXTURE_FORMAT_NONE_EXT        0x20D8
+#define GLX_TEXTURE_FORMAT_RGB_EXT         0x20D9
+#define GLX_TEXTURE_FORMAT_RGBA_EXT        0x20DA
+
 #endif /* __gl_core_h_ */
diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c
index a602cd2..6bcf965 100644
--- a/src/glx/x11/glx_pbuffer.c
+++ b/src/glx/x11/glx_pbuffer.c
@@ -189,6 +189,21 @@ determineTextureTarget(const int *attribs, int numAttribs)
 
    return target;
 }
+
+
+static GLenum
+determineTextureFormat(const int *attribs, int numAttribs)
+{
+   GLenum target = 0;
+   int i;
+
+   for (i = 0; i < numAttribs; i++) {
+      if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
+	 return attribs[2 * i + 1];
+   }
+
+   return 0;
+}
 #endif
 
 /**
@@ -294,6 +309,9 @@ GetDrawableAttribute(Display * dpy, GLXDrawable drawable,
             if (pdraw != NULL && !pdraw->textureTarget)
                pdraw->textureTarget =
                   determineTextureTarget((const int *) data, num_attributes);
+            if (pdraw != NULL && !pdraw->textureFormat)
+               pdraw->textureFormat =
+                  determineTextureFormat((const int *) data, num_attributes);
          }
 #endif
 
@@ -374,6 +392,7 @@ CreateDrawable(Display * dpy, const __GLcontextModes * fbconfig,
       }
 
       pdraw->textureTarget = determineTextureTarget(attrib_list, i);
+      pdraw->textureFormat = determineTextureFormat(attrib_list, i);
    } while (0);
 #endif
 
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index caf58bb..c42e80a 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -161,6 +161,7 @@ struct __GLXDRIdrawableRec {
     __GLXscreenConfigs *psc;
     GLenum textureTarget;
     __DRIdrawable *driDrawable;
+    GLenum textureFormat; /* EXT_texture_from_pixmap support */
 };
 
 /*
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index fc0e593..e5c0db4 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -2631,11 +2631,19 @@ static void __glXBindTexImageEXT(Display *dpy,
     if (gc->driContext) {
 	__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
 
-	if (pdraw != NULL)
-	    (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext,
-						   pdraw->textureTarget,
-						   pdraw->driDrawable);
-
+	if (pdraw != NULL) {
+	    if (pdraw->psc->texBuffer->base.version >= 2 &&
+		pdraw->psc->texBuffer->setTexBuffer2 != NULL) {
+		(*pdraw->psc->texBuffer->setTexBuffer2)(gc->__driContext,
+							pdraw->textureTarget,
+							pdraw->textureFormat,
+							pdraw->driDrawable);
+	    } else {
+		(*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext,
+						       pdraw->textureTarget,
+						       pdraw->driDrawable);
+	    }
+	}
 	return;
     }
 #endif
diff --git a/src/mesa/drivers/dri/i915/i830_texstate.c b/src/mesa/drivers/dri/i915/i830_texstate.c
index c718bb0..df43b77 100644
--- a/src/mesa/drivers/dri/i915/i830_texstate.c
+++ b/src/mesa/drivers/dri/i915/i830_texstate.c
@@ -38,7 +38,7 @@
 
 
 static GLuint
-translate_texture_format(GLuint mesa_format)
+translate_texture_format(GLuint mesa_format, GLuint internal_format)
 {
    switch (mesa_format) {
    case MESA_FORMAT_L8:
@@ -56,7 +56,10 @@ translate_texture_format(GLuint mesa_format)
    case MESA_FORMAT_ARGB4444:
       return MAPSURF_16BIT | MT_16BIT_ARGB4444;
    case MESA_FORMAT_ARGB8888:
-      return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+      if (internal_format == GL_RGB)
+	 return MAPSURF_32BIT | MT_32BIT_XRGB8888;
+      else
+	 return MAPSURF_32BIT | MT_32BIT_ARGB8888;
    case MESA_FORMAT_YCBCR_REV:
       return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
    case MESA_FORMAT_YCBCR:
@@ -162,7 +165,8 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
 								0, intelObj->
 								firstLevel);
 
-      format = translate_texture_format(firstImage->TexFormat->MesaFormat);
+      format = translate_texture_format(firstImage->TexFormat->MesaFormat,
+					firstImage->InternalFormat);
       pitch = intelObj->mt->pitch * intelObj->mt->cpp;
    }
 
diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c
index adbb52a..6d25f8d 100644
--- a/src/mesa/drivers/dri/i915/i915_texstate.c
+++ b/src/mesa/drivers/dri/i915/i915_texstate.c
@@ -37,7 +37,8 @@
 
 
 static GLuint
-translate_texture_format(GLuint mesa_format, GLenum DepthMode)
+translate_texture_format(GLuint mesa_format, GLuint internal_format,
+			 GLenum DepthMode)
 {
    switch (mesa_format) {
    case MESA_FORMAT_L8:
@@ -55,7 +56,10 @@ translate_texture_format(GLuint mesa_format, GLenum DepthMode)
    case MESA_FORMAT_ARGB4444:
       return MAPSURF_16BIT | MT_16BIT_ARGB4444;
    case MESA_FORMAT_ARGB8888:
-      return MAPSURF_32BIT | MT_32BIT_ARGB8888;
+      if (internal_format == GL_RGB)
+	 return MAPSURF_32BIT | MT_32BIT_XRGB8888;
+      else
+	 return MAPSURF_32BIT | MT_32BIT_ARGB8888;
    case MESA_FORMAT_YCBCR_REV:
       return (MAPSURF_422 | MT_422_YCRCB_NORMAL);
    case MESA_FORMAT_YCBCR:
@@ -173,7 +177,8 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3)
 								 firstLevel);
 
       format = translate_texture_format(firstImage->TexFormat->MesaFormat, 
-		tObj->DepthMode);
+					firstImage->InternalFormat,
+					tObj->DepthMode);
       pitch = intelObj->mt->pitch * intelObj->mt->cpp;
    }
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 9b32048..e6113ef 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -69,7 +69,8 @@ static GLuint translate_tex_target( GLenum target )
 }
 
 
-static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode )
+static GLuint translate_tex_format( GLuint mesa_format, GLenum internal_format,
+				    GLenum depth_mode )
 {
    switch( mesa_format ) {
    case MESA_FORMAT_L8:
@@ -89,10 +90,16 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode )
       return BRW_SURFACEFORMAT_R8G8B8_UNORM;      
 
    case MESA_FORMAT_ARGB8888:
-      return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
+      if (internal_format == GL_RGB)
+	 return BRW_SURFACEFORMAT_B8G8R8X8_UNORM;
+      else
+	 return BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
 
    case MESA_FORMAT_RGBA8888_REV:
-      return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
+      if (internal_format == GL_RGB)
+	 return BRW_SURFACEFORMAT_R8G8B8X8_UNORM;
+      else
+	 return BRW_SURFACEFORMAT_R8G8B8A8_UNORM;
 
    case MESA_FORMAT_RGB565:
       return BRW_SURFACEFORMAT_B5G6R5_UNORM;
@@ -161,7 +168,7 @@ static GLuint translate_tex_format( GLuint mesa_format, GLenum depth_mode )
 struct brw_wm_surface_key {
    GLenum target, depthmode;
    dri_bo *bo;
-   GLint format;
+   GLint format, internal_format;
    GLint first_level, last_level;
    GLint width, height, depth;
    GLint pitch, cpp;
@@ -199,9 +206,11 @@ brw_create_texture_surface( struct brw_context *brw,
 
    surf.ss0.mipmap_layout_mode = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
    surf.ss0.surface_type = translate_tex_target(key->target);
-
-   if (key->bo) 
-      surf.ss0.surface_format = translate_tex_format(key->format, key->depthmode);
+   if (key->bo) {
+      surf.ss0.surface_format = translate_tex_format(key->format,
+						     key->internal_format,
+						     key->depthmode);
+   }
    else {
       switch (key->depth) {
       case 32:
@@ -278,6 +287,7 @@ brw_update_texture_surface( GLcontext *ctx, GLuint unit )
       key.offset = intelObj->textureOffset;
    } else {
       key.format = firstImage->TexFormat->MesaFormat;
+      key.internal_format = firstImage->InternalFormat;
       key.pitch = intelObj->mt->pitch;
       key.depth = firstImage->Depth;
       key.bo = intelObj->mt->region->buffer;
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index e8c0747..d20ea15 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -211,6 +211,7 @@ static const __DRItexOffsetExtension intelTexOffsetExtension = {
 static const __DRItexBufferExtension intelTexBufferExtension = {
     { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
    intelSetTexBuffer,
+   intelSetTexBuffer2,
 };
 
 static const __DRIextension *intelScreenExtensions[] = {
diff --git a/src/mesa/drivers/dri/intel/intel_tex.h b/src/mesa/drivers/dri/intel/intel_tex.h
index 742ccc0..f5372d8 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.h
+++ b/src/mesa/drivers/dri/intel/intel_tex.h
@@ -149,6 +149,8 @@ void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
 		       unsigned long long offset, GLint depth, GLuint pitch);
 void intelSetTexBuffer(__DRIcontext *pDRICtx,
 		       GLint target, __DRIdrawable *pDraw);
+void intelSetTexBuffer2(__DRIcontext *pDRICtx,
+			GLint target, GLint format, __DRIdrawable *pDraw);
 
 GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit);
 
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index 943636c..e902187 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -714,7 +714,9 @@ intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname,
 }
 
 void
-intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target,
+		   GLint glx_texture_format,
+		   __DRIdrawable *dPriv)
 {
    struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
    struct intel_context *intel = pDRICtx->driverPrivate;
@@ -745,7 +747,10 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
 
    type = GL_BGRA;
    format = GL_UNSIGNED_BYTE;
-   internalFormat = (rb->region->cpp == 3 ? 3 : 4);
+   if (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT)
+      internalFormat = GL_RGB;
+   else
+      internalFormat = GL_RGBA;
 
    mt = intel_miptree_create_for_region(intel, target,
 					internalFormat,
@@ -785,3 +790,12 @@ intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
 
    _mesa_unlock_texture(&intel->ctx, texObj);
 }
+
+void
+intelSetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv)
+{
+   /* The old interface didn't have the format argument, so copy our
+    * implementation's behavior at the time.
+    */
+   intelSetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
+}




More information about the mesa-commit mailing list