diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/mipmap.c | 961 |
1 files changed, 523 insertions, 438 deletions
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 8ca912b3a9d..09709d17874 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -36,462 +36,543 @@ -/** - * Average together two rows of a source image to produce a single new - * row in the dest image. It's legal for the two source rows to point - * to the same data. The source width must be equal to either the - * dest width or two times the dest width. - */ -static void -do_row(const struct gl_texture_format *format, GLint srcWidth, - const GLvoid *srcRowA, const GLvoid *srcRowB, - GLint dstWidth, GLvoid *dstRow) +static GLint +bytes_per_pixel(GLenum datatype, GLuint comps) { - const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; - const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; + GLint b = _mesa_sizeof_packed_type(datatype); + assert(b >= 0); + return b * comps; +} - /* This assertion is no longer valid with non-power-of-2 textures - assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); - */ +static void +mesa_format_to_type_and_comps(const struct gl_texture_format *format, + GLenum *datatype, GLuint *comps) +{ switch (format->MesaFormat) { - case MESA_FORMAT_RGBA: - { - GLuint i, j, k; - const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA; - const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB; - GLchan (*dst)[4] = (GLchan (*)[4]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) / 4; - dst[i][3] = (rowA[j][3] + rowA[k][3] + - rowB[j][3] + rowB[k][3]) / 4; - } - } - return; - case MESA_FORMAT_RGB: - { - GLuint i, j, k; - const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA; - const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB; - GLchan (*dst)[3] = (GLchan (*)[3]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) / 4; - } - } - return; - case MESA_FORMAT_ALPHA: - case MESA_FORMAT_LUMINANCE: - case MESA_FORMAT_INTENSITY: - { - GLuint i, j, k; - const GLchan *rowA = (const GLchan *) srcRowA; - const GLchan *rowB = (const GLchan *) srcRowB; - GLchan *dst = (GLchan *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; - } - } - return; - case MESA_FORMAT_LUMINANCE_ALPHA: - { - GLuint i, j, k; - const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA; - const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB; - GLchan (*dst)[2] = (GLchan (*)[2]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) / 4; - } - } - return; - case MESA_FORMAT_Z32: - { - GLuint i, j, k; - const GLuint *rowA = (const GLuint *) srcRowA; - const GLuint *rowB = (const GLuint *) srcRowB; - GLfloat *dst = (GLfloat *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; - } - } - return; - case MESA_FORMAT_Z16: - { - GLuint i, j, k; - const GLushort *rowA = (const GLushort *) srcRowA; - const GLushort *rowB = (const GLushort *) srcRowB; - GLushort *dst = (GLushort *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; - } - } - return; - /* Begin hardware formats */ case MESA_FORMAT_RGBA8888: case MESA_FORMAT_RGBA8888_REV: case MESA_FORMAT_ARGB8888: case MESA_FORMAT_ARGB8888_REV: -#if FEATURE_EXT_texture_sRGB - case MESA_FORMAT_SRGBA8: -#endif - { - GLuint i, j, k; - const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA; - const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB; - GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) / 4; - dst[i][3] = (rowA[j][3] + rowA[k][3] + - rowB[j][3] + rowB[k][3]) / 4; - } - } + *datatype = CHAN_TYPE; + *comps = 4; return; case MESA_FORMAT_RGB888: case MESA_FORMAT_BGR888: -#if FEATURE_EXT_texture_sRGB - case MESA_FORMAT_SRGB8: -#endif - { - GLuint i, j, k; - const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA; - const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB; - GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) / 4; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) / 4; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) / 4; - } - } + *datatype = GL_UNSIGNED_BYTE; + *comps = 3; return; case MESA_FORMAT_RGB565: case MESA_FORMAT_RGB565_REV: - { - GLuint i, j, k; - const GLushort *rowA = (const GLushort *) srcRowA; - const GLushort *rowB = (const GLushort *) srcRowB; - GLushort *dst = (GLushort *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - const GLint rowAr0 = rowA[j] & 0x1f; - const GLint rowAr1 = rowA[k] & 0x1f; - const GLint rowBr0 = rowB[j] & 0x1f; - const GLint rowBr1 = rowB[k] & 0x1f; - const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; - const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; - const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; - const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; - const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; - const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; - const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; - const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; - const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - dst[i] = (blue << 11) | (green << 5) | red; - } - } + *datatype = GL_UNSIGNED_SHORT_5_6_5; + *comps = 3; return; + case MESA_FORMAT_ARGB4444: case MESA_FORMAT_ARGB4444_REV: - { - GLuint i, j, k; - const GLushort *rowA = (const GLushort *) srcRowA; - const GLushort *rowB = (const GLushort *) srcRowB; - GLushort *dst = (GLushort *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - const GLint rowAr0 = rowA[j] & 0xf; - const GLint rowAr1 = rowA[k] & 0xf; - const GLint rowBr0 = rowB[j] & 0xf; - const GLint rowBr1 = rowB[k] & 0xf; - const GLint rowAg0 = (rowA[j] >> 4) & 0xf; - const GLint rowAg1 = (rowA[k] >> 4) & 0xf; - const GLint rowBg0 = (rowB[j] >> 4) & 0xf; - const GLint rowBg1 = (rowB[k] >> 4) & 0xf; - const GLint rowAb0 = (rowA[j] >> 8) & 0xf; - const GLint rowAb1 = (rowA[k] >> 8) & 0xf; - const GLint rowBb0 = (rowB[j] >> 8) & 0xf; - const GLint rowBb1 = (rowB[k] >> 8) & 0xf; - const GLint rowAa0 = (rowA[j] >> 12) & 0xf; - const GLint rowAa1 = (rowA[k] >> 12) & 0xf; - const GLint rowBa0 = (rowB[j] >> 12) & 0xf; - const GLint rowBa1 = (rowB[k] >> 12) & 0xf; - const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; - dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; - } - } + *datatype = GL_UNSIGNED_SHORT_4_4_4_4; + *comps = 4; return; + case MESA_FORMAT_ARGB1555: - case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */ - { - GLuint i, j, k; - const GLushort *rowA = (const GLushort *) srcRowA; - const GLushort *rowB = (const GLushort *) srcRowB; - GLushort *dst = (GLushort *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - const GLint rowAr0 = rowA[j] & 0x1f; - const GLint rowAr1 = rowA[k] & 0x1f; - const GLint rowBr0 = rowB[j] & 0x1f; - const GLint rowBr1 = rowB[k] & 0xf; - const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; - const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; - const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; - const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; - const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; - const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; - const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; - const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; - const GLint rowAa0 = (rowA[j] >> 15) & 0x1; - const GLint rowAa1 = (rowA[k] >> 15) & 0x1; - const GLint rowBa0 = (rowB[j] >> 15) & 0x1; - const GLint rowBa1 = (rowB[k] >> 15) & 0x1; - const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; - dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; - } - } + case MESA_FORMAT_ARGB1555_REV: + *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV; + *comps = 3; return; + case MESA_FORMAT_AL88: case MESA_FORMAT_AL88_REV: -#if FEATURE_EXT_texture_sRGB - case MESA_FORMAT_SLA8: -#endif - { - GLuint i, j, k; - const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA; - const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB; - GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) >> 2; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) >> 2; - } - } + *datatype = GL_UNSIGNED_BYTE; + *comps = 2; return; case MESA_FORMAT_RGB332: - { - GLuint i, j, k; - const GLubyte *rowA = (const GLubyte *) srcRowA; - const GLubyte *rowB = (const GLubyte *) srcRowB; - GLubyte *dst = (GLubyte *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - const GLint rowAr0 = rowA[j] & 0x3; - const GLint rowAr1 = rowA[k] & 0x3; - const GLint rowBr0 = rowB[j] & 0x3; - const GLint rowBr1 = rowB[k] & 0x3; - const GLint rowAg0 = (rowA[j] >> 2) & 0x7; - const GLint rowAg1 = (rowA[k] >> 2) & 0x7; - const GLint rowBg0 = (rowB[j] >> 2) & 0x7; - const GLint rowBg1 = (rowB[k] >> 2) & 0x7; - const GLint rowAb0 = (rowA[j] >> 5) & 0x7; - const GLint rowAb1 = (rowA[k] >> 5) & 0x7; - const GLint rowBb0 = (rowB[j] >> 5) & 0x7; - const GLint rowBb1 = (rowB[k] >> 5) & 0x7; - const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; - const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; - const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; - dst[i] = (blue << 5) | (green << 2) | red; - } - } + *datatype = GL_UNSIGNED_BYTE_3_3_2; + *comps = 3; return; + case MESA_FORMAT_A8: case MESA_FORMAT_L8: case MESA_FORMAT_I8: case MESA_FORMAT_CI8: -#if FEATURE_EXT_texture_sRGB + *datatype = GL_UNSIGNED_BYTE; + *comps = 1; + return; + + case MESA_FORMAT_YCBCR: + case MESA_FORMAT_YCBCR_REV: + *datatype = GL_UNSIGNED_SHORT; + *comps = 2; + return; + + case MESA_FORMAT_Z24_S8: + *datatype = GL_UNSIGNED_INT; + *comps = 1; /* XXX OK? */ + return; + + case MESA_FORMAT_Z16: + *datatype = GL_UNSIGNED_SHORT; + *comps = 1; + return; + + case MESA_FORMAT_Z32: + *datatype = GL_UNSIGNED_INT; + *comps = 1; + return; + + case MESA_FORMAT_SRGB8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 3; + return; + case MESA_FORMAT_SRGBA8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 4; + return; case MESA_FORMAT_SL8: -#endif - { - GLuint i, j, k; - const GLubyte *rowA = (const GLubyte *) srcRowA; - const GLubyte *rowB = (const GLubyte *) srcRowB; - GLubyte *dst = (GLubyte *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; - } - } + *datatype = GL_UNSIGNED_BYTE; + *comps = 1; + return; + case MESA_FORMAT_SLA8: + *datatype = GL_UNSIGNED_BYTE; + *comps = 2; + return; + + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + /* XXX generate error instead? */ + *datatype = GL_UNSIGNED_BYTE; + *comps = 0; + return; + + case MESA_FORMAT_RGBA: + *datatype = CHAN_TYPE; + *comps = 4; return; + case MESA_FORMAT_RGB: + *datatype = CHAN_TYPE; + *comps = 3; + return; + case MESA_FORMAT_LUMINANCE_ALPHA: + *datatype = CHAN_TYPE; + *comps = 2; + return; + case MESA_FORMAT_ALPHA: + case MESA_FORMAT_LUMINANCE: + case MESA_FORMAT_INTENSITY: + *datatype = CHAN_TYPE; + *comps = 1; + return; + case MESA_FORMAT_RGBA_FLOAT32: - { - GLuint i, j, k; - const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA; - const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB; - GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) * 0.25F; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) * 0.25F; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) * 0.25F; - dst[i][3] = (rowA[j][3] + rowA[k][3] + - rowB[j][3] + rowB[k][3]) * 0.25F; - } - } + *datatype = GL_FLOAT; + *comps = 4; return; case MESA_FORMAT_RGBA_FLOAT16: - { - GLuint i, j, k, comp; - const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA; - const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB; - GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - for (comp = 0; comp < 4; comp++) { - GLfloat aj, ak, bj, bk; - aj = _mesa_half_to_float(rowA[j][comp]); - ak = _mesa_half_to_float(rowA[k][comp]); - bj = _mesa_half_to_float(rowB[j][comp]); - bk = _mesa_half_to_float(rowB[k][comp]); - dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - } + *datatype = GL_HALF_FLOAT_ARB; + *comps = 4; return; case MESA_FORMAT_RGB_FLOAT32: - { - GLuint i, j, k; - const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA; - const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB; - GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) * 0.25F; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) * 0.25F; - dst[i][2] = (rowA[j][2] + rowA[k][2] + - rowB[j][2] + rowB[k][2]) * 0.25F; - } - } + *datatype = GL_FLOAT; + *comps = 3; return; case MESA_FORMAT_RGB_FLOAT16: - { - GLuint i, j, k, comp; - const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA; - const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB; - GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - for (comp = 0; comp < 3; comp++) { - GLfloat aj, ak, bj, bk; - aj = _mesa_half_to_float(rowA[j][comp]); - ak = _mesa_half_to_float(rowA[k][comp]); - bj = _mesa_half_to_float(rowB[j][comp]); - bk = _mesa_half_to_float(rowB[k][comp]); - dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - } + *datatype = GL_HALF_FLOAT_ARB; + *comps = 3; return; case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32: - { - GLuint i, j, k; - const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA; - const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB; - GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i][0] = (rowA[j][0] + rowA[k][0] + - rowB[j][0] + rowB[k][0]) * 0.25F; - dst[i][1] = (rowA[j][1] + rowA[k][1] + - rowB[j][1] + rowB[k][1]) * 0.25F; - } - } + *datatype = GL_FLOAT; + *comps = 2; return; case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16: - { - GLuint i, j, k, comp; - const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA; - const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB; - GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - for (comp = 0; comp < 2; comp++) { - GLfloat aj, ak, bj, bk; - aj = _mesa_half_to_float(rowA[j][comp]); - ak = _mesa_half_to_float(rowA[k][comp]); - bj = _mesa_half_to_float(rowB[j][comp]); - bk = _mesa_half_to_float(rowB[k][comp]); - dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); - } - } - } + *datatype = GL_HALF_FLOAT_ARB; + *comps = 2; return; case MESA_FORMAT_ALPHA_FLOAT32: case MESA_FORMAT_LUMINANCE_FLOAT32: case MESA_FORMAT_INTENSITY_FLOAT32: - { - GLuint i, j, k; - const GLfloat *rowA = (const GLfloat *) srcRowA; - const GLfloat *rowB = (const GLfloat *) srcRowB; - GLfloat *dst = (GLfloat *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { - dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; - } - } + *datatype = GL_FLOAT; + *comps = 1; return; case MESA_FORMAT_ALPHA_FLOAT16: case MESA_FORMAT_LUMINANCE_FLOAT16: case MESA_FORMAT_INTENSITY_FLOAT16: - { - GLuint i, j, k; - const GLhalfARB *rowA = (const GLhalfARB *) srcRowA; - const GLhalfARB *rowB = (const GLhalfARB *) srcRowB; - GLhalfARB *dst = (GLhalfARB *) dstRow; - for (i = j = 0, k = k0; i < (GLuint) dstWidth; - i++, j += colStride, k += colStride) { + *datatype = GL_HALF_FLOAT_ARB; + *comps = 1; + return; + + default: + _mesa_problem(NULL, "bad texture format in mesa_format_to_type_and_comps"); + *datatype = 0; + *comps = 1; + } +} + + +/** + * Average together two rows of a source image to produce a single new + * row in the dest image. It's legal for the two source rows to point + * to the same data. The source width must be equal to either the + * dest width or two times the dest width. + * \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc. + * \param comps number of components per pixel (1..4) + */ +static void +do_row(GLenum datatype, GLuint comps, GLint srcWidth, + const GLvoid *srcRowA, const GLvoid *srcRowB, + GLint dstWidth, GLvoid *dstRow) +{ + const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; + const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; + + ASSERT(comps >= 1); + ASSERT(comps <= 4); + + /* This assertion is no longer valid with non-power-of-2 textures + assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); + */ + + if (datatype == GL_UNSIGNED_BYTE && comps == 4) { + GLuint i, j, k; + const GLubyte(*rowA)[4] = (const GLubyte(*)[4]) srcRowA; + const GLubyte(*rowB)[4] = (const GLubyte(*)[4]) srcRowB; + GLubyte(*dst)[4] = (GLubyte(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; + } + } + else if (datatype == GL_UNSIGNED_BYTE && comps == 3) { + GLuint i, j, k; + const GLubyte(*rowA)[3] = (const GLubyte(*)[3]) srcRowA; + const GLubyte(*rowB)[3] = (const GLubyte(*)[3]) srcRowB; + GLubyte(*dst)[3] = (GLubyte(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + } + } + else if (datatype == GL_UNSIGNED_BYTE && comps == 2) { + GLuint i, j, k; + const GLubyte(*rowA)[2] = (const GLubyte(*)[2]) srcRowA; + const GLubyte(*rowB)[2] = (const GLubyte(*)[2]) srcRowB; + GLubyte(*dst)[2] = (GLubyte(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; + } + } + else if (datatype == GL_UNSIGNED_BYTE && comps == 1) { + GLuint i, j, k; + const GLubyte *rowA = (const GLubyte *) srcRowA; + const GLubyte *rowB = (const GLubyte *) srcRowB; + GLubyte *dst = (GLubyte *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; + } + } + + else if (datatype == GL_UNSIGNED_SHORT && comps == 4) { + GLuint i, j, k; + const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA; + const GLushort(*rowB)[4] = (const GLushort(*)[4]) srcRowB; + GLushort(*dst)[4] = (GLushort(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; + } + } + else if (datatype == GL_UNSIGNED_SHORT && comps == 3) { + GLuint i, j, k; + const GLushort(*rowA)[3] = (const GLushort(*)[3]) srcRowA; + const GLushort(*rowB)[3] = (const GLushort(*)[3]) srcRowB; + GLushort(*dst)[3] = (GLushort(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; + } + } + else if (datatype == GL_UNSIGNED_SHORT && comps == 2) { + GLuint i, j, k; + const GLushort(*rowA)[2] = (const GLushort(*)[2]) srcRowA; + const GLushort(*rowB)[2] = (const GLushort(*)[2]) srcRowB; + GLushort(*dst)[2] = (GLushort(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; + dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; + } + } + else if (datatype == GL_UNSIGNED_SHORT && comps == 1) { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; + } + } + + else if (datatype == GL_FLOAT && comps == 4) { + GLuint i, j, k; + const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA; + const GLfloat(*rowB)[4] = (const GLfloat(*)[4]) srcRowB; + GLfloat(*dst)[4] = (GLfloat(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) * 0.25F; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) * 0.25F; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) * 0.25F; + dst[i][3] = (rowA[j][3] + rowA[k][3] + + rowB[j][3] + rowB[k][3]) * 0.25F; + } + } + else if (datatype == GL_FLOAT && comps == 3) { + GLuint i, j, k; + const GLfloat(*rowA)[3] = (const GLfloat(*)[3]) srcRowA; + const GLfloat(*rowB)[3] = (const GLfloat(*)[3]) srcRowB; + GLfloat(*dst)[3] = (GLfloat(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) * 0.25F; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) * 0.25F; + dst[i][2] = (rowA[j][2] + rowA[k][2] + + rowB[j][2] + rowB[k][2]) * 0.25F; + } + } + else if (datatype == GL_FLOAT && comps == 2) { + GLuint i, j, k; + const GLfloat(*rowA)[2] = (const GLfloat(*)[2]) srcRowA; + const GLfloat(*rowB)[2] = (const GLfloat(*)[2]) srcRowB; + GLfloat(*dst)[2] = (GLfloat(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i][0] = (rowA[j][0] + rowA[k][0] + + rowB[j][0] + rowB[k][0]) * 0.25F; + dst[i][1] = (rowA[j][1] + rowA[k][1] + + rowB[j][1] + rowB[k][1]) * 0.25F; + } + } + else if (datatype == GL_FLOAT && comps == 1) { + GLuint i, j, k; + const GLfloat *rowA = (const GLfloat *) srcRowA; + const GLfloat *rowB = (const GLfloat *) srcRowB; + GLfloat *dst = (GLfloat *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; + } + } + + else if (datatype == GL_HALF_FLOAT_ARB && comps == 4) { + GLuint i, j, k, comp; + const GLhalfARB(*rowA)[4] = (const GLhalfARB(*)[4]) srcRowA; + const GLhalfARB(*rowB)[4] = (const GLhalfARB(*)[4]) srcRowB; + GLhalfARB(*dst)[4] = (GLhalfARB(*)[4]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + for (comp = 0; comp < 4; comp++) { GLfloat aj, ak, bj, bk; - aj = _mesa_half_to_float(rowA[j]); - ak = _mesa_half_to_float(rowA[k]); - bj = _mesa_half_to_float(rowB[j]); - bk = _mesa_half_to_float(rowB[k]); - dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); + aj = _mesa_half_to_float(rowA[j][comp]); + ak = _mesa_half_to_float(rowA[k][comp]); + bj = _mesa_half_to_float(rowB[j][comp]); + bk = _mesa_half_to_float(rowB[k][comp]); + dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); } } - return; + } + else if (datatype == GL_HALF_FLOAT_ARB && comps == 3) { + GLuint i, j, k, comp; + const GLhalfARB(*rowA)[3] = (const GLhalfARB(*)[3]) srcRowA; + const GLhalfARB(*rowB)[3] = (const GLhalfARB(*)[3]) srcRowB; + GLhalfARB(*dst)[3] = (GLhalfARB(*)[3]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + for (comp = 0; comp < 3; comp++) { + GLfloat aj, ak, bj, bk; + aj = _mesa_half_to_float(rowA[j][comp]); + ak = _mesa_half_to_float(rowA[k][comp]); + bj = _mesa_half_to_float(rowB[j][comp]); + bk = _mesa_half_to_float(rowB[k][comp]); + dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); + } + } + } + else if (datatype == GL_HALF_FLOAT_ARB && comps == 2) { + GLuint i, j, k, comp; + const GLhalfARB(*rowA)[2] = (const GLhalfARB(*)[2]) srcRowA; + const GLhalfARB(*rowB)[2] = (const GLhalfARB(*)[2]) srcRowB; + GLhalfARB(*dst)[2] = (GLhalfARB(*)[2]) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + for (comp = 0; comp < 2; comp++) { + GLfloat aj, ak, bj, bk; + aj = _mesa_half_to_float(rowA[j][comp]); + ak = _mesa_half_to_float(rowA[k][comp]); + bj = _mesa_half_to_float(rowB[j][comp]); + bk = _mesa_half_to_float(rowB[k][comp]); + dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); + } + } + } + else if (datatype == GL_HALF_FLOAT_ARB && comps == 1) { + GLuint i, j, k; + const GLhalfARB *rowA = (const GLhalfARB *) srcRowA; + const GLhalfARB *rowB = (const GLhalfARB *) srcRowB; + GLhalfARB *dst = (GLhalfARB *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + GLfloat aj, ak, bj, bk; + aj = _mesa_half_to_float(rowA[j]); + ak = _mesa_half_to_float(rowA[k]); + bj = _mesa_half_to_float(rowB[j]); + bk = _mesa_half_to_float(rowB[k]); + dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); + } + } - default: + else if (datatype == GL_UNSIGNED_INT && comps == 1) { + GLuint i, j, k; + const GLuint *rowA = (const GLuint *) srcRowA; + const GLuint *rowB = (const GLuint *) srcRowB; + GLfloat *dst = (GLfloat *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; + } + } + + else if (datatype == GL_UNSIGNED_SHORT_5_6_5 && comps == 3) { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x1f; + const GLint rowAr1 = rowA[k] & 0x1f; + const GLint rowBr0 = rowB[j] & 0x1f; + const GLint rowBr1 = rowB[k] & 0x1f; + const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; + const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; + const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; + const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; + const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + dst[i] = (blue << 11) | (green << 5) | red; + } + } + else if (datatype == GL_UNSIGNED_SHORT_4_4_4_4 && comps == 4) { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0xf; + const GLint rowAr1 = rowA[k] & 0xf; + const GLint rowBr0 = rowB[j] & 0xf; + const GLint rowBr1 = rowB[k] & 0xf; + const GLint rowAg0 = (rowA[j] >> 4) & 0xf; + const GLint rowAg1 = (rowA[k] >> 4) & 0xf; + const GLint rowBg0 = (rowB[j] >> 4) & 0xf; + const GLint rowBg1 = (rowB[k] >> 4) & 0xf; + const GLint rowAb0 = (rowA[j] >> 8) & 0xf; + const GLint rowAb1 = (rowA[k] >> 8) & 0xf; + const GLint rowBb0 = (rowB[j] >> 8) & 0xf; + const GLint rowBb1 = (rowB[k] >> 8) & 0xf; + const GLint rowAa0 = (rowA[j] >> 12) & 0xf; + const GLint rowAa1 = (rowA[k] >> 12) & 0xf; + const GLint rowBa0 = (rowB[j] >> 12) & 0xf; + const GLint rowBa1 = (rowB[k] >> 12) & 0xf; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; + dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; + } + } + else if (datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV && comps == 4) { + GLuint i, j, k; + const GLushort *rowA = (const GLushort *) srcRowA; + const GLushort *rowB = (const GLushort *) srcRowB; + GLushort *dst = (GLushort *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x1f; + const GLint rowAr1 = rowA[k] & 0x1f; + const GLint rowBr0 = rowB[j] & 0x1f; + const GLint rowBr1 = rowB[k] & 0xf; + const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; + const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; + const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; + const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; + const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; + const GLint rowAa0 = (rowA[j] >> 15) & 0x1; + const GLint rowAa1 = (rowA[k] >> 15) & 0x1; + const GLint rowBa0 = (rowB[j] >> 15) & 0x1; + const GLint rowBa1 = (rowB[k] >> 15) & 0x1; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; + dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; + } + } + else if (datatype == GL_UNSIGNED_BYTE_3_3_2 && comps == 3) { + GLuint i, j, k; + const GLubyte *rowA = (const GLubyte *) srcRowA; + const GLubyte *rowB = (const GLubyte *) srcRowB; + GLubyte *dst = (GLubyte *) dstRow; + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = rowA[j] & 0x3; + const GLint rowAr1 = rowA[k] & 0x3; + const GLint rowBr0 = rowB[j] & 0x3; + const GLint rowBr1 = rowB[k] & 0x3; + const GLint rowAg0 = (rowA[j] >> 2) & 0x7; + const GLint rowAg1 = (rowA[k] >> 2) & 0x7; + const GLint rowBg0 = (rowB[j] >> 2) & 0x7; + const GLint rowBg1 = (rowB[k] >> 2) & 0x7; + const GLint rowAb0 = (rowA[j] >> 5) & 0x7; + const GLint rowAb1 = (rowA[k] >> 5) & 0x7; + const GLint rowBb0 = (rowB[j] >> 5) & 0x7; + const GLint rowBb1 = (rowB[k] >> 5) & 0x7; + const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; + dst[i] = (blue << 5) | (green << 2) | red; + } + } + else { _mesa_problem(NULL, "bad format in do_row()"); } } @@ -504,11 +585,11 @@ do_row(const struct gl_texture_format *format, GLint srcWidth, */ static void -make_1d_mipmap(const struct gl_texture_format *format, GLint border, +make_1d_mipmap(GLenum datatype, GLuint comps, GLint border, GLint srcWidth, const GLubyte *srcPtr, GLint dstWidth, GLubyte *dstPtr) { - const GLint bpt = format->TexelBytes; + const GLint bpt = bytes_per_pixel(datatype, comps); const GLubyte *src; GLubyte *dst; @@ -517,7 +598,7 @@ make_1d_mipmap(const struct gl_texture_format *format, GLint border, dst = dstPtr + border * bpt; /* we just duplicate the input row, kind of hack, saves code */ - do_row(format, srcWidth - 2 * border, src, src, + do_row(datatype, comps, srcWidth - 2 * border, src, src, dstWidth - 2 * border, dst); if (border) { @@ -532,13 +613,13 @@ make_1d_mipmap(const struct gl_texture_format *format, GLint border, static void -make_2d_mipmap(const struct gl_texture_format *format, GLint border, +make_2d_mipmap(GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLubyte *dstPtr, GLint dstRowStride) { - const GLint bpt = format->TexelBytes; + const GLint bpt = bytes_per_pixel(datatype, comps); const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint dstWidthNB = dstWidth - 2 * border; const GLint dstHeightNB = dstHeight - 2 * border; @@ -557,7 +638,7 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, dst = dstPtr + border * ((dstWidth + 1) * bpt); for (row = 0; row < dstHeightNB; row++) { - do_row(format, srcWidthNB, srcA, srcB, + do_row(datatype, comps, srcWidthNB, srcA, srcB, dstWidthNB, dst); srcA += 2 * srcRowBytes; srcB += 2 * srcRowBytes; @@ -579,12 +660,12 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); /* lower border */ - do_row(format, srcWidthNB, + do_row(datatype, comps, srcWidthNB, srcPtr + bpt, srcPtr + bpt, dstWidthNB, dstPtr + bpt); /* upper border */ - do_row(format, srcWidthNB, + do_row(datatype, comps, srcWidthNB, srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, dstWidthNB, @@ -602,11 +683,11 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, else { /* average two src pixels each dest pixel */ for (row = 0; row < dstHeightNB; row += 2) { - do_row(format, 1, + do_row(datatype, comps, 1, srcPtr + (srcWidth * (row * 2 + 1)) * bpt, srcPtr + (srcWidth * (row * 2 + 2)) * bpt, 1, dstPtr + (dstWidth * row + 1) * bpt); - do_row(format, 1, + do_row(datatype, comps, 1, srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); @@ -617,13 +698,13 @@ make_2d_mipmap(const struct gl_texture_format *format, GLint border, static void -make_3d_mipmap(const struct gl_texture_format *format, GLint border, +make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, GLint srcDepth, const GLubyte *srcPtr, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLint dstDepth, GLubyte *dstPtr, GLint dstRowStride) { - const GLint bpt = format->TexelBytes; + const GLint bpt = bytes_per_pixel(datatype, comps); const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint srcDepthNB = srcDepth - 2 * border; const GLint dstWidthNB = dstWidth - 2 * border; @@ -693,13 +774,13 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, for (row = 0; row < dstHeightNB; row++) { /* Average together two rows from first src image */ - do_row(format, srcWidthNB, srcImgARowA, srcImgARowB, + do_row(datatype, comps, srcWidthNB, srcImgARowA, srcImgARowB, srcWidthNB, tmpRowA); /* Average together two rows from second src image */ - do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB, + do_row(datatype, comps, srcWidthNB, srcImgBRowA, srcImgBRowB, srcWidthNB, tmpRowB); /* Average together the temp rows to make the final row */ - do_row(format, srcWidthNB, tmpRowA, tmpRowB, + do_row(datatype, comps, srcWidthNB, tmpRowA, tmpRowB, dstWidthNB, dstImgRow); /* advance to next rows */ srcImgARowA += bytesPerSrcRow + srcRowOffset; @@ -716,10 +797,10 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, /* Luckily we can leverage the make_2d_mipmap() function here! */ if (border > 0) { /* do front border image */ - make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, srcRowStride, + make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight, srcPtr, srcRowStride, dstWidth, dstHeight, dstPtr, dstRowStride); /* do back border image */ - make_2d_mipmap(format, 1, srcWidth, srcHeight, + make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight, srcPtr + bytesPerSrcImage * (srcDepth - 1), srcRowStride, dstWidth, dstHeight, dstPtr + bytesPerDstImage * (dstDepth - 1), dstRowStride); @@ -767,28 +848,28 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, /* do border along [img][row=0][col=0] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage; dst = dstPtr + (img + 1) * bytesPerDstImage; - do_row(format, 1, src, src + srcImageOffset, 1, dst); + do_row(datatype, comps, 1, src, src + srcImageOffset, 1, dst); /* do border along [img][row=dstHeight-1][col=0] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + (srcHeight - 1) * bytesPerSrcRow; dst = dstPtr + (img + 1) * bytesPerDstImage + (dstHeight - 1) * bytesPerDstRow; - do_row(format, 1, src, src + srcImageOffset, 1, dst); + do_row(datatype, comps, 1, src, src + srcImageOffset, 1, dst); /* do border along [img][row=0][col=dstWidth-1] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + (srcWidth - 1) * bpt; dst = dstPtr + (img + 1) * bytesPerDstImage + (dstWidth - 1) * bpt; - do_row(format, 1, src, src + srcImageOffset, 1, dst); + do_row(datatype, comps, 1, src, src + srcImageOffset, 1, dst); /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ src = srcPtr + (img * 2 + 1) * bytesPerSrcImage + (bytesPerSrcImage - bpt); dst = dstPtr + (img + 1) * bytesPerDstImage + (bytesPerDstImage - bpt); - do_row(format, 1, src, src + srcImageOffset, 1, dst); + do_row(datatype, comps, 1, src, src + srcImageOffset, 1, dst); } } } @@ -796,12 +877,12 @@ make_3d_mipmap(const struct gl_texture_format *format, GLint border, static void -make_1d_stack_mipmap(const struct gl_texture_format *format, GLint border, +make_1d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, GLint srcWidth, const GLubyte *srcPtr, GLuint srcRowStride, GLint dstWidth, GLint dstHeight, GLubyte *dstPtr, GLuint dstRowStride ) { - const GLint bpt = format->TexelBytes; + const GLint bpt = bytes_per_pixel(datatype, comps); const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint dstWidthNB = dstWidth - 2 * border; const GLint dstHeightNB = dstHeight - 2 * border; @@ -816,7 +897,7 @@ make_1d_stack_mipmap(const struct gl_texture_format *format, GLint border, dst = dstPtr + border * ((dstWidth + 1) * bpt); for (row = 0; row < dstHeightNB; row++) { - do_row(format, srcWidthNB, src, src, + do_row(datatype, comps, srcWidthNB, src, src, dstWidthNB, dst); src += srcRowBytes; dst += dstRowBytes; @@ -839,13 +920,13 @@ make_1d_stack_mipmap(const struct gl_texture_format *format, GLint border, * and \c make_2d_mipmap. */ static void -make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border, +make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr, GLint srcRowStride, GLint dstWidth, GLint dstHeight, GLint dstDepth, GLubyte *dstPtr, GLint dstRowStride) { - const GLint bpt = format->TexelBytes; + const GLint bpt = bytes_per_pixel(datatype, comps); const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ const GLint dstWidthNB = dstWidth - 2 * border; const GLint dstHeightNB = dstHeight - 2 * border; @@ -867,7 +948,7 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border, for (layer = 0; layer < dstDepthNB; layer++) { for (row = 0; row < dstHeightNB; row++) { - do_row(format, srcWidthNB, srcA, srcB, + do_row(datatype, comps, srcWidthNB, srcA, srcB, dstWidthNB, dst); srcA += 2 * srcRowBytes; srcB += 2 * srcRowBytes; @@ -889,12 +970,12 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border, MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); /* lower border */ - do_row(format, srcWidthNB, + do_row(datatype, comps, srcWidthNB, srcPtr + bpt, srcPtr + bpt, dstWidthNB, dstPtr + bpt); /* upper border */ - do_row(format, srcWidthNB, + do_row(datatype, comps, srcWidthNB, srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, dstWidthNB, @@ -912,11 +993,11 @@ make_2d_stack_mipmap(const struct gl_texture_format *format, GLint border, else { /* average two src pixels each dest pixel */ for (row = 0; row < dstHeightNB; row += 2) { - do_row(format, 1, + do_row(datatype, comps, 1, srcPtr + (srcWidth * (row * 2 + 1)) * bpt, srcPtr + (srcWidth * (row * 2 + 2)) * bpt, 1, dstPtr + (dstWidth * row + 1) * bpt); - do_row(format, 1, + do_row(datatype, comps, 1, srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); @@ -941,6 +1022,8 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, const GLubyte *srcData = NULL; GLubyte *dstData = NULL; GLint level, maxLevels; + GLenum datatype; + GLuint comps; ASSERT(texObj); /* XXX choose cube map face here??? */ @@ -1004,6 +1087,8 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, convertFormat = srcImage->TexFormat; } + mesa_format_to_type_and_comps(convertFormat, &datatype, &comps); + for (level = texObj->BaseLevel; level < texObj->MaxLevel && level < maxLevels - 1; level++) { /* generate image[level+1] from image[level] */ @@ -1120,7 +1205,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, */ switch (target) { case GL_TEXTURE_1D: - make_1d_mipmap(convertFormat, border, + make_1d_mipmap(datatype, comps, border, srcWidth, srcData, dstWidth, dstData); break; @@ -1131,25 +1216,25 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB: - make_2d_mipmap(convertFormat, border, + make_2d_mipmap(datatype, comps, border, srcWidth, srcHeight, srcData, srcImage->RowStride, dstWidth, dstHeight, dstData, dstImage->RowStride); break; case GL_TEXTURE_3D: - make_3d_mipmap(convertFormat, border, + make_3d_mipmap(datatype, comps, border, srcWidth, srcHeight, srcDepth, srcData, srcImage->RowStride, dstWidth, dstHeight, dstDepth, dstData, dstImage->RowStride); break; case GL_TEXTURE_1D_ARRAY_EXT: - make_1d_stack_mipmap(convertFormat, border, + make_1d_stack_mipmap(datatype, comps, border, srcWidth, srcData, srcImage->RowStride, dstWidth, dstHeight, dstData, dstImage->RowStride); break; case GL_TEXTURE_2D_ARRAY_EXT: - make_2d_stack_mipmap(convertFormat, border, + make_2d_stack_mipmap(datatype, comps, border, srcWidth, srcHeight, srcData, srcImage->RowStride, dstWidth, dstHeight, |