mesa: fix GetTexImage if mesa format and internal format don't match

Tested with softpipe only exposing RGBA formats.

NOTE: This is a candidate for the stable branches.

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Marek Olšák 2013-02-06 22:39:53 +01:00
parent c8379204ab
commit cb6470775c
2 changed files with 71 additions and 0 deletions

View 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 */
;

View 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;