mesa: fix GetTexImage if mesa format and internal format don't match
authorMarek Olšák <maraeo@gmail.com>
Wed, 6 Feb 2013 21:39:53 +0000 (22:39 +0100)
committerMarek Olšák <maraeo@gmail.com>
Mon, 11 Feb 2013 18:43:01 +0000 (19:43 +0100)
Tested with softpipe only exposing RGBA formats.

NOTE: This is a candidate for the stable branches.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/mesa/main/pack.c
src/mesa/main/texgetimage.c

index e00ae63fc0aaf23c8d5fce886b221f7a8bcae138..d976e5aae0002c37fa1473c8b58e917630e835c3 100644 (file)
@@ -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 */
       ;
index d1c00e80039a06dfd459cb44df1d15d18703dbf6..7299a4b23e9f5b549059e9552d227bad38ec257b 100644 (file)
@@ -367,6 +367,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);
 
    /* Allocate buffer for one row of texels */
    rgba = malloc(4 * width * sizeof(GLfloat));
@@ -403,6 +404,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;