summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brianp@vmware.com>2010-05-04 17:15:26 -0600
committerBrian Paul <brianp@vmware.com>2010-05-04 17:17:04 -0600
commit87022efb4f1e40a70d34beb30754854608a49246 (patch)
tree94b1eba7d0b954c33e1aad275dcd35520dcd7005
parent0f0c0368faf38d73b0bbbb6e0a147bc94564d3a1 (diff)
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.
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c74
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 2f41d620c8..e017fbe8c9 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];
}
}