summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/mipmap.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2011-08-01 23:04:12 -0700
committerEric Anholt <[email protected]>2011-10-03 13:29:30 -0700
commite0304180c32227342dbb67b707bfae446543bb48 (patch)
tree05224697ca0948eded9adb328a215bc2c5a3a24f /src/mesa/main/mipmap.c
parent1165b64f561a7bdd3f603d9e30a2340774ba31ee (diff)
mesa: Convert _mesa_generate_mipmap to MapTexImage()-based access.
Now that we can zero-copy generate the mipmaps into brand new glTexImage()-generated storage using MapTextureImage(), we no longer need to allocate image->Data in mipmap generate. This requires deleting the drivers' old overrides of the miptree tracking after calling _mesa_generate_mipmap at the same time, or the drivers promptly lose our newly-generated data. Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/mesa/main/mipmap.c')
-rw-r--r--src/mesa/main/mipmap.c270
1 files changed, 148 insertions, 122 deletions
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 7325a420f0e..cc46f5c4d22 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -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,34 +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);
+ 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);
}
}
}
@@ -1670,8 +1663,6 @@ make_1d_stack_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 *src;
GLubyte *dst;
GLint row;
@@ -1683,8 +1674,8 @@ make_1d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
for (row = 0; row < dstHeightNB; row++) {
do_row(datatype, comps, srcWidthNB, src, src,
dstWidthNB, dst);
- src += srcRowBytes;
- dst += dstRowBytes;
+ src += srcRowStride;
+ dst += dstRowStride;
}
if (border) {
@@ -1708,87 +1699,86 @@ make_1d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
static void
make_2d_stack_mipmap(GLenum datatype, GLuint comps, GLint border,
GLint srcWidth, GLint srcHeight,
- 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 */
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++) {
+
+ /* Compute src and dst pointers, skipping any border */
+ srcA = srcPtr[layer] + border * (srcWidth + 1) * bpt;
+ if (srcHeight > 1)
+ srcB = srcA + srcRowStride;
+ else
+ srcB = srcA;
+ dst = dstPtr[layer] + 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;
- dst += dstRowBytes;
+ srcA += 2 * srcRowStride;
+ srcB += 2 * srcRowStride;
+ dst += dstRowStride;
}
/* 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);
+ assert(dstPtr[layer]);
+ assert(srcPtr[layer]);
+ memcpy(dstPtr[layer], srcPtr[0], bpt);
/* lower-right border pixel */
- memcpy(dstPtr + (dstWidth - 1) * bpt,
- srcPtr + (srcWidth - 1) * bpt, bpt);
+ memcpy(dstPtr[layer] + (dstWidth - 1) * bpt,
+ srcPtr[layer] + (srcWidth - 1) * bpt, bpt);
/* upper-left border pixel */
- memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt,
- srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
+ memcpy(dstPtr[layer] + dstWidth * (dstHeight - 1) * bpt,
+ srcPtr[layer] + srcWidth * (srcHeight - 1) * bpt, bpt);
/* upper-right border pixel */
- memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt,
- srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
+ memcpy(dstPtr[layer] + (dstWidth * dstHeight - 1) * bpt,
+ srcPtr[layer] + (srcWidth * srcHeight - 1) * bpt, bpt);
/* lower border */
do_row(datatype, comps, srcWidthNB,
- srcPtr + bpt,
- srcPtr + bpt,
- dstWidthNB, dstPtr + bpt);
+ srcPtr[layer] + bpt,
+ srcPtr[layer] + bpt,
+ dstWidthNB, dstPtr[layer] + bpt);
/* upper border */
do_row(datatype, comps, srcWidthNB,
- srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
- srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
+ srcPtr[layer] + (srcWidth * (srcHeight - 1) + 1) * bpt,
+ srcPtr[layer] + (srcWidth * (srcHeight - 1) + 1) * bpt,
dstWidthNB,
- dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
+ dstPtr[layer] + (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);
+ memcpy(dstPtr[layer] + dstWidth * row * bpt,
+ srcPtr[layer] + srcWidth * row * bpt, bpt);
+ memcpy(dstPtr[layer] + (dstWidth * row + dstWidth - 1) * bpt,
+ srcPtr[layer] + (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);
+ srcPtr[layer] + (srcWidth * (row * 2 + 1)) * bpt,
+ srcPtr[layer] + (srcWidth * (row * 2 + 2)) * bpt,
+ 1, dstPtr[layer] + (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);
+ srcPtr[layer] + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
+ srcPtr[layer] + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
+ 1, dstPtr[layer] + (dstWidth * row + 1 + dstWidth - 1) * bpt);
}
}
}
@@ -1799,28 +1789,27 @@ 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.
- */
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 +1819,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,
@@ -1842,9 +1831,9 @@ _mesa_generate_mipmap_level(GLenum target,
break;
case GL_TEXTURE_1D_ARRAY_EXT:
make_1d_stack_mipmap(datatype, comps, border,
- srcWidth, srcData, srcRowStride,
+ srcWidth, srcData[0], srcRowStride,
dstWidth, dstHeight,
- dstData, dstRowStride);
+ dstData[0], dstRowStride);
break;
case GL_TEXTURE_2D_ARRAY_EXT:
make_2d_stack_mipmap(datatype, comps, border,
@@ -1857,7 +1846,7 @@ _mesa_generate_mipmap_level(GLenum target,
/* 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 +1908,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 +1941,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 +1957,47 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
ASSERT(dstImage->TexFormat);
+ /* 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 src 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 +2007,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;
@@ -2049,6 +2071,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);
@@ -2085,15 +2108,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,
@@ -2105,7 +2132,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 */