Mesa (master): llvmpipe: fix broken compressed cube maps

Brian Paul brianp at kemper.freedesktop.org
Tue May 4 23:25:56 UTC 2010


Module: Mesa
Branch: master
Commit: 87022efb4f1e40a70d34beb30754854608a49246
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=87022efb4f1e40a70d34beb30754854608a49246

Author: Brian Paul <brianp at vmware.com>
Date:   Tue May  4 17:15:26 2010 -0600

llvmpipe: fix broken compressed cube maps

When the cube faces were stored in a compressed format, the img_stride
values were wrong and didn't match the per-face size computed in the
tex_image_face_size() function.  This caused bad rendering or segfaults.

---

 src/gallium/drivers/llvmpipe/lp_texture.c |   74 ++++++++++++++++++----------
 1 files changed, 47 insertions(+), 27 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 2f41d62..e017fbe 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -107,32 +107,55 @@ llvmpipe_texture_layout(struct llvmpipe_screen *screen,
    assert(LP_MAX_TEXTURE_3D_LEVELS <= LP_MAX_TEXTURE_LEVELS);
 
    for (level = 0; level <= pt->last_level; level++) {
-      const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
-      const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
-      unsigned nblocksx, num_slices;
-
-      if (lpr->base.target == PIPE_TEXTURE_CUBE)
-         num_slices = 6;
-      else if (lpr->base.target == PIPE_TEXTURE_3D)
-         num_slices = depth;
-      else
-         num_slices = 1;
-
-      /* Allocate storage for whole quads. This is particularly important
-       * for depth surfaces, which are currently stored in a swizzled format.
-       */
-      nblocksx = util_format_get_nblocksx(pt->format, align(width, TILE_SIZE));
 
-      lpr->row_stride[level] =
-         align(nblocksx * util_format_get_blocksize(pt->format), 16);
+      /* Row stride and image stride (for linear layout) */
+      {
+         unsigned alignment, nblocksx, nblocksy, block_size;
+
+         /* For non-compressed formats we need to align the texture size
+          * to the tile size to facilitate render-to-texture.
+          */
+         if (util_format_is_compressed(pt->format))
+            alignment = 1;
+         else
+            alignment = TILE_SIZE;
+
+         nblocksx = util_format_get_nblocksx(pt->format,
+                                             align(width, alignment));
+         nblocksy = util_format_get_nblocksy(pt->format,
+                                             align(height, alignment));
+         block_size = util_format_get_blocksize(pt->format);
 
-      lpr->img_stride[level] = lpr->row_stride[level] * align(height, TILE_SIZE);
+         lpr->row_stride[level] = align(nblocksx * block_size, 16);
+
+         lpr->img_stride[level] = lpr->row_stride[level] * nblocksy * block_size;
+      }
+
+      /* Size of the image in tiles (for tiled layout) */
+      {
+         const unsigned width_t = align(width, TILE_SIZE) / TILE_SIZE;
+         const unsigned height_t = align(height, TILE_SIZE) / TILE_SIZE;
+         lpr->tiles_per_row[level] = width_t;
+         lpr->tiles_per_image[level] = width_t * height_t;
+      }
 
-      lpr->tiles_per_row[level] = width_t;
-      lpr->tiles_per_image[level] = width_t * height_t;
-      lpr->num_slices_faces[level] = num_slices;
-      lpr->layout[level] = alloc_layout_array(num_slices, width, height);
+      /* Number of 3D image slices or cube faces */
+      {
+         unsigned num_slices;
 
+         if (lpr->base.target == PIPE_TEXTURE_CUBE)
+            num_slices = 6;
+         else if (lpr->base.target == PIPE_TEXTURE_3D)
+            num_slices = depth;
+         else
+            num_slices = 1;
+
+         lpr->num_slices_faces[level] = num_slices;
+
+         lpr->layout[level] = alloc_layout_array(num_slices, width, height);
+      }
+
+      /* Compute size of next mipmap level */
       width = u_minify(width, 1);
       height = u_minify(height, 1);
       depth = u_minify(depth, 1);
@@ -698,11 +721,8 @@ tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
       return buffer_size;
    }
    else {
-      const enum pipe_format format = lpr->base.format;
-      const unsigned nblocksy =
-         util_format_get_nblocksy(format, align(height, TILE_SIZE));
-      const unsigned buffer_size = nblocksy * lpr->row_stride[level];
-      return buffer_size;
+      /* we already computed this */
+      return lpr->img_stride[level];
    }
 }
 




More information about the mesa-commit mailing list