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