mesa: add _mesa_pack_colormask()

For generating bit-wise colormasks for arbitrary pixel formats.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
This commit is contained in:
Brian Paul 2011-12-24 08:54:26 -07:00
parent 488d7fc67d
commit f1a2aa5cb3
2 changed files with 78 additions and 0 deletions

View 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;
}
}

View 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