Mesa (master): llvmpipe: fix surface memory allocation bug

Brian Paul brianp at kemper.freedesktop.org
Mon Apr 19 17:20:14 UTC 2010


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

Author: Brian Paul <brianp at vmware.com>
Date:   Mon Apr 19 11:17:11 2010 -0600

llvmpipe: fix surface memory allocation bug

We weren't always allocating the right amount of memory for image tiles
for some formats (those < 32bpp).

Fixes fd.o bug 27712.

---

 src/gallium/drivers/llvmpipe/lp_texture.c |   48 +++++++++++++++++++++-------
 1 files changed, 36 insertions(+), 12 deletions(-)

diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index 2267fcb..f719ca4 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -665,17 +665,35 @@ static unsigned
 tex_image_face_size(const struct llvmpipe_resource *lpr, unsigned level,
                     enum lp_texture_layout layout)
 {
-   /* for tiled layout, force a 32bpp format */
-   enum pipe_format format = layout == LP_TEX_LAYOUT_TILED
-      ? PIPE_FORMAT_B8G8R8A8_UNORM : lpr->base.format;
+   const unsigned width = u_minify(lpr->base.width0, level);
    const unsigned height = u_minify(lpr->base.height0, level);
    const unsigned depth = u_minify(lpr->base.depth0, level);
-   const unsigned nblocksy =
-      util_format_get_nblocksy(format, align(height, TILE_SIZE));
-   const unsigned buffer_size =
-      nblocksy * lpr->stride[level] *
-      (lpr->base.target == PIPE_TEXTURE_3D ? depth : 1);
-   return buffer_size;
+
+   assert(layout == LP_TEX_LAYOUT_TILED ||
+          layout == LP_TEX_LAYOUT_LINEAR);
+
+   if (layout == LP_TEX_LAYOUT_TILED) {
+      /* for tiled layout, force a 32bpp format */
+      const enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM;
+      const unsigned block_size = util_format_get_blocksize(format);
+      const unsigned nblocksy =
+         util_format_get_nblocksy(format, align(height, TILE_SIZE));
+      const unsigned nblocksx =
+         util_format_get_nblocksx(format, align(width, TILE_SIZE));
+      const unsigned buffer_size =
+         block_size * nblocksy * nblocksx *
+         (lpr->base.target == PIPE_TEXTURE_3D ? depth : 1);
+      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->stride[level] *
+         (lpr->base.target == PIPE_TEXTURE_3D ? depth : 1);
+      return buffer_size;
+   }
 }
 
 
@@ -784,7 +802,7 @@ llvmpipe_get_texture_image_address(struct llvmpipe_resource *lpr,
 /**
  * Return pointer to texture image data (either linear or tiled layout).
  * \param usage  one of LP_TEX_USAGE_READ/WRITE_ALL/READ_WRITE
- * \param layout  either LP_TEX_LAYOUT_LINEAR or LP_TEX_LAYOUT_TILED
+ * \param layout  either LP_TEX_LAYOUT_LINEAR or _TILED or _NONE
  */
 void *
 llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
@@ -837,7 +855,11 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
 
    if (!target_data) {
       /* allocate memory for the target image now */
-      unsigned buffer_size = tex_image_size(lpr, level, layout);
+      unsigned buffer_size;
+      if (layout == LP_TEX_LAYOUT_LINEAR)
+         buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
+      else
+         buffer_size = tex_image_size(lpr, level, LP_TEX_LAYOUT_TILED);
       target_img->data = align_malloc(buffer_size, 16);
       target_data = target_img->data;
    }
@@ -853,7 +875,9 @@ llvmpipe_get_texture_image(struct llvmpipe_resource *lpr,
    }
 
    if (layout == LP_TEX_LAYOUT_NONE) {
-      /* just allocating memory */
+      /* Just allocating tiled memory.  Don't initialize it from the the
+       * linear data if it exists.
+       */
       return target_data;
    }
 




More information about the mesa-commit mailing list