aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/main/mipmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/main/mipmap.c')
-rw-r--r--mesalib/src/mesa/main/mipmap.c356
1 files changed, 131 insertions, 225 deletions
diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c
index 1ead5ee10..c2f922674 100644
--- a/mesalib/src/mesa/main/mipmap.c
+++ b/mesalib/src/mesa/main/mipmap.c
@@ -47,9 +47,9 @@ bytes_per_pixel(GLenum datatype, GLuint comps)
assert(b >= 0);
if (_mesa_type_is_packed(datatype))
- return b;
+ return b;
else
- return b * comps;
+ return b * comps;
}
@@ -1414,8 +1414,6 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
const GLint dstWidthNB = dstWidth - 2 * border;
const GLint dstHeightNB = dstHeight - 2 * border;
- const GLint srcRowBytes = bpt * srcRowStride;
- const GLint dstRowBytes = bpt * dstRowStride;
const GLubyte *srcA, *srcB;
GLubyte *dst;
GLint row, srcRowStep;
@@ -1424,7 +1422,7 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
srcA = srcPtr + border * ((srcWidth + 1) * bpt);
if (srcHeight > 1 && srcHeight > dstHeight) {
/* sample from two source rows */
- srcB = srcA + srcRowBytes;
+ srcB = srcA + srcRowStride;
srcRowStep = 2;
}
else {
@@ -1438,9 +1436,9 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
for (row = 0; row < dstHeightNB; row++) {
do_row(datatype, comps, srcWidthNB, srcA, srcB,
dstWidthNB, dst);
- srcA += srcRowStep * srcRowBytes;
- srcB += srcRowStep * srcRowBytes;
- dst += dstRowBytes;
+ srcA += srcRowStep * srcRowStride;
+ srcB += srcRowStep * srcRowStride;
+ dst += dstRowStride;
}
/* This is ugly but probably won't be used much */
@@ -1500,9 +1498,9 @@ make_2d_mipmap(GLenum datatype, GLuint comps, GLint border,
static void
make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
- const GLubyte *srcPtr, GLint srcRowStride,
+ const GLubyte **srcPtr, GLint srcRowStride,
GLint dstWidth, GLint dstHeight, GLint dstDepth,
- GLubyte *dstPtr, GLint dstRowStride)
+ GLubyte **dstPtr, GLint dstRowStride)
{
const GLint bpt = bytes_per_pixel(datatype, comps);
const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */
@@ -1525,7 +1523,7 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
bytesPerDstRow = dstWidth * bpt;
/* Offset between adjacent src images to be averaged together */
- srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
+ srcImageOffset = (srcDepth == dstDepth) ? 0 : 1;
/* Offset between adjacent src rows to be averaged together */
srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
@@ -1545,15 +1543,15 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
for (img = 0; img < dstDepthNB; img++) {
/* first source image pointer, skipping border */
- const GLubyte *imgSrcA = srcPtr
- + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
- + img * (bytesPerSrcImage + srcImageOffset);
+ const GLubyte *imgSrcA = srcPtr[img * 2 + border]
+ + bytesPerSrcRow * border + bpt * border;
/* second source image pointer, skipping border */
- const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
+ const GLubyte *imgSrcB = srcPtr[img * 2 + srcImageOffset + border]
+ + bytesPerSrcRow * border + bpt * border;
+
/* address of the dest image, skipping border */
- GLubyte *imgDst = dstPtr
- + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
- + img * bytesPerDstImage;
+ GLubyte *imgDst = dstPtr[img + border]
+ + bytesPerDstRow * border + bpt * border;
/* setup the four source row pointers and the dest row pointer */
const GLubyte *srcImgARowA = imgSrcA;
@@ -1581,13 +1579,14 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
/* Luckily we can leverage the make_2d_mipmap() function here! */
if (border > 0) {
/* do front border image */
- make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight, srcPtr, srcRowStride,
- dstWidth, dstHeight, dstPtr, dstRowStride);
+ make_2d_mipmap(datatype, comps, 1,
+ srcWidth, srcHeight, srcPtr[0], srcRowStride,
+ dstWidth, dstHeight, dstPtr[0], dstRowStride);
/* do back border image */
- make_2d_mipmap(datatype, comps, 1, srcWidth, srcHeight,
- srcPtr + bytesPerSrcImage * (srcDepth - 1), srcRowStride,
- dstWidth, dstHeight,
- dstPtr + bytesPerDstImage * (dstDepth - 1), dstRowStride);
+ make_2d_mipmap(datatype, comps, 1,
+ srcWidth, srcHeight, srcPtr[srcDepth - 1], srcRowStride,
+ dstWidth, dstHeight, dstPtr[dstDepth - 1], dstRowStride);
+
/* do four remaining border edges that span the image slices */
if (srcDepth == dstDepth) {
/* just copy border pixels from src to dst */
@@ -1596,29 +1595,23 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
GLubyte *dst;
/* do border along [img][row=0][col=0] */
- src = srcPtr + (img + 1) * bytesPerSrcImage;
- dst = dstPtr + (img + 1) * bytesPerDstImage;
+ src = srcPtr[img * 2];
+ dst = dstPtr[img];
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;
+ src = srcPtr[img * 2] + (srcHeight - 1) * bytesPerSrcRow;
+ dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow;
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;
+ src = srcPtr[img * 2] + (srcWidth - 1) * bpt;
+ dst = dstPtr[img] + (dstWidth - 1) * 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);
+ src = srcPtr[img * 2] + (bytesPerSrcImage - bpt);
+ dst = dstPtr[img] + (bytesPerDstImage - bpt);
memcpy(dst, src, bpt);
}
}
@@ -1626,170 +1619,34 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border,
/* average border pixels from adjacent src image pairs */
ASSERT(srcDepthNB == 2 * dstDepthNB);
for (img = 0; img < dstDepthNB; img++) {
- const GLubyte *src;
+ const GLubyte *srcA, *srcB;
GLubyte *dst;
/* do border along [img][row=0][col=0] */
- src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
- dst = dstPtr + (img + 1) * bytesPerDstImage;
- do_row(datatype, comps, 1, src, src + srcImageOffset, 1, dst);
+ srcA = srcPtr[img * 2 + 0];
+ srcB = srcPtr[img * 2 + srcImageOffset];
+ dst = dstPtr[img];
+ do_row(datatype, comps, 1, srcA, srcB, 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(datatype, comps, 1, src, src + srcImageOffset, 1, dst);
+ srcA = srcPtr[img * 2 + 0]
+ + (srcHeight - 1) * bytesPerSrcRow;
+ srcB = srcPtr[img * 2 + srcImageOffset]
+ + (srcHeight - 1) * bytesPerSrcRow;
+ dst = dstPtr[img] + (dstHeight - 1) * bytesPerDstRow;
+ do_row(datatype, comps, 1, srcA, srcB, 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(datatype, comps, 1, src, src + srcImageOffset, 1, dst);
+ srcA = srcPtr[img * 2 + 0] + (srcWidth - 1) * bpt;
+ srcB = srcPtr[img * 2 + srcImageOffset] + (srcWidth - 1) * bpt;
+ dst = dstPtr[img] + (dstWidth - 1) * bpt;
+ do_row(datatype, comps, 1, srcA, srcB, 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(datatype, comps, 1, src, src + srcImageOffset, 1, dst);
- }
- }
- }
-}
-
-
-static void
-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 = 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;
- const GLint srcRowBytes = bpt * srcRowStride;
- const GLint dstRowBytes = bpt * dstRowStride;
- const GLubyte *src;
- GLubyte *dst;
- GLint row;
-
- /* Compute src and dst pointers, skipping any border */
- src = srcPtr + border * ((srcWidth + 1) * bpt);
- dst = dstPtr + border * ((dstWidth + 1) * bpt);
-
- for (row = 0; row < dstHeightNB; row++) {
- do_row(datatype, comps, srcWidthNB, src, src,
- dstWidthNB, dst);
- src += srcRowBytes;
- dst += dstRowBytes;
- }
-
- if (border) {
- /* copy left-most pixel from source */
- assert(dstPtr);
- assert(srcPtr);
- memcpy(dstPtr, srcPtr, bpt);
- /* copy right-most pixel from source */
- memcpy(dstPtr + (dstWidth - 1) * bpt,
- srcPtr + (srcWidth - 1) * bpt,
- bpt);
- }
-}
-
-
-/**
- * \bug
- * There is quite a bit of refactoring that could be done with this function
- * and \c make_2d_mipmap.
- */
-static void
-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 = 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;
- const GLint dstDepthNB = dstDepth - 2 * border;
- const GLint srcRowBytes = bpt * srcRowStride;
- const GLint dstRowBytes = bpt * dstRowStride;
- const GLubyte *srcA, *srcB;
- GLubyte *dst;
- GLint layer;
- GLint row;
-
- /* Compute src and dst pointers, skipping any border */
- srcA = srcPtr + border * ((srcWidth + 1) * bpt);
- if (srcHeight > 1)
- srcB = srcA + srcRowBytes;
- else
- srcB = srcA;
- dst = dstPtr + border * ((dstWidth + 1) * bpt);
-
- for (layer = 0; layer < dstDepthNB; layer++) {
- for (row = 0; row < dstHeightNB; row++) {
- do_row(datatype, comps, srcWidthNB, srcA, srcB,
- dstWidthNB, dst);
- srcA += 2 * srcRowBytes;
- srcB += 2 * srcRowBytes;
- dst += dstRowBytes;
- }
-
- /* This is ugly but probably won't be used much */
- if (border > 0) {
- /* fill in dest border */
- /* lower-left border pixel */
- assert(dstPtr);
- assert(srcPtr);
- memcpy(dstPtr, srcPtr, bpt);
- /* lower-right border pixel */
- memcpy(dstPtr + (dstWidth - 1) * bpt,
- srcPtr + (srcWidth - 1) * bpt, bpt);
- /* upper-left border pixel */
- memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt,
- srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
- /* upper-right border pixel */
- memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt,
- srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
- /* lower border */
- do_row(datatype, comps, srcWidthNB,
- srcPtr + bpt,
- srcPtr + bpt,
- dstWidthNB, dstPtr + bpt);
- /* upper border */
- do_row(datatype, comps, srcWidthNB,
- srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
- srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
- dstWidthNB,
- dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
- /* left and right borders */
- if (srcHeight == dstHeight) {
- /* copy border pixel from src to dst */
- for (row = 1; row < srcHeight; row++) {
- memcpy(dstPtr + dstWidth * row * bpt,
- srcPtr + srcWidth * row * bpt, bpt);
- memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
- srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
- }
- }
- else {
- /* average two src pixels each dest pixel */
- for (row = 0; row < dstHeightNB; row += 2) {
- 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(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);
- }
+ srcA = srcPtr[img * 2 + 0] + (bytesPerSrcImage - bpt);
+ srcB = srcPtr[img * 2 + srcImageOffset] + (bytesPerSrcImage - bpt);
+ dst = dstPtr[img] + (bytesPerDstImage - bpt);
+ do_row(datatype, comps, 1, srcA, srcB, 1, dst);
}
}
}
@@ -1799,28 +1656,29 @@ make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
/**
* Down-sample a texture image to produce the next lower mipmap level.
* \param comps components per texel (1, 2, 3 or 4)
- * \param srcRowStride stride between source rows, in texels
- * \param dstRowStride stride between destination rows, in texels
+ * \param srcData array[slice] of pointers to source image slices
+ * \param dstData array[slice] of pointers to dest image slices
+ * \param srcRowStride stride between source rows, in bytes
+ * \param dstRowStride stride between destination rows, in bytes
*/
void
_mesa_generate_mipmap_level(GLenum target,
GLenum datatype, GLuint comps,
GLint border,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
- const GLubyte *srcData,
+ const GLubyte **srcData,
GLint srcRowStride,
GLint dstWidth, GLint dstHeight, GLint dstDepth,
- GLubyte *dstData,
+ GLubyte **dstData,
GLint dstRowStride)
{
- /*
- * We use simple 2x2 averaging to compute the next mipmap level.
- */
+ int i;
+
switch (target) {
case GL_TEXTURE_1D:
make_1d_mipmap(datatype, comps, border,
- srcWidth, srcData,
- dstWidth, dstData);
+ srcWidth, srcData[0],
+ dstWidth, dstData[0]);
break;
case GL_TEXTURE_2D:
case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
@@ -1830,8 +1688,8 @@ _mesa_generate_mipmap_level(GLenum target,
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
make_2d_mipmap(datatype, comps, border,
- srcWidth, srcHeight, srcData, srcRowStride,
- dstWidth, dstHeight, dstData, dstRowStride);
+ srcWidth, srcHeight, srcData[0], srcRowStride,
+ dstWidth, dstHeight, dstData[0], dstRowStride);
break;
case GL_TEXTURE_3D:
make_3d_mipmap(datatype, comps, border,
@@ -1841,23 +1699,26 @@ _mesa_generate_mipmap_level(GLenum target,
dstData, dstRowStride);
break;
case GL_TEXTURE_1D_ARRAY_EXT:
- make_1d_stack_mipmap(datatype, comps, border,
- srcWidth, srcData, srcRowStride,
- dstWidth, dstHeight,
- dstData, dstRowStride);
+ assert(srcHeight == 1);
+ assert(dstHeight == 1);
+ for (i = 0; i < dstDepth; i++) {
+ make_1d_mipmap(datatype, comps, border,
+ srcWidth, srcData[i],
+ dstWidth, dstData[i]);
+ }
break;
case GL_TEXTURE_2D_ARRAY_EXT:
- make_2d_stack_mipmap(datatype, comps, border,
- srcWidth, srcHeight,
- srcData, srcRowStride,
- dstWidth, dstHeight,
- dstDepth, dstData, dstRowStride);
+ for (i = 0; i < dstDepth; i++) {
+ make_2d_mipmap(datatype, comps, border,
+ srcWidth, srcHeight, srcData[i], srcRowStride,
+ dstWidth, dstHeight, dstData[i], dstRowStride);
+ }
break;
case GL_TEXTURE_RECTANGLE_NV:
/* no mipmaps, do nothing */
break;
default:
- _mesa_problem(NULL, "bad dimensions in _mesa_generate_mipmaps");
+ _mesa_problem(NULL, "bad tex target in _mesa_generate_mipmaps");
return;
}
}
@@ -1919,12 +1780,14 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
for (level = texObj->BaseLevel; level < maxLevel; level++) {
/* generate image[level+1] from image[level] */
- const struct gl_texture_image *srcImage;
- struct gl_texture_image *dstImage;
+ struct gl_texture_image *srcImage, *dstImage;
+ GLint srcRowStride, dstRowStride;
GLint srcWidth, srcHeight, srcDepth;
GLint dstWidth, dstHeight, dstDepth;
GLint border;
+ GLint slice;
GLboolean nextLevel;
+ GLubyte **srcMaps, **dstMaps;
/* get src image parameters */
srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -1950,7 +1813,6 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
/* Free old image data */
ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
- /* initialize new image */
_mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
dstDepth, border, srcImage->InternalFormat,
srcImage->TexFormat);
@@ -1967,15 +1829,54 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
ASSERT(dstImage->TexFormat);
+ if (target == GL_TEXTURE_1D_ARRAY) {
+ srcDepth = srcHeight;
+ dstDepth = dstHeight;
+ srcHeight = 1;
+ dstHeight = 1;
+ }
+
+ /* Map src texture image slices */
+ srcMaps = (GLubyte **) malloc(srcDepth * sizeof(GLubyte *));
+ for (slice = 0; slice < srcDepth; slice++) {
+ ctx->Driver.MapTextureImage(ctx, srcImage, slice,
+ 0, 0, srcWidth, srcHeight,
+ GL_MAP_READ_BIT,
+ &srcMaps[slice], &srcRowStride);
+ }
+
+ /* Map dst texture image slices */
+ dstMaps = (GLubyte **) malloc(dstDepth * sizeof(GLubyte *));
+ for (slice = 0; slice < dstDepth; slice++) {
+ ctx->Driver.MapTextureImage(ctx, dstImage, slice,
+ 0, 0, dstWidth, dstHeight,
+ GL_MAP_WRITE_BIT,
+ &dstMaps[slice], &dstRowStride);
+ }
+
+ /* generate one mipmap level (for 1D/2D/3D/array/etc texture) */
_mesa_generate_mipmap_level(target, datatype, comps, border,
srcWidth, srcHeight, srcDepth,
- srcImage->Data, srcImage->RowStride,
+ (const GLubyte **) srcMaps, srcRowStride,
dstWidth, dstHeight, dstDepth,
- dstImage->Data, dstImage->RowStride);
+ dstMaps, dstRowStride);
+
+ /* Unmap src image slices */
+ for (slice = 0; slice < srcDepth; slice++) {
+ ctx->Driver.UnmapTextureImage(ctx, srcImage, slice);
+ }
+ free(srcMaps);
+
+ /* Unmap dst image slices */
+ for (slice = 0; slice < dstDepth; slice++) {
+ ctx->Driver.UnmapTextureImage(ctx, dstImage, slice);
+ }
+ free(dstMaps);
} /* loop over mipmap levels */
}
+
static void
generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
struct gl_texture_object *texObj,
@@ -1985,7 +1886,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
GLint level;
gl_format temp_format;
GLint components;
- GLuint temp_src_stride, temp_dst_stride; /* in bytes */
+ GLuint temp_src_stride; /* in bytes */
GLubyte *temp_src = NULL, *temp_dst = NULL;
GLenum temp_datatype;
GLenum temp_base_format;
@@ -2032,9 +1933,10 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
ctx->Pack = ctx->DefaultPacking;
/* Get the uncompressed image */
- ctx->Driver.GetTexImage(ctx, target, texObj->BaseLevel,
+ assert(srcImage->Level == texObj->BaseLevel);
+ ctx->Driver.GetTexImage(ctx,
temp_base_format, temp_datatype,
- temp_src, texObj, srcImage);
+ temp_src, srcImage);
/* restore packing mode */
ctx->Pack = save;
}
@@ -2048,6 +1950,7 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
GLint dstWidth, dstHeight, dstDepth;
GLint border;
GLboolean nextLevel;
+ GLuint temp_dst_stride; /* in bytes */
/* get src image parameters */
srcImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -2084,15 +1987,19 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
_mesa_generate_mipmap_level(target, temp_datatype, components, border,
srcWidth, srcHeight, srcDepth,
- temp_src, temp_src_stride / components,
+ (const GLubyte **) &temp_src,
+ temp_src_stride,
dstWidth, dstHeight, dstDepth,
- temp_dst, temp_dst_stride / components);
+ &temp_dst, temp_dst_stride);
/* initialize new image */
_mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
dstDepth, border, srcImage->InternalFormat,
srcImage->TexFormat);
+ /* Free old dest texture image buffer */
+ ctx->Driver.FreeTextureImageBuffer(ctx, dstImage);
+
ctx->Driver.TexImage2D(ctx, target, level + 1,
srcImage->InternalFormat,
dstWidth, dstHeight, border,
@@ -2104,7 +2011,6 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
GLubyte *temp = temp_src;
temp_src = temp_dst;
temp_dst = temp;
-
temp_src_stride = temp_dst_stride;
}
} /* loop over mipmap levels */