summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/llvmpipe
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2010-04-20 17:14:47 -0600
committerBrian Paul <[email protected]>2010-04-20 17:15:33 -0600
commit7688a4749e9266fe6c5f86b62e19d3a0975c3f57 (patch)
tree509893ea413647c8da47ce668df5f3cc71bf576c /src/gallium/drivers/llvmpipe
parentc668a97ad5779ff7e0077524529e812141b03fa7 (diff)
llvmpipe: fix cube face addressing bug
Fixes fd.o bug 27760 (pigit fbo-cubemap).
Diffstat (limited to 'src/gallium/drivers/llvmpipe')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c80
1 files changed, 60 insertions, 20 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
index c8cf5820c7d..cd1dddcd39a 100644
--- a/src/gallium/drivers/llvmpipe/lp_texture.c
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -1008,10 +1008,51 @@ llvmpipe_get_texture_image_all(struct llvmpipe_resource *lpr,
}
+/**
+ * Return pointer to start of linear data for a particular 2D texture
+ * image/face/slice.
+ */
+static uint8_t *
+get_linear_image_address(struct llvmpipe_resource *lpr,
+ unsigned face_slice, unsigned level)
+{
+ struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
+
+ if (face_slice > 0) {
+ unsigned linear_offset =
+ face_slice * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
+ return (uint8_t *) linear_img->data + linear_offset;
+ }
+ else {
+ return (uint8_t *) linear_img->data;
+ }
+}
+
/**
- * Get pointer to a linear image where the tile at (x,y) is known to be
- * in linear layout.
+ * Return pointer to start of tiled data for a particular 2D texture
+ * image/face/slice.
+ */
+static uint8_t *
+get_tiled_image_address(struct llvmpipe_resource *lpr,
+ unsigned face_slice, unsigned level)
+{
+ struct llvmpipe_texture_image *tiled_img = &lpr->tiled[level];
+
+ if (face_slice > 0) {
+ unsigned tiled_offset =
+ face_slice * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_TILED);
+ return (uint8_t *) tiled_img->data + tiled_offset;
+ }
+ else {
+ return (uint8_t *) tiled_img->data;
+ }
+}
+
+
+/**
+ * Get pointer to a linear image (not the tile!) where the tile at (x,y)
+ * is known to be in linear layout.
* Conversion from tiled to linear will be done if necessary.
* \return pointer to start of image/face (not the tile)
*/
@@ -1021,11 +1062,11 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
enum lp_texture_usage usage,
unsigned x, unsigned y)
{
- struct llvmpipe_texture_image *tiled_img = &lpr->tiled[level];
struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
enum lp_texture_layout cur_layout, new_layout;
const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
boolean convert;
+ uint8_t *tiled_image, *linear_image;
assert(resource_is_texture(&lpr->base));
assert(x % TILE_SIZE == 0);
@@ -1037,13 +1078,18 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
linear_img->data = align_malloc(buffer_size, 16);
}
+ /* compute address of the slice/face of the image that contains the tile */
+ tiled_image = get_tiled_image_address(lpr, face_slice, level);
+ linear_image = get_linear_image_address(lpr, face_slice, level);
+
+
cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
layout_logic(cur_layout, LP_TEX_LAYOUT_LINEAR, usage,
&new_layout, &convert);
if (convert) {
- lp_tiled_to_linear(tiled_img->data, linear_img->data,
+ lp_tiled_to_linear(tiled_image, linear_image,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
lpr->row_stride[level]);
}
@@ -1051,14 +1097,7 @@ llvmpipe_get_texture_tile_linear(struct llvmpipe_resource *lpr,
if (new_layout != cur_layout)
llvmpipe_set_texture_tile_layout(lpr, face_slice, level, tx, ty, new_layout);
- if (face_slice > 0) {
- unsigned offset
- = face_slice * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_LINEAR);
- return (ubyte *) linear_img->data + offset;
- }
- else {
- return linear_img->data;
- }
+ return linear_image;
}
@@ -1074,10 +1113,10 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
{
const unsigned width = u_minify(lpr->base.width0, level);
struct llvmpipe_texture_image *tiled_img = &lpr->tiled[level];
- struct llvmpipe_texture_image *linear_img = &lpr->linear[level];
enum lp_texture_layout cur_layout, new_layout;
const unsigned tx = x / TILE_SIZE, ty = y / TILE_SIZE;
boolean convert;
+ uint8_t *tiled_image, *linear_image;
assert(x % TILE_SIZE == 0);
assert(y % TILE_SIZE == 0);
@@ -1088,11 +1127,16 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
tiled_img->data = align_malloc(buffer_size, 16);
}
+ /* compute address of the slice/face of the image that contains the tile */
+ tiled_image = get_tiled_image_address(lpr, face_slice, level);
+ linear_image = get_linear_image_address(lpr, face_slice, level);
+
+ /* get current tile layout and see if we need to convert the data */
cur_layout = llvmpipe_get_texture_tile_layout(lpr, face_slice, level, tx, ty);
layout_logic(cur_layout, LP_TEX_LAYOUT_TILED, usage, &new_layout, &convert);
if (convert) {
- lp_linear_to_tiled(linear_img->data, tiled_img->data,
+ lp_linear_to_tiled(linear_image, tiled_image,
x, y, TILE_SIZE, TILE_SIZE, lpr->base.format,
lpr->row_stride[level]);
}
@@ -1102,7 +1146,7 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
/* compute, return address of the 64x64 tile */
{
- unsigned tiles_per_row, tile_offset, face_slice_offset;
+ unsigned tiles_per_row, tile_offset;
tiles_per_row = align(width, TILE_SIZE) / TILE_SIZE;
@@ -1113,11 +1157,7 @@ llvmpipe_get_texture_tile(struct llvmpipe_resource *lpr,
assert(tiled_img->data);
- face_slice_offset = (face_slice > 0)
- ? (face_slice * tex_image_face_size(lpr, level, LP_TEX_LAYOUT_TILED))
- : 0;
-
- return (ubyte *) tiled_img->data + face_slice_offset + tile_offset;
+ return (ubyte *) tiled_image + tile_offset;
}
}