[Mesa-dev] [PATCH 3/4] mesa: add _mesa_pack_colormask()

Brian Paul brianp at vmware.com
Sun Dec 18 18:18:41 PST 2011


For generating bit-wise colormasks for arbitrary pixel formats.
---
 src/mesa/main/format_pack.c |   75 +++++++++++++++++++++++++++++++++++++++++++
 src/mesa/main/format_pack.h |    3 ++
 2 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/src/mesa/main/format_pack.c b/src/mesa/main/format_pack.c
index 390b494..840559b 100644
--- a/src/mesa/main/format_pack.c
+++ b/src/mesa/main/format_pack.c
@@ -2494,3 +2494,78 @@ _mesa_pack_uint_24_8_depth_stencil_row(gl_format format, GLuint n,
       return;
    }
 }
+
+
+
+/**
+ * Convert a boolean color mask to a packed color where each channel of
+ * the packed value at dst will be 0 or ~0 depending on the colorMask.
+ */
+void
+_mesa_pack_colormask(gl_format format, const GLubyte colorMask[4], void *dst)
+{
+   GLfloat maskColor[4];
+
+   switch (_mesa_get_format_datatype(format)) {
+   case GL_UNSIGNED_NORMALIZED:
+      /* simple: 1.0 will convert to ~0 in the right bit positions */
+      maskColor[0] = colorMask[0] ? 1.0 : 0.0;
+      maskColor[1] = colorMask[1] ? 1.0 : 0.0;
+      maskColor[2] = colorMask[2] ? 1.0 : 0.0;
+      maskColor[3] = colorMask[3] ? 1.0 : 0.0;
+      _mesa_pack_float_rgba_row(format, 1,
+                                (const GLfloat (*)[4]) maskColor, dst);
+      break;
+   case GL_SIGNED_NORMALIZED:
+   case GL_FLOAT:
+      /* These formats are harder because it's hard to know the floating
+       * point values that will convert to ~0 for each color channel's bits.
+       * This solution just generates a non-zero value for each color channel
+       * then fixes up the non-zero values to be ~0.
+       * Note: we'll need to add special case code if we ever have to deal
+       * with formats with unequal color channel sizes, like R11_G11_B10.
+       * We issue a warning below for channel sizes other than 8,16,32.
+       */
+      {
+         GLuint bits = _mesa_get_format_max_bits(format); /* bits per chan */
+         GLuint bytes = _mesa_get_format_bytes(format);
+         GLuint i;
+
+         /* this should put non-zero values into the channels of dst */
+         maskColor[0] = colorMask[0] ? -1.0 : 0.0;
+         maskColor[1] = colorMask[1] ? -1.0 : 0.0;
+         maskColor[2] = colorMask[2] ? -1.0 : 0.0;
+         maskColor[3] = colorMask[3] ? -1.0 : 0.0;
+         _mesa_pack_float_rgba_row(format, 1,
+                                   (const GLfloat (*)[4]) maskColor, dst);
+
+         /* fix-up the dst channels by converting non-zero values to ~0 */
+         if (bits == 8) {
+            GLubyte *d = (GLubyte *) dst;
+            for (i = 0; i < bytes; i++) {
+               d[i] = d[i] ? 0xffff : 0x0;
+            }
+         }
+         else if (bits == 16) {
+            GLushort *d = (GLushort *) dst;
+            for (i = 0; i < bytes / 2; i++) {
+               d[i] = d[i] ? 0xffff : 0x0;
+            }
+         }
+         else if (bits == 32) {
+            GLuint *d = (GLuint *) dst;
+            for (i = 0; i < bytes / 4; i++) {
+               d[i] = d[i] ? 0xffffffffU : 0x0;
+            }
+         }
+         else {
+            _mesa_problem(NULL, "unexpected size in _mesa_pack_colormask()");
+            return;
+         }
+      }
+      break;
+   default:
+      _mesa_problem(NULL, "unexpected format data type in gen_color_mask()");
+      return;
+   }
+}
diff --git a/src/mesa/main/format_pack.h b/src/mesa/main/format_pack.h
index 7df1356..f1b4805 100644
--- a/src/mesa/main/format_pack.h
+++ b/src/mesa/main/format_pack.h
@@ -95,4 +95,7 @@ _mesa_pack_uint_24_8_depth_stencil_row(gl_format format, GLuint n,
                                        const GLuint *src, void *dst);
 
 
+extern void
+_mesa_pack_colormask(gl_format format, const GLubyte colorMask[4], void *dst);
+
 #endif
-- 
1.7.3.4



More information about the mesa-dev mailing list