mesa: Fix GL_LUMINANCE handling for textures in glGetTexImage

We need to rebase colors (ex: set G=B=0) when getting GL_LUMINANCE
textures in following cases:
1. If the luminance texture is actually stored as rgba
2. If getting a luminance texture, but returning rgba
3. If getting an rgba texture, but returning luminance

A similar fix was pushed by Brian Paul for uncompressed textures
in commit: f5d0ced.
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=47220

Observed no regressions in piglit and ogles2conform due to this fix.
This patch will cause failures in intel oglconform pxconv-gettex,
pxstore-gettex and pxtrans-gettex test cases. The cause of failures
is a bug in test cases. Expected luminance value is calculted
incorrectly in test cases: L = R+G+B.

V2: Set G = 0 when getting a RG texture but returning luminance.

Note: This is a candidate for stable branches.

Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Ian Romanick <idr@freedesktop.org>
This commit is contained in:
Anuj Phogat 2012-11-16 10:47:56 -08:00
parent 53ba40c156
commit 9ab896243c
2 changed files with 41 additions and 14 deletions

View File

@ -3685,6 +3685,7 @@ decompress_texture_image(struct gl_context *ctx,
/* read pixels from renderbuffer */
{
GLenum baseTexFormat = texImage->_BaseFormat;
GLenum destBaseFormat = _mesa_base_tex_format(ctx, destFormat);
/* The pixel transfer state will be set to default values at this point
* (see MESA_META_PIXEL_TRANSFER) so pixel transfer ops are effectively
@ -3693,9 +3694,19 @@ decompress_texture_image(struct gl_context *ctx,
* returned as red and two-channel texture values are returned as
* red/alpha.
*/
if (baseTexFormat == GL_LUMINANCE ||
baseTexFormat == GL_LUMINANCE_ALPHA ||
baseTexFormat == GL_INTENSITY) {
if ((baseTexFormat == GL_LUMINANCE ||
baseTexFormat == GL_LUMINANCE_ALPHA ||
baseTexFormat == GL_INTENSITY) ||
/* If we're reading back an RGB(A) texture (using glGetTexImage) as
* luminance then we need to return L=tex(R).
*/
((baseTexFormat == GL_RGBA ||
baseTexFormat == GL_RGB ||
baseTexFormat == GL_RG) &&
(destBaseFormat == GL_LUMINANCE ||
destBaseFormat == GL_LUMINANCE_ALPHA ||
destBaseFormat == GL_LUMINANCE_INTEGER_EXT ||
destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT))) {
/* Green and blue must be zero */
_mesa_PixelTransferf(GL_GREEN_SCALE, 0.0f);
_mesa_PixelTransferf(GL_BLUE_SCALE, 0.0f);

View File

@ -229,6 +229,8 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
const gl_format texFormat =
_mesa_get_srgb_format_linear(texImage->TexFormat);
const GLenum baseFormat = _mesa_get_format_base_format(texFormat);
const GLenum destBaseFormat = _mesa_base_tex_format(ctx, format);
GLenum rebaseFormat = GL_NONE;
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
const GLuint depth = texImage->Depth;
@ -266,9 +268,31 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions,
}
if (baseFormat == GL_LUMINANCE ||
baseFormat == GL_INTENSITY ||
baseFormat == GL_LUMINANCE_ALPHA) {
/* If a luminance (or intensity) texture is read back as RGB(A), the
* returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat
* here to get G=B=0.
*/
rebaseFormat = texImage->_BaseFormat;
}
else if ((baseFormat == GL_RGBA ||
baseFormat == GL_RGB ||
baseFormat == GL_RG) &&
(destBaseFormat == GL_LUMINANCE ||
destBaseFormat == GL_LUMINANCE_ALPHA ||
destBaseFormat == GL_LUMINANCE_INTEGER_EXT ||
destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) {
/* If we're reading back an RGB(A) texture as luminance then we need
* to return L=tex(R). Note, that's different from glReadPixels which
* returns L=R+G+B.
*/
rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */
}
if (rebaseFormat) {
_mesa_rebase_rgba_float(width * height, (GLfloat (*)[4]) tempImage,
baseFormat);
rebaseFormat);
}
srcRow = tempImage;
@ -332,7 +356,8 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
rebaseFormat = texImage->_BaseFormat;
}
else if ((texImage->_BaseFormat == GL_RGBA ||
texImage->_BaseFormat == GL_RGB) &&
texImage->_BaseFormat == GL_RGB ||
texImage->_BaseFormat == GL_RG) &&
(destBaseFormat == GL_LUMINANCE ||
destBaseFormat == GL_LUMINANCE_ALPHA ||
destBaseFormat == GL_LUMINANCE_INTEGER_EXT ||
@ -419,15 +444,6 @@ get_tex_rgba(struct gl_context *ctx, GLuint dimensions,
transferOps |= IMAGE_CLAMP_BIT;
}
}
/* This applies to RGB, RGBA textures. if the format is either LUMINANCE
* or LUMINANCE ALPHA, luminance (L) is computed as L=R+G+B .we need to
* clamp the sum to [0,1].
*/
else if ((format == GL_LUMINANCE ||
format == GL_LUMINANCE_ALPHA) &&
dataType == GL_UNSIGNED_NORMALIZED) {
transferOps |= IMAGE_CLAMP_BIT;
}
if (_mesa_is_format_compressed(texImage->TexFormat)) {
get_tex_rgba_compressed(ctx, dimensions, format, type,