mesa: add _mesa_pack_colormask()
authorBrian Paul <brianp@vmware.com>
Sat, 24 Dec 2011 15:54:26 +0000 (08:54 -0700)
committerBrian Paul <brianp@vmware.com>
Sat, 24 Dec 2011 15:54:26 +0000 (08:54 -0700)
For generating bit-wise colormasks for arbitrary pixel formats.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
src/mesa/main/format_pack.c
src/mesa/main/format_pack.h

index 390b494c009a9b9876d696781659ffecd653001d..840559bac5e38ac1fe543f0b9bedccc3022641aa 100644 (file)
@@ -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;
+   }
+}
index 7df1356321c98c29ea2d5e43ad4003cf2ead1194..f1b4805106525fabe215c5189f8feaaba5851a31 100644 (file)
@@ -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