This patch fixes many Piglit tests [failing due to assert(region->map_refcount 
== 0)]
on SNB when HiZ is enabled, and causes no regressions.

Tested-by: Chad Versace <c...@chad-versace.us>

On 09/27/2011 12:27 PM, Eric Anholt wrote:
From: Brian Paul<bri...@vmware.com>

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.
---
  src/mesa/drivers/dri/intel/intel_tex.c         |   30 +---
  src/mesa/drivers/dri/nouveau/nouveau_texture.c |   10 -
  src/mesa/drivers/dri/radeon/radeon_texture.c   |   50 +-----
  src/mesa/main/mipmap.c                         |  270 +++++++++++++-----------
  src/mesa/main/mipmap.h                         |    4 +-
  src/mesa/state_tracker/st_gen_mipmap.c         |  205 +------------------
  6 files changed, 153 insertions(+), 416 deletions(-)

diff --git a/src/mesa/drivers/dri/intel/intel_tex.c 
b/src/mesa/drivers/dri/intel/intel_tex.c
index 55b3e34..bc7b1f6 100644
--- a/src/mesa/drivers/dri/intel/intel_tex.c
+++ b/src/mesa/drivers/dri/intel/intel_tex.c
@@ -163,37 +163,9 @@ intelGenerateMipmap(struct gl_context *ctx, GLenum target,
                      struct gl_texture_object *texObj)
  {
     if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
-      /* sw path: need to map texture images */
-      struct intel_context *intel = intel_context(ctx);
-      struct intel_texture_object *intelObj = intel_texture_object(texObj);
-      struct gl_texture_image *first_image = 
texObj->Image[0][texObj->BaseLevel];
-
        fallback_debug("%s - fallback to swrast\n", __FUNCTION__);

-      if (_mesa_is_format_compressed(first_image->TexFormat)) {
-         _mesa_generate_mipmap(ctx, target, texObj);
-      } else {
-         intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel);
-         _mesa_generate_mipmap(ctx, target, texObj);
-         intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel);
-      }
-
-      if (!_mesa_is_format_compressed(first_image->TexFormat)) {
-         GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
-         GLuint face, i;
-         for (face = 0; face<  nr_faces; face++) {
-            for (i = texObj->BaseLevel + 1; i<  texObj->MaxLevel; i++) {
-               struct intel_texture_image *intelImage =
-                  intel_texture_image(texObj->Image[face][i]);
-               if (!intelImage)
-                  break;
-               /* Unreference the miptree to signal that the new Data is a
-                * bare pointer from mesa.
-                */
-               intel_miptree_release(&intelImage->mt);
-            }
-         }
-      }
+      _mesa_generate_mipmap(ctx, target, texObj);
     }
     else {
        _mesa_meta_GenerateMipmap(ctx, target, texObj);
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_texture.c 
b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
index 9dc2186..508c8a5 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_texture.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_texture.c
@@ -739,17 +739,7 @@ nouveau_generate_mipmap(struct gl_context *ctx, GLenum 
target,
  {
        if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, t)) {
                struct gl_texture_image *base = t->Image[0][t->BaseLevel];
-
-               nouveau_teximage_map(ctx, base, GL_MAP_READ_BIT,
-                                    0, 0, base->Width, base->Height);
                _mesa_generate_mipmap(ctx, target, t);
-               nouveau_teximage_unmap(ctx, base);
-
-               if (!_mesa_is_format_compressed(base->TexFormat)) {
-                       store_mipmap(ctx, target, t->BaseLevel + 1,
-                                    get_last_level(t), t);
-               }
-
        } else {
                _mesa_meta_GenerateMipmap(ctx, target, t);
        }
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c 
b/src/mesa/drivers/dri/radeon/radeon_texture.c
index 7f824ce..6bd8967 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -324,52 +324,6 @@ radeon_unmap_texture_image(struct gl_context *ctx,
                radeon_bo_unmap(image->mt->bo);
  }

-/**
- * Wraps Mesa's implementation to ensure that the base level image is mapped.
- *
- * This relies on internal details of _mesa_generate_mipmap, in particular
- * the fact that the memory for recreated texture images is always freed.
- */
-static void radeon_generate_mipmap(struct gl_context *ctx, GLenum target,
-                                  struct gl_texture_object *texObj)
-{
-       radeonTexObj* t = radeon_tex_obj(texObj);
-       GLuint nr_faces = (t->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
-       int i, face;
-       struct gl_texture_image *first_image;
-
-       radeon_print(RADEON_TEXTURE, RADEON_VERBOSE,
-                       "%s(%p, tex %p) Target type %s.\n",
-                       __func__, ctx, texObj,
-                       _mesa_lookup_enum_by_nr(target));
-
-       _mesa_generate_mipmap(ctx, target, texObj);
-
-       /* For the compressed case, we don't need to do the
-        * non-TexImage recovery path below.
-        */
-       first_image = texObj->Image[0][texObj->BaseLevel];
-       if (_mesa_is_format_compressed(first_image->TexFormat))
-               return;
-
-       for (face = 0; face<  nr_faces; face++) {
-               for (i = texObj->BaseLevel + 1; i<  texObj->MaxLevel; i++) {
-                       radeon_texture_image *image;
-
-                       image = 
get_radeon_texture_image(texObj->Image[face][i]);
-
-                       if (image == NULL)
-                               break;
-
-                       image->mtlevel = i;
-                       image->mtface = face;
-
-                       radeon_miptree_unreference(&image->mt);
-               }
-       }
-       
-}
-
  void radeonGenerateMipmap(struct gl_context* ctx, GLenum target, struct 
gl_texture_object *texObj)
  {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
@@ -392,9 +346,7 @@ void radeonGenerateMipmap(struct gl_context* ctx, GLenum 
target, struct gl_textu
        }

        if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) {
-               radeon_teximage_map(baseimage, GL_FALSE);
-               radeon_generate_mipmap(ctx, target, texObj);
-               radeon_teximage_unmap(baseimage);
+               _mesa_generate_mipmap(ctx, target, texObj);
        } else {
                _mesa_meta_GenerateMipmap(ctx, target, texObj);
        }
diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index e0cc6a2..4c8ab23 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;
@@ -2048,6 +2070,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 +2107,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 +2131,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 */
diff --git a/src/mesa/main/mipmap.h b/src/mesa/main/mipmap.h
index 4783950..8b7cd7d 100644
--- a/src/mesa/main/mipmap.h
+++ b/src/mesa/main/mipmap.h
@@ -34,10 +34,10 @@ _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);


diff --git a/src/mesa/state_tracker/st_gen_mipmap.c 
b/src/mesa/state_tracker/st_gen_mipmap.c
index e53da5f..36fea3d 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -106,209 +106,6 @@ st_render_mipmap(struct st_context *st,
     return TRUE;
  }

-
-/**
- * Helper function to decompress an image.  The result is a 32-bpp RGBA
- * image with stride==width.
- */
-static void
-decompress_image(enum pipe_format format, int datatype,
-                 const uint8_t *src, void *dst,
-                 unsigned width, unsigned height, unsigned src_stride)
-{
-   const struct util_format_description *desc = 
util_format_description(format);
-   const uint bw = util_format_get_blockwidth(format);
-   const uint bh = util_format_get_blockheight(format);
-   uint dst_stride = 4 * MAX2(width, bw);
-
-   if (datatype == GL_FLOAT) {
-      desc->unpack_rgba_float((float *)dst, dst_stride * sizeof(GLfloat), src, 
src_stride, width, height);
-      if (width<  bw || height<  bh) {
-        float *dst_p = (float *)dst;
-        /* We're decompressing an image smaller than the compression
-         * block size.  We don't want garbage pixel values in the region
-         * outside (width x height) so replicate pixels from the (width
-         * x height) region to fill out the (bw x bh) block size.
-         */
-        uint x, y;
-        for (y = 0; y<  bh; y++) {
-           for (x = 0; x<  bw; x++) {
-              if (x>= width || y>= height) {
-                 uint p = (y * bw + x) * 4;
-                 dst_p[p + 0] = dst_p[0];
-                 dst_p[p + 1] = dst_p[1];
-                 dst_p[p + 2] = dst_p[2];
-                 dst_p[p + 3] = dst_p[3];
-              }
-           }
-        }
-      }
-   } else {
-      desc->unpack_rgba_8unorm((uint8_t *)dst, dst_stride, src, src_stride, 
width, height);
-      if (width<  bw || height<  bh) {
-        uint8_t *dst_p = (uint8_t *)dst;
-        /* We're decompressing an image smaller than the compression
-         * block size.  We don't want garbage pixel values in the region
-         * outside (width x height) so replicate pixels from the (width
-         * x height) region to fill out the (bw x bh) block size.
-         */
-        uint x, y;
-        for (y = 0; y<  bh; y++) {
-           for (x = 0; x<  bw; x++) {
-              if (x>= width || y>= height) {
-                 uint p = (y * bw + x) * 4;
-                 dst_p[p + 0] = dst_p[0];
-                 dst_p[p + 1] = dst_p[1];
-                 dst_p[p + 2] = dst_p[2];
-                 dst_p[p + 3] = dst_p[3];
-              }
-           }
-        }
-      }
-   }
-}
-
-/**
- * Helper function to compress an image.  The source is a 32-bpp RGBA image
- * with stride==width.
- */
-static void
-compress_image(enum pipe_format format, int datatype,
-               const void *src, uint8_t *dst,
-               unsigned width, unsigned height, unsigned dst_stride)
-{
-   const struct util_format_description *desc = 
util_format_description(format);
-   const uint src_stride = 4 * width;
-
-   if (datatype == GL_FLOAT)
-      desc->pack_rgba_float(dst, dst_stride, (GLfloat *)src, src_stride * 
sizeof(GLfloat), width, height);
-   else
-      desc->pack_rgba_8unorm(dst, dst_stride, (uint8_t *)src, src_stride, 
width, height);
-}
-
-
-/**
- * Software fallback for generate mipmap levels.
- */
-static void
-fallback_generate_mipmap(struct gl_context *ctx, GLenum target,
-                         struct gl_texture_object *texObj)
-{
-   struct pipe_context *pipe = st_context(ctx)->pipe;
-   struct pipe_resource *pt = st_get_texobj_resource(texObj);
-   const uint baseLevel = texObj->BaseLevel;
-   const uint lastLevel = pt->last_level;
-   const uint face = _mesa_tex_target_to_face(target);
-   uint dstLevel;
-   GLenum datatype;
-   GLuint comps;
-   GLboolean compressed;
-
-   if (ST_DEBUG&  DEBUG_FALLBACK)
-      debug_printf("%s: fallback processing\n", __FUNCTION__);
-
-   assert(target != GL_TEXTURE_3D); /* not done yet */
-
-   compressed =
-      _mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat);
-
-   if (compressed) {
-      GLenum type =
-         _mesa_get_format_datatype(texObj->Image[face][baseLevel]->TexFormat);
-
-      datatype = type == GL_UNSIGNED_NORMALIZED ? GL_UNSIGNED_BYTE : GL_FLOAT;
-      comps = 4;
-   }
-   else {
-      _mesa_format_to_type_and_comps(texObj->Image[face][baseLevel]->TexFormat,
-&datatype,&comps);
-      assert(comps>  0&&  "bad texture format in fallback_generate_mipmap()");
-   }
-
-   for (dstLevel = baseLevel + 1; dstLevel<= lastLevel; dstLevel++) {
-      const uint srcLevel = dstLevel - 1;
-      const uint srcWidth = u_minify(pt->width0, srcLevel);
-      const uint srcHeight = u_minify(pt->height0, srcLevel);
-      const uint srcDepth = u_minify(pt->depth0, srcLevel);
-      const uint dstWidth = u_minify(pt->width0, dstLevel);
-      const uint dstHeight = u_minify(pt->height0, dstLevel);
-      const uint dstDepth = u_minify(pt->depth0, dstLevel);
-      struct pipe_transfer *srcTrans, *dstTrans;
-      const ubyte *srcData;
-      ubyte *dstData;
-      int srcStride, dstStride;
-
-      srcTrans = pipe_get_transfer(pipe, pt, srcLevel,
-                                   face,
-                                   PIPE_TRANSFER_READ, 0, 0,
-                                   srcWidth, srcHeight);
-
-      dstTrans = pipe_get_transfer(pipe, pt, dstLevel,
-                                   face,
-                                   PIPE_TRANSFER_WRITE, 0, 0,
-                                   dstWidth, dstHeight);
-
-      srcData = (ubyte *) pipe_transfer_map(pipe, srcTrans);
-      dstData = (ubyte *) pipe_transfer_map(pipe, dstTrans);
-
-      srcStride = srcTrans->stride / 
util_format_get_blocksize(srcTrans->resource->format);
-      dstStride = dstTrans->stride / 
util_format_get_blocksize(dstTrans->resource->format);
-
-     /* this cannot work correctly for 3d since it does
-        not respect layerStride. */
-      if (compressed) {
-         const enum pipe_format format = pt->format;
-         const uint bw = util_format_get_blockwidth(format);
-         const uint bh = util_format_get_blockheight(format);
-         const uint srcWidth2 = align(srcWidth, bw);
-         const uint srcHeight2 = align(srcHeight, bh);
-         const uint dstWidth2 = align(dstWidth, bw);
-         const uint dstHeight2 = align(dstHeight, bh);
-         uint8_t *srcTemp, *dstTemp;
-
-         assert(comps == 4);
-
-         srcTemp = malloc(srcWidth2 * srcHeight2 * comps * (datatype == 
GL_FLOAT ? 4 : 1));
-         dstTemp = malloc(dstWidth2 * dstHeight2 * comps * (datatype == 
GL_FLOAT ? 4 : 1));
-
-         /* decompress the src image: srcData ->  srcTemp */
-         decompress_image(format, datatype, srcData, srcTemp, srcWidth2, 
srcHeight2, srcTrans->stride);
-
-         _mesa_generate_mipmap_level(target, datatype, comps,
-                                     0 /*border*/,
-                                     srcWidth2, srcHeight2, srcDepth,
-                                     srcTemp,
-                                     srcWidth2, /* stride in texels */
-                                     dstWidth2, dstHeight2, dstDepth,
-                                     dstTemp,
-                                     dstWidth2); /* stride in texels */
-
-         /* compress the new image: dstTemp ->  dstData */
-         compress_image(format, datatype, dstTemp, dstData, dstWidth2, 
dstHeight2, dstTrans->stride);
-
-         free(srcTemp);
-         free(dstTemp);
-      }
-      else {
-         _mesa_generate_mipmap_level(target, datatype, comps,
-                                     0 /*border*/,
-                                     srcWidth, srcHeight, srcDepth,
-                                     srcData,
-                                     srcStride, /* stride in texels */
-                                     dstWidth, dstHeight, dstDepth,
-                                     dstData,
-                                     dstStride); /* stride in texels */
-      }
-
-      pipe_transfer_unmap(pipe, srcTrans);
-      pipe_transfer_unmap(pipe, dstTrans);
-
-      pipe->transfer_destroy(pipe, srcTrans);
-      pipe->transfer_destroy(pipe, dstTrans);
-   }
-}
-
-
  /**
   * Compute the expected number of mipmap levels in the texture given
   * the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/
@@ -422,7 +219,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
     if (!st_render_mipmap(st, target, stObj, baseLevel, lastLevel)) {
        /* since the util code actually also has a fallback, should
           probably make it never fail and kill this */
-      fallback_generate_mipmap(ctx, target, texObj);
+      _mesa_generate_mipmap(ctx, target, texObj);
     }

     /* Fill in the Mesa gl_texture_image fields */
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to