X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Fmipmap.c;h=0727e1818f1cc085ada3220977d73dd10d29f184;hb=cf143c1f4d7c3636ddd5c767518b1b00ff46b16c;hp=694d593330bf049ff90ec16b5014d0fda6faa03f;hpb=019bc97bd900a84f5f999afdb42928e92d33814b;p=mesa.git diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 694d593330b..0727e1818f1 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -30,7 +30,7 @@ #include "imports.h" #include "formats.h" #include "mipmap.h" -#include "texcompress.h" +#include "mtypes.h" #include "teximage.h" #include "texstore.h" #include "image.h" @@ -289,6 +289,54 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; } } + + else if (datatype == GL_SHORT && comps == 4) { + GLuint i, j, k; + const GLshort(*rowA)[4] = (const GLshort(*)[4]) srcRowA; + const GLshort(*rowB)[4] = (const GLshort(*)[4]) srcRowB; + GLshort(*dst)[4] = (GLshort(*)[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_SHORT && comps == 3) { + GLuint i, j, k; + const GLshort(*rowA)[3] = (const GLshort(*)[3]) srcRowA; + const GLshort(*rowB)[3] = (const GLshort(*)[3]) srcRowB; + GLshort(*dst)[3] = (GLshort(*)[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_SHORT && comps == 2) { + GLuint i, j, k; + const GLshort(*rowA)[2] = (const GLshort(*)[2]) srcRowA; + const GLshort(*rowB)[2] = (const GLshort(*)[2]) srcRowB; + GLshort(*dst)[2] = (GLshort(*)[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_SHORT && comps == 1) { + GLuint i, j, k; + const GLshort *rowA = (const GLshort *) srcRowA; + const GLshort *rowB = (const GLshort *) srcRowB; + GLshort *dst = (GLshort *) 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; @@ -416,7 +464,7 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, GLuint i, j, k; const GLuint *rowA = (const GLuint *) srcRowA; const GLuint *rowB = (const GLuint *) srcRowB; - GLfloat *dst = (GLfloat *) dstRow; + GLuint *dst = (GLuint *) dstRow; for (i = j = 0, k = k0; i < (GLuint) dstWidth; i++, j += colStride, k += colStride) { dst[i] = (GLfloat)(rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4); @@ -508,6 +556,37 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; } } + else if (datatype == GL_UNSIGNED_SHORT_5_5_5_1 && 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] >> 11) & 0x1f; + const GLint rowAr1 = (rowA[k] >> 11) & 0x1f; + const GLint rowBr0 = (rowB[j] >> 11) & 0x1f; + const GLint rowBr1 = (rowB[k] >> 11) & 0x1f; + const GLint rowAg0 = (rowA[j] >> 6) & 0x1f; + const GLint rowAg1 = (rowA[k] >> 6) & 0x1f; + const GLint rowBg0 = (rowB[j] >> 6) & 0x1f; + const GLint rowBg1 = (rowB[k] >> 6) & 0x1f; + const GLint rowAb0 = (rowA[j] >> 1) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 1) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 1) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 1) & 0x1f; + const GLint rowAa0 = (rowA[j] & 0x1); + const GLint rowAa1 = (rowA[k] & 0x1); + const GLint rowBa0 = (rowB[j] & 0x1); + const GLint rowBa1 = (rowB[k] & 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] = (red << 11) | (green << 6) | (blue << 1) | alpha; + } + } + else if (datatype == GL_UNSIGNED_BYTE_3_3_2 && comps == 3) { GLuint i, j, k; const GLubyte *rowA = (const GLubyte *) srcRowA; @@ -533,6 +612,28 @@ do_row(GLenum datatype, GLuint comps, GLint srcWidth, dst[i] = (blue << 5) | (green << 2) | red; } } + + else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) { + 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] & 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 r = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; + const GLint g = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; + dst[i] = (g << 4) | r; + } + } + else { _mesa_problem(NULL, "bad format in do_row()"); } @@ -607,7 +708,7 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, FILTER_3D(0); } } - if ((datatype == GL_BYTE) && (comps == 4)) { + else if ((datatype == GL_BYTE) && (comps == 4)) { DECLARE_ROW_POINTERS(GLbyte, 4); for (i = j = 0, k = k0; i < (GLuint) dstWidth; @@ -683,6 +784,44 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, FILTER_3D(0); } } + else if ((datatype == GL_SHORT) && (comps == 4)) { + DECLARE_ROW_POINTERS(GLshort, 4); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + FILTER_3D(3); + } + } + else if ((datatype == GL_SHORT) && (comps == 3)) { + DECLARE_ROW_POINTERS(GLshort, 3); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + FILTER_3D(2); + } + } + else if ((datatype == GL_SHORT) && (comps == 2)) { + DECLARE_ROW_POINTERS(GLshort, 2); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + FILTER_3D(1); + } + } + else if ((datatype == GL_SHORT) && (comps == 1)) { + DECLARE_ROW_POINTERS(GLshort, 1); + + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + FILTER_3D(0); + } + } else if ((datatype == GL_FLOAT) && (comps == 4)) { DECLARE_ROW_POINTERS(GLfloat, 4); @@ -911,9 +1050,58 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, dst[i] = (a << 15) | (b << 10) | (g << 5) | r; } } - else if ((datatype == GL_UNSIGNED_BYTE_3_3_2) && (comps == 3)) { + else if ((datatype == GL_UNSIGNED_SHORT_5_5_5_1) && (comps == 4)) { DECLARE_ROW_POINTERS0(GLushort); + for (i = j = 0, k = k0; i < (GLuint) dstWidth; + i++, j += colStride, k += colStride) { + const GLint rowAr0 = (rowA[j] >> 11) & 0x1f; + const GLint rowAr1 = (rowA[k] >> 11) & 0x1f; + const GLint rowBr0 = (rowB[j] >> 11) & 0x1f; + const GLint rowBr1 = (rowB[k] >> 11) & 0x1f; + const GLint rowCr0 = (rowC[j] >> 11) & 0x1f; + const GLint rowCr1 = (rowC[k] >> 11) & 0x1f; + const GLint rowDr0 = (rowD[j] >> 11) & 0x1f; + const GLint rowDr1 = (rowD[k] >> 11) & 0x1f; + const GLint rowAg0 = (rowA[j] >> 6) & 0x1f; + const GLint rowAg1 = (rowA[k] >> 6) & 0x1f; + const GLint rowBg0 = (rowB[j] >> 6) & 0x1f; + const GLint rowBg1 = (rowB[k] >> 6) & 0x1f; + const GLint rowCg0 = (rowC[j] >> 6) & 0x1f; + const GLint rowCg1 = (rowC[k] >> 6) & 0x1f; + const GLint rowDg0 = (rowD[j] >> 6) & 0x1f; + const GLint rowDg1 = (rowD[k] >> 6) & 0x1f; + const GLint rowAb0 = (rowA[j] >> 1) & 0x1f; + const GLint rowAb1 = (rowA[k] >> 1) & 0x1f; + const GLint rowBb0 = (rowB[j] >> 1) & 0x1f; + const GLint rowBb1 = (rowB[k] >> 1) & 0x1f; + const GLint rowCb0 = (rowC[j] >> 1) & 0x1f; + const GLint rowCb1 = (rowC[k] >> 1) & 0x1f; + const GLint rowDb0 = (rowD[j] >> 1) & 0x1f; + const GLint rowDb1 = (rowD[k] >> 1) & 0x1f; + const GLint rowAa0 = (rowA[j] & 0x1); + const GLint rowAa1 = (rowA[k] & 0x1); + const GLint rowBa0 = (rowB[j] & 0x1); + const GLint rowBa1 = (rowB[k] & 0x1); + const GLint rowCa0 = (rowC[j] & 0x1); + const GLint rowCa1 = (rowC[k] & 0x1); + const GLint rowDa0 = (rowD[j] & 0x1); + const GLint rowDa1 = (rowD[k] & 0x1); + const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, + rowCb0, rowCb1, rowDb0, rowDb1); + const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, + rowCa0, rowCa1, rowDa0, rowDa1); + + dst[i] = (r << 11) | (g << 6) | (b << 1) | a; + } + } + else if ((datatype == GL_UNSIGNED_BYTE_3_3_2) && (comps == 3)) { + DECLARE_ROW_POINTERS0(GLubyte); + for (i = j = 0, k = k0; i < (GLuint) dstWidth; i++, j += colStride, k += colStride) { const GLint rowAr0 = rowA[j] & 0x3; @@ -949,6 +1137,34 @@ do_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, dst[i] = (b << 5) | (g << 2) | r; } } + else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) { + DECLARE_ROW_POINTERS0(GLubyte); + + 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 rowCr0 = rowC[j] & 0xf; + const GLint rowCr1 = rowC[k] & 0xf; + const GLint rowDr0 = rowD[j] & 0xf; + const GLint rowDr1 = rowD[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 rowCg0 = (rowC[j] >> 4) & 0xf; + const GLint rowCg1 = (rowC[k] >> 4) & 0xf; + const GLint rowDg0 = (rowD[j] >> 4) & 0xf; + const GLint rowDg1 = (rowD[k] >> 4) & 0xf; + const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, + rowCr0, rowCr1, rowDr0, rowDr1); + const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, + rowCg0, rowCg1, rowDg0, rowDg1); + dst[i] = (g << 4) | r; + } + } else { _mesa_problem(NULL, "bad format in do_row()"); } @@ -980,9 +1196,11 @@ make_1d_mipmap(GLenum datatype, GLuint comps, GLint border, if (border) { /* copy left-most pixel from source */ - MEMCPY(dstPtr, srcPtr, bpt); + assert(dstPtr); + assert(srcPtr); + memcpy(dstPtr, srcPtr, bpt); /* copy right-most pixel from source */ - MEMCPY(dstPtr + (dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth - 1) * bpt, srcPtr + (srcWidth - 1) * bpt, bpt); } @@ -1004,21 +1222,28 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border, const GLint dstRowBytes = bpt * dstRowStride; const GLubyte *srcA, *srcB; GLubyte *dst; - GLint row; + GLint row, srcRowStep; /* Compute src and dst pointers, skipping any border */ srcA = srcPtr + border * ((srcWidth + 1) * bpt); - if (srcHeight > 1) + if (srcHeight > 1 && srcHeight > dstHeight) { + /* sample from two source rows */ srcB = srcA + srcRowBytes; - else + srcRowStep = 2; + } + else { + /* sample from one source row */ srcB = srcA; + srcRowStep = 1; + } + dst = dstPtr + border * ((dstWidth + 1) * bpt); for (row = 0; row < dstHeightNB; row++) { do_row(datatype, comps, srcWidthNB, srcA, srcB, dstWidthNB, dst); - srcA += 2 * srcRowBytes; - srcB += 2 * srcRowBytes; + srcA += srcRowStep * srcRowBytes; + srcB += srcRowStep * srcRowBytes; dst += dstRowBytes; } @@ -1026,15 +1251,17 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border, if (border > 0) { /* fill in dest border */ /* lower-left border pixel */ - MEMCPY(dstPtr, srcPtr, bpt); + assert(dstPtr); + assert(srcPtr); + memcpy(dstPtr, srcPtr, bpt); /* lower-right border pixel */ - MEMCPY(dstPtr + (dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth - 1) * bpt, srcPtr + (srcWidth - 1) * bpt, bpt); /* upper-left border pixel */ - MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, + memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt, srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); /* upper-right border pixel */ - MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, + memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt, srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); /* lower border */ do_row(datatype, comps, srcWidthNB, @@ -1051,9 +1278,9 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border, if (srcHeight == dstHeight) { /* copy border pixel from src to dst */ for (row = 1; row < srcHeight; row++) { - MEMCPY(dstPtr + dstWidth * row * bpt, + memcpy(dstPtr + dstWidth * row * bpt, srcPtr + srcWidth * row * bpt, bpt); - MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); } } @@ -1116,7 +1343,7 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, */ /* - _mesa_printf("mip3d %d x %d x %d -> %d x %d x %d\n", + printf("mip3d %d x %d x %d -> %d x %d x %d\n", srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); */ @@ -1175,28 +1402,28 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, /* do border along [img][row=0][col=0] */ src = srcPtr + (img + 1) * bytesPerSrcImage; dst = dstPtr + (img + 1) * bytesPerDstImage; - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); /* 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; - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); /* 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; - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); /* 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); - MEMCPY(dst, src, bpt); + memcpy(dst, src, bpt); } } else { @@ -1266,9 +1493,11 @@ make_1d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, if (border) { /* copy left-most pixel from source */ - MEMCPY(dstPtr, srcPtr, bpt); + assert(dstPtr); + assert(srcPtr); + memcpy(dstPtr, srcPtr, bpt); /* copy right-most pixel from source */ - MEMCPY(dstPtr + (dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth - 1) * bpt, srcPtr + (srcWidth - 1) * bpt, bpt); } @@ -1320,15 +1549,17 @@ make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, if (border > 0) { /* fill in dest border */ /* lower-left border pixel */ - MEMCPY(dstPtr, srcPtr, bpt); + assert(dstPtr); + assert(srcPtr); + memcpy(dstPtr, srcPtr, bpt); /* lower-right border pixel */ - MEMCPY(dstPtr + (dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth - 1) * bpt, srcPtr + (srcWidth - 1) * bpt, bpt); /* upper-left border pixel */ - MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt, + memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt, srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); /* upper-right border pixel */ - MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt, + memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt, srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); /* lower border */ do_row(datatype, comps, srcWidthNB, @@ -1345,9 +1576,9 @@ make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border, if (srcHeight == dstHeight) { /* copy border pixel from src to dst */ for (row = 1; row < srcHeight; row++) { - MEMCPY(dstPtr + dstWidth * row * bpt, + memcpy(dstPtr + dstWidth * row * bpt, srcPtr + srcWidth * row * bpt, bpt); - MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, + memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); } } @@ -1490,7 +1721,7 @@ next_mipmap_level_size(GLenum target, GLint border, * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP. */ void -_mesa_generate_mipmap(GLcontext *ctx, GLenum target, +_mesa_generate_mipmap(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj) { const struct gl_texture_image *srcImage; @@ -1502,16 +1733,18 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, GLuint comps; ASSERT(texObj); - /* XXX choose cube map face here??? */ - srcImage = texObj->Image[0][texObj->BaseLevel]; + srcImage = _mesa_select_tex_image(ctx, texObj, target, texObj->BaseLevel); ASSERT(srcImage); maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); ASSERT(maxLevels > 0); /* bad target */ /* Find convertFormat - the format that do_row() will process */ + if (_mesa_is_format_compressed(srcImage->TexFormat)) { - /* setup for compressed textures */ + /* setup for compressed textures - need to allocate temporary + * image buffers to hold uncompressed images. + */ GLuint row; GLint components, size; GLchan *dst; @@ -1522,8 +1755,13 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, if (srcImage->_BaseFormat == GL_RGB) { convertFormat = MESA_FORMAT_RGB888; components = 3; - } - else if (srcImage->_BaseFormat == GL_RGBA) { + } else if (srcImage->_BaseFormat == GL_RED) { + convertFormat = MESA_FORMAT_R8; + components = 1; + } else if (srcImage->_BaseFormat == GL_RG) { + convertFormat = MESA_FORMAT_RG88; + components = 2; + } else if (srcImage->_BaseFormat == GL_RGBA) { convertFormat = MESA_FORMAT_RGBA8888; components = 4; } @@ -1536,15 +1774,15 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE) * srcImage->Width * srcImage->Height * srcImage->Depth + 20; /* 20 extra bytes, just be safe when calling last FetchTexel */ - srcData = (GLubyte *) _mesa_malloc(size); + srcData = (GLubyte *) malloc(size); if (!srcData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); return; } - dstData = (GLubyte *) _mesa_malloc(size / 2); /* 1/4 would probably be OK */ + dstData = (GLubyte *) malloc(size / 2); /* 1/4 would probably be OK */ if (!dstData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); - _mesa_free((void *) srcData); + free((void *) srcData); return; } @@ -1572,7 +1810,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, struct gl_texture_image *dstImage; GLint srcWidth, srcHeight, srcDepth; GLint dstWidth, dstHeight, dstDepth; - GLint border, bytesPerTexel; + GLint border; GLboolean nextLevel; /* get src image parameters */ @@ -1589,8 +1827,8 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, if (!nextLevel) { /* all done */ if (_mesa_is_format_compressed(srcImage->TexFormat)) { - _mesa_free((void *) srcData); - _mesa_free(dstData); + free((void *) srcData); + free(dstData); } return; } @@ -1608,41 +1846,30 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, /* initialize new image */ _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight, - dstDepth, border, srcImage->InternalFormat); + dstDepth, border, srcImage->InternalFormat, + srcImage->TexFormat); dstImage->DriverData = NULL; - dstImage->TexFormat = srcImage->TexFormat; dstImage->FetchTexelc = srcImage->FetchTexelc; dstImage->FetchTexelf = srcImage->FetchTexelf; - /* Alloc new teximage data buffer. - * Setup src and dest data pointers. - */ - if (_mesa_is_format_compressed(dstImage->TexFormat)) { - GLuint dstCompressedSize - = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width, - dstImage->Height, - dstImage->Depth, - dstImage->TexFormat); - ASSERT(dstCompressedSize > 0); - - dstImage->Data = _mesa_alloc_texmemory(dstCompressedSize); + /* Alloc new teximage data buffer */ + { + GLuint size = _mesa_format_image_size(dstImage->TexFormat, + dstWidth, dstHeight, dstDepth); + dstImage->Data = _mesa_alloc_texmemory(size); if (!dstImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); return; } + } + + /* Setup src and dest data pointers */ + if (_mesa_is_format_compressed(dstImage->TexFormat)) { /* srcData and dstData are already set */ ASSERT(srcData); ASSERT(dstData); } else { - bytesPerTexel = _mesa_get_format_bytes(dstImage->TexFormat); - ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0); - dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight - * dstDepth * bytesPerTexel); - if (!dstImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps"); - return; - } srcData = (const GLubyte *) srcImage->Data; dstData = (GLubyte *) dstImage->Data; } @@ -1663,7 +1890,7 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, /* compress image from dstData into dstImage->Data */ const GLenum srcFormat = _mesa_get_format_base_format(convertFormat); GLint dstRowStride - = _mesa_compressed_row_stride(dstImage->TexFormat, dstWidth); + = _mesa_format_row_stride(dstImage->TexFormat, dstWidth); ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA); _mesa_texstore(ctx, 2, dstImage->_BaseFormat,