#include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
+/** Helper struct for MESA_FORMAT_Z32_FLOAT_X24S8 */
+struct z32f_x24s8
+{
+ float z;
+ uint32_t x24s8;
+};
+
+
typedef void (*pack_ubyte_rgba_row_func)(GLuint n,
const GLubyte src[][4], void *dst);
static void
pack_ubyte_AL44(const GLubyte src[4], void *dst)
{
- GLushort *d = ((GLushort *) dst);
+ GLubyte *d = ((GLubyte *) dst);
*d = PACK_COLOR_44(src[ACOMP], src[RCOMP]);
}
}
+/* MESA_FORMAT_ABGR2101010_UINT */
+
+static void
+pack_ubyte_ABGR2101010_UINT(const GLubyte src[4], void *dst)
+{
+ GLuint *d = ((GLuint *) dst);
+ GLushort r = UBYTE_TO_USHORT(src[RCOMP]);
+ GLushort g = UBYTE_TO_USHORT(src[GCOMP]);
+ GLushort b = UBYTE_TO_USHORT(src[BCOMP]);
+ GLushort a = UBYTE_TO_USHORT(src[ACOMP]);
+ *d = PACK_COLOR_2101010_US(a, b, g, r);
+}
+
+static void
+pack_float_ABGR2101010_UINT(const GLfloat src[4], void *dst)
+{
+ GLuint *d = ((GLuint *) dst);
+ GLushort r, g, b, a;
+ UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
+ *d = PACK_COLOR_2101010_US(a, b, g, r);
+}
+
+
/* MESA_FORMAT_SRGB8 */
static void
table[MESA_FORMAT_RG1616] = pack_ubyte_RG1616;
table[MESA_FORMAT_RG1616_REV] = pack_ubyte_RG1616_REV;
table[MESA_FORMAT_ARGB2101010] = pack_ubyte_ARGB2101010;
+ table[MESA_FORMAT_ABGR2101010_UINT] = pack_ubyte_ABGR2101010_UINT;
/* should never convert RGBA to these formats */
table[MESA_FORMAT_Z24_S8] = NULL;
table[MESA_FORMAT_RG1616] = pack_float_RG1616;
table[MESA_FORMAT_RG1616_REV] = pack_float_RG1616_REV;
table[MESA_FORMAT_ARGB2101010] = pack_float_ARGB2101010;
+ table[MESA_FORMAT_ABGR2101010_UINT] = pack_float_ABGR2101010_UINT;
/* should never convert RGBA to these formats */
table[MESA_FORMAT_Z24_S8] = NULL;
}
+/**
+ * Pack a 2D image of ubyte RGBA pixels in the given format.
+ * \param srcRowStride source image row stride in bytes
+ * \param dstRowStride destination image row stride in bytes
+ */
+void
+_mesa_pack_ubyte_rgba_rect(gl_format format, GLuint width, GLuint height,
+ const GLubyte *src, GLint srcRowStride,
+ void *dst, GLint dstRowStride)
+{
+ pack_ubyte_rgba_row_func packrow = get_pack_ubyte_rgba_row_function(format);
+ GLubyte *dstUB = (GLubyte *) dst;
+ GLuint i;
+
+ if (packrow) {
+ if (srcRowStride == width * 4 * sizeof(GLubyte) &&
+ dstRowStride == _mesa_format_row_stride(format, width)) {
+ /* do whole image at once */
+ packrow(width * height, (const GLubyte (*)[4]) src, dst);
+ }
+ else {
+ /* row by row */
+ for (i = 0; i < height; i++) {
+ packrow(width, (const GLubyte (*)[4]) src, dstUB);
+ src += srcRowStride;
+ dstUB += dstRowStride;
+ }
+ }
+ }
+ else {
+ /* slower fallback */
+ for (i = 0; i < height; i++) {
+ _mesa_pack_ubyte_rgba_row(format, width,
+ (const GLubyte (*)[4]) src, dstUB);
+ src += srcRowStride;
+ dstUB += dstRowStride;
+ }
+ }
+}
+
+
+
/**
** Pack float Z pixels
**/
break;
case MESA_FORMAT_Z32_FLOAT_X24S8:
{
- GLfloat *d = ((GLfloat *) dst);
+ struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
GLuint i;
for (i = 0; i < n; i++) {
- d[i * 2] = src[i];
+ d[i].z = src[i];
}
}
break;
break;
case MESA_FORMAT_Z32_FLOAT_X24S8:
{
- GLfloat *d = ((GLfloat *) dst);
+ struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
const GLdouble scale = 1.0 / (GLdouble) 0xffffffff;
GLuint i;
for (i = 0; i < n; i++) {
- d[i * 2] = src[i] * scale;
- assert(d[i * 2] >= 0.0f);
- assert(d[i * 2] <= 1.0f);
+ d[i].z = src[i] * scale;
+ assert(d[i].z >= 0.0f);
+ assert(d[i].z <= 1.0f);
}
}
break;
break;
case MESA_FORMAT_Z32_FLOAT_X24S8:
{
- GLfloat *d = ((GLfloat *) dst);
+ struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
GLuint i;
for (i = 0; i < n; i++) {
- d[i * 2 + 1] = src[i];
+ d[i].x24s8 = src[i];
}
}
break;
}
}
break;
+ case MESA_FORMAT_Z32_FLOAT_X24S8:
+ {
+ const GLdouble scale = 1.0 / (GLdouble) 0xffffff;
+ struct z32f_x24s8 *d = (struct z32f_x24s8 *) dst;
+ GLint i;
+ for (i = 0; i < n; i++) {
+ GLfloat z = (src[i] >> 8) * scale;
+ d[i].z = z;
+ d[i].x24s8 = src[i];
+ }
+ }
+ break;
default:
_mesa_problem(NULL, "bad format %s in _mesa_pack_ubyte_s_row",
_mesa_get_format_name(format));
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.0f : 0.0f;
+ maskColor[1] = colorMask[1] ? -1.0f : 0.0f;
+ maskColor[2] = colorMask[2] ? -1.0f : 0.0f;
+ maskColor[3] = colorMask[3] ? -1.0f : 0.0f;
+ _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] ? 0xff : 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;
+ }
+}