diff options
author | Marek Olšák <[email protected]> | 2013-02-06 22:39:53 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2013-02-11 19:43:01 +0100 |
commit | cb6470775c0139323bf889d2df2facdbc06a2b09 (patch) | |
tree | d90da215803505ba7981930442bb464c20a8596a /src/mesa/main/texgetimage.c | |
parent | c8379204ab0af97558871fffccdd74c60a41776a (diff) |
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 <[email protected]>
Diffstat (limited to 'src/mesa/main/texgetimage.c')
-rw-r--r-- | src/mesa/main/texgetimage.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index d1c00e80039..7299a4b23e9 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -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; |