[Mesa-dev] [PATCH 17/29] mesa: Unify rebase logic for glReadPixels and glGetTexImage.
Iago Toral Quiroga
itoral at igalia.com
Tue Nov 18 01:23:58 PST 2014
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
More information about the mesa-dev
mailing list