Mesa (10.6): mesa: fix mipmap generation for immutable, compressed textures

Emil Velikov evelikov at kemper.freedesktop.org
Thu Oct 1 09:28:56 UTC 2015


Module: Mesa
Branch: 10.6
Commit: 41b44abdcbc5aa9a36afceee5f26fc7ea60ee497
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=41b44abdcbc5aa9a36afceee5f26fc7ea60ee497

Author: Roland Scheidegger <sroland at vmware.com>
Date:   Sun Sep 20 01:33:17 2015 +0200

mesa: fix mipmap generation for immutable, compressed textures

If the immutable compressed texture didn't have the full mip pyramid,
this didn't work, because it tried to generate mip levels for non-existing
levels. _mesa_prepare_mipmap_level() would correctly handle this by returning
FALSE if the mip level didn't exist, however we actually created the
non-existing mip level right before that because we used _mesa_get_tex_image()
before calling _mesa_prepare_mipmap_level(). It would then proceed to crash
(we allocated the mip level, which is a bad idea on an immutable texture,
but didn't initialize the values, leading to assertion failures or segfaults).
Fix this by using _mesa_select_tex_image() instead and call it after
_mesa_prepare_mipmap_level(), as that function will allocate missing mip levels
for non-immutable textures already.
This fixes a (2 year old) crash with astromenace which was hack-fixed in ubuntu
packages instead: http://bugs.debian.org/718680 (I guess most apps do full mip
chains - I believe this app not doing it is actually unintentional, always one
level less than full mip chain...).

Cc: "10.6 11.0" <mesa-stable at lists.freedesktop.org>
Reviewed-by: Brian Paul <brianp at vmware.com>
(cherry picked from commit 19604d30e1351868f7f54847c91ffec7b3fcd27e)

---

 src/mesa/main/mipmap.c |   36 +++++++++++++++---------------------
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c
index 7732d09..17aab29 100644
--- a/src/mesa/main/mipmap.c
+++ b/src/mesa/main/mipmap.c
@@ -1922,11 +1922,8 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target,
       }
 
       /* get dest gl_texture_image */
-      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
-      if (!dstImage) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
-         return;
-      }
+      dstImage = _mesa_select_tex_image(texObj, target, level + 1);
+      assert(dstImage);
 
       if (target == GL_TEXTURE_1D_ARRAY) {
 	 srcDepth = srcHeight;
@@ -2107,7 +2104,19 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
                                          srcWidth, srcHeight, srcDepth,
                                          &dstWidth, &dstHeight, &dstDepth);
       if (!nextLevel)
-	 break;
+	 goto end;
+
+      if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
+                                      dstWidth, dstHeight, dstDepth,
+                                      border, srcImage->InternalFormat,
+                                      srcImage->TexFormat)) {
+         /* all done */
+         goto end;
+      }
+
+      /* get dest gl_texture_image */
+      dstImage = _mesa_select_tex_image(texObj, target, level + 1);
+      assert(dstImage);
 
       /* Compute dst image strides and alloc memory on first iteration */
       temp_dst_row_stride = _mesa_format_row_stride(temp_format, dstWidth);
@@ -2121,13 +2130,6 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
 	 }
       }
 
-      /* get dest gl_texture_image */
-      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);
-      if (!dstImage) {
-         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
-         goto end;
-      }
-
       /* for 2D arrays, setup array[depth] of slice pointers */
       for (i = 0; i < srcDepth; i++) {
          temp_src_slices[i] = temp_src + temp_src_img_stride * i;
@@ -2146,14 +2148,6 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target,
                                   dstWidth, dstHeight, dstDepth,
                                   temp_dst_slices, temp_dst_row_stride);
 
-      if (!_mesa_prepare_mipmap_level(ctx, texObj, level + 1,
-                                      dstWidth, dstHeight, dstDepth,
-                                      border, srcImage->InternalFormat,
-                                      srcImage->TexFormat)) {
-         /* all done */
-         goto end;
-      }
-
       /* The image space was allocated above so use glTexSubImage now */
       ctx->Driver.TexSubImage(ctx, 2, dstImage,
                               0, 0, 0, dstWidth, dstHeight, dstDepth,




More information about the mesa-commit mailing list