[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