meta: fix GetTexImage() for luminance, l/a, intensity formats
authorBrian Paul <brianp@vmware.com>
Fri, 30 Sep 2011 14:15:30 +0000 (08:15 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 30 Sep 2011 14:16:34 +0000 (08:16 -0600)
The GL spec says that luminance values are returned as (l, 0, 0, 1),
L/A values as (l, 0, 0, a) and intensity values as (i, 0, 0, 1).
Use the pixel transfer scale controls to implement that.
This fixes a few failures in the new piglit getteximage-formats
test when getting a compressed L or L/A image.

src/mesa/drivers/common/meta.c
src/mesa/main/pixel.c
src/mesa/main/pixel.h

index 02913685e66920b899810681a58b462f654bc640..4d645e200839c0c75d33635943cdb473e12bb970 100644 (file)
@@ -49,6 +49,7 @@
 #include "main/macros.h"
 #include "main/matrix.h"
 #include "main/mipmap.h"
+#include "main/pixel.h"
 #include "main/pbo.h"
 #include "main/polygon.h"
 #include "main/readpix.h"
@@ -3235,8 +3236,27 @@ decompress_texture_image(struct gl_context *ctx,
    }
 
    /* read pixels from renderbuffer */
-   ctx->Pack.RowLength = destRowLength;
-   _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest);
+   {
+      GLenum baseTexFormat = texImage->_BaseFormat;
+
+      /* The pixel transfer state will be set to default values at this point
+       * (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively
+       * turned off (as required by glGetTexImage) but we need to handle some
+       * special cases.  In particular, single-channel texture values are
+       * returned as red and two-channel texture values are returned as
+       * red/alpha.
+       */
+      if (baseTexFormat == GL_LUMINANCE ||
+          baseTexFormat == GL_LUMINANCE_ALPHA ||
+          baseTexFormat == GL_INTENSITY) {
+         /* Green and blue must be zero */
+         _mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f);
+         _mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f);
+      }
+
+      ctx->Pack.RowLength = destRowLength;
+      _mesa_ReadPixels(0, 0, width, height, destFormat, destType, dest);
+   }
 
    /* disable texture unit */
    _mesa_set_enable(ctx, target, GL_FALSE);
index c87f5e0e9f76d9beee4bd44e2290d827f7cc270d..e73c5a49a4ae9f3bb679069a73849f2a92a4c207 100644 (file)
@@ -506,7 +506,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
  * Implements glPixelTransfer[fi] whether called immediately or from a
  * display list.
  */
-static void GLAPIENTRY
+void GLAPIENTRY
 _mesa_PixelTransferf( GLenum pname, GLfloat param )
 {
    GET_CURRENT_CONTEXT(ctx);
index 6f04eb62724e7caa8870c8597802b209a779e254..558b106d78ceceae21a47d3ab016845abce0797e 100644 (file)
@@ -43,6 +43,9 @@ struct gl_context;
 
 #if FEATURE_pixel_transfer
 
+extern void GLAPIENTRY
+_mesa_PixelTransferf(GLenum pname, GLfloat param);
+
 extern void 
 _mesa_update_pixel( struct gl_context *ctx, GLuint newstate );
 
@@ -51,6 +54,12 @@ _mesa_init_pixel_dispatch( struct _glapi_table * disp );
 
 #else /* FEATURE_pixel_transfer */
 
+static inline void GLAPIENTRY
+_mesa_PixelTransferf(GLenum pname, GLfloat param)
+{
+}
+
+
 static INLINE void
 _mesa_update_pixel(struct gl_context *ctx, GLuint newstate)
 {