[Mesa-dev] [PATCH 3/3] mesa: fix GetTexImage if mesa format and internal format don't match

Marek Olšák maraeo at gmail.com
Wed Feb 6 15:29:45 PST 2013


Tested with softpipe only exposing RGBA formats.

NOTE: This is a candidate for the stable branches.
---
 src/mesa/main/pack.c        |   26 +++++++++++++++++++++++++
 src/mesa/main/texgetimage.c |   45 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c
index e00ae63..d976e5a 100644
--- a/src/mesa/main/pack.c
+++ b/src/mesa/main/pack.c
@@ -6027,6 +6027,20 @@ _mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat)
          rgba[i][ACOMP] = 1.0F;
       }
       break;
+   case GL_RG:
+      for (i = 0; i < n; i++) {
+         rgba[i][BCOMP] = 0.0F;
+         rgba[i][ACOMP] = 1.0F;
+      }
+      break;
+   case GL_RED:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0.0F;
+         rgba[i][BCOMP] = 0.0F;
+         rgba[i][ACOMP] = 1.0F;
+      }
+      break;
+
    default:
       /* no-op */
       ;
@@ -6070,6 +6084,18 @@ _mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat)
          rgba[i][ACOMP] = 1;
       }
       break;
+   case GL_RG:
+      for (i = 0; i < n; i++) {
+         rgba[i][BCOMP] = 0;
+         rgba[i][ACOMP] = 1;
+      }
+      break;
+   case GL_RED:
+      for (i = 0; i < n; i++) {
+         rgba[i][GCOMP] = 0;
+         rgba[i][BCOMP] = 0;
+         rgba[i][ACOMP] = 1;
+      }
    default:
       /* no-op */
       ;
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c
index c6068f2..419f222 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -332,6 +332,7 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
    GLuint (*rgba_uint)[4];
    GLboolean tex_is_integer = _mesa_is_format_integer_color(texImage->TexFormat);
    GLboolean tex_is_uint = _mesa_is_format_unsigned(texImage->TexFormat);
+   GLenum texBaseFormat = _mesa_get_format_base_format(texImage->TexFormat);
 
    switch (format) {
    case GL_ABGR_EXT:
@@ -380,6 +381,50 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
        */
       rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */
    }
+   else if (texImage->_BaseFormat != texBaseFormat) {
+      /* The internal format and the real format differ, so we can't rely
+       * on the unpack functions setting the correct constant values.
+       * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1)
+       */
+      switch (texImage->_BaseFormat) {
+      case GL_RED:
+         if ((texBaseFormat == GL_RGBA ||
+              texBaseFormat == GL_RGB ||
+              texBaseFormat == GL_RG) &&
+             (destBaseFormat == GL_RGBA ||
+              destBaseFormat == GL_RGB ||
+              destBaseFormat == GL_RG ||
+              destBaseFormat == GL_GREEN)) {
+            rebaseFormat = texImage->_BaseFormat;
+            break;
+         }
+         /* fall through */
+      case GL_RG:
+         if ((texBaseFormat == GL_RGBA ||
+              texBaseFormat == GL_RGB) &&
+             (destBaseFormat == GL_RGBA ||
+              destBaseFormat == GL_RGB ||
+              destBaseFormat == GL_BLUE)) {
+            rebaseFormat = texImage->_BaseFormat;
+            break;
+         }
+         /* fall through */
+      case GL_RGB:
+         if (texBaseFormat == GL_RGBA &&
+             (destBaseFormat == GL_RGBA ||
+              destBaseFormat == GL_ALPHA ||
+              destBaseFormat == GL_LUMINANCE_ALPHA)) {
+            rebaseFormat = texImage->_BaseFormat;
+         }
+         break;
+
+      case GL_ALPHA:
+         if (destBaseFormat != GL_ALPHA) {
+            rebaseFormat = texImage->_BaseFormat;
+         }
+         break;
+      }
+   }
 
    for (img = 0; img < depth; img++) {
       GLubyte *srcMap;
-- 
1.7.10.4



More information about the mesa-dev mailing list