Both glReadPixels and glGetTexImage have RGBA rebasing logic that is almost the same, so move that logic to a separate helper function _mesa_get_rebase_format_for_color_read_back and call this from both implementations. --- src/mesa/main/pack.c | 69 +++++++++++++++++++++++++++++++++++++++++++ src/mesa/main/pack.h | 5 ++++ src/mesa/main/readpix.c | 71 +++++++-------------------------------------- src/mesa/main/texgetimage.c | 68 +++++++------------------------------------ 4 files changed, 95 insertions(+), 118 deletions(-)
diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index aabe6a9..8e7afc2 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -4334,6 +4334,75 @@ _mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat) } } +GLenum +_mesa_get_rebase_format_for_color_read_back(GLenum src_internal_base_format, + GLenum src_base_format, + GLenum dst_base_format) +{ + if (src_internal_base_format == GL_LUMINANCE || + src_internal_base_format == GL_INTENSITY || + src_internal_base_format == GL_LUMINANCE_ALPHA) { + /* If luminance (or intensity) is read back as RGB(A), the returned value + * should be (L,0,0,1), not (L,L,L,1), so we need to rebase. + */ + return src_internal_base_format; + } else if ((src_internal_base_format == GL_RGB || + src_internal_base_format == GL_RG) && + (dst_base_format == GL_LUMINANCE || + dst_base_format == GL_LUMINANCE_ALPHA)) { + /* If RG(B) is read as luminance we want to have (R,G,B,1) or (R,G,0,1), + * RGBA values, so we need a rebase. + */ + return src_internal_base_format; + } else if (src_internal_base_format != src_base_format) { + /* If the internal format and the real format differ we can't rely + * on the convert functions setting the correct constant values + * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1), + * so we will have to rebase in certain cases. + */ + switch (src_internal_base_format) { + case GL_RED: + if ((src_base_format == GL_RGBA || + src_base_format == GL_RGB || + src_base_format == GL_RG) && + (dst_base_format == GL_RGBA || + dst_base_format == GL_RGB || + dst_base_format == GL_RG || + dst_base_format == GL_GREEN)) { + return src_internal_base_format; + break; + } + /* fall through */ + case GL_RG: + if ((src_base_format == GL_RGBA || + src_base_format == GL_RGB) && + (dst_base_format == GL_RGBA || + dst_base_format == GL_RGB || + dst_base_format == GL_BLUE)) { + return src_internal_base_format; + break; + } + /* fall through */ + case GL_RGB: + if (src_base_format == GL_RGBA && + (dst_base_format == GL_RGBA || + dst_base_format == GL_ALPHA || + dst_base_format == GL_LUMINANCE_ALPHA)) { + return src_internal_base_format; + } + break; + case GL_ALPHA: + if (dst_base_format != GL_ALPHA) { + return src_internal_base_format; + } + break; + } + } + + /* No rebase needed */ + return GL_NONE; +} + void _mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], GLvoid *dstAddr, GLenum dst_format, diff --git a/src/mesa/main/pack.h b/src/mesa/main/pack.h index 5a532e0..6765a7f 100644 --- a/src/mesa/main/pack.h +++ b/src/mesa/main/pack.h @@ -155,6 +155,11 @@ _mesa_rebase_rgba_float(GLuint n, GLfloat rgba[][4], GLenum baseFormat); extern void _mesa_rebase_rgba_uint(GLuint n, GLuint rgba[][4], GLenum baseFormat); +extern GLenum +_mesa_get_rebase_format_for_color_read_back(GLenum src_internal_base_format, + GLenum src_base_format, + GLenum dst_base_format); + extern void _mesa_pack_luminance_from_rgba_float(GLuint n, GLfloat rgba[][4], GLvoid *dstAddr, GLenum dst_format, diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index b779a5b..f08fead 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -431,6 +431,8 @@ read_rgba_pixels( struct gl_context *ctx, int dst_stride = _mesa_image_row_stride(packing, width, format, type); uint32_t dst_format = _mesa_format_from_format_and_type(format, type); GLenum dst_base_format = _mesa_get_format_base_format(dst_format); + bool dst_is_luminance = format == GL_LUMINANCE || + format == GL_LUMINANCE_ALPHA; GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, format, type, 0, 0); @@ -454,68 +456,17 @@ read_rgba_pixels( struct gl_context *ctx, * * Depending on the base formats involved in the conversion we might need to * rebase some values and for that we need to convert to RGBA first too. + * + * Converting to luminance requires converting to RGBA first, so we can then + * compute luminance values as L=R+G+B. */ assert(!transferOps || (transferOps && !dst_is_integer)); - GLenum rebase_format = GL_NONE; - if (rb->_BaseFormat == GL_LUMINANCE || - rb->_BaseFormat == GL_INTENSITY || - rb->_BaseFormat == GL_LUMINANCE_ALPHA) { - /* If luminance (or intensity) is read back as RGB(A), the returned value - * should be (L,0,0,1), not (L,L,L,1), so we need to rebase. - */ - rebase_format = rb->_BaseFormat; - } else if (dst_base_format == GL_LUMINANCE || - dst_base_format == GL_LUMINANCE_ALPHA) { - /* If dst is luminance we will convert to RGBA first so we can then - * compute luminance values as L=R+G+B. We will need a rebase or not - * depending on the base format of the render buffer. - */ - rebase_format = rb->_BaseFormat; - } else if (rb->_BaseFormat != rb_base_format) { - /* If the internal format and the real format differ we can't rely - * on the convert functions setting the correct constant values - * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1), - * so we will have to rebase in certain cases. - */ - switch (rb->_BaseFormat) { - case GL_RED: - if ((rb_base_format == GL_RGBA || - rb_base_format == GL_RGB || - rb_base_format == GL_RG) && - (dst_base_format == GL_RGBA || - dst_base_format == GL_RGB || - dst_base_format == GL_RG || - dst_base_format == GL_GREEN)) { - rebase_format = rb->_BaseFormat; - break; - } - /* fall through */ - case GL_RG: - if ((rb_base_format == GL_RGBA || - rb_base_format == GL_RGB) && - (dst_base_format == GL_RGBA || - dst_base_format == GL_RGB || - dst_base_format == GL_BLUE)) { - rebase_format = rb->_BaseFormat; - break; - } - /* fall through */ - case GL_RGB: - if (rb_base_format == GL_RGBA && - (dst_base_format == GL_RGBA || - dst_base_format == GL_ALPHA)) { - rebase_format = rb->_BaseFormat; - } - break; - case GL_ALPHA: - if (dst_base_format != GL_ALPHA) { - rebase_format = rb->_BaseFormat; - } - break; - } - } + GLenum rebase_format = + _mesa_get_rebase_format_for_color_read_back(rb->_BaseFormat, + rb_base_format, + dst_base_format); - bool needs_rgba = transferOps || rebase_format; + bool needs_rgba = transferOps || rebase_format || dst_is_luminance; void *rgba = NULL; void *src; @@ -594,7 +545,7 @@ read_rgba_pixels( struct gl_context *ctx, * If the dst format is Luminance, we need to do the conversion by computing * L=R+G+B values. */ - if (format != GL_LUMINANCE && format != GL_LUMINANCE_ALPHA) { + if (!dst_is_luminance) { _mesa_format_convert(dst, dst_format, dst_stride, src, src_format, src_stride, width, height, diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 84cd53e..13e5ae6 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -391,69 +391,21 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, height = 1; } - if (texImage->_BaseFormat == GL_LUMINANCE || - texImage->_BaseFormat == GL_INTENSITY || - texImage->_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 ((texImage->_BaseFormat == GL_RGBA || - texImage->_BaseFormat == GL_RGB || - texImage->_BaseFormat == GL_RG) && - (destBaseFormat == GL_LUMINANCE || - destBaseFormat == GL_LUMINANCE_ALPHA)) { + if ((texImage->_BaseFormat == GL_RGBA || + texImage->_BaseFormat == GL_RGB || + texImage->_BaseFormat == GL_RG) && + (destBaseFormat == GL_LUMINANCE || + destBaseFormat == GL_LUMINANCE_ALPHA)) { /* 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 */ - } - 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; - } + } else { + rebaseFormat = + _mesa_get_rebase_format_for_color_read_back(texImage->_BaseFormat, + texBaseFormat, + destBaseFormat); } /* Describe the dst format */ -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev