summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChia-I Wu <[email protected]>2013-05-15 08:51:16 +0800
committerChia-I Wu <[email protected]>2013-05-15 15:21:50 +0800
commitb6c307744f01c40cdaa128318db7229261a3186e (patch)
tree750efdd8b550163b7e3036ebe023f7b6f88853ce
parent5af8641ce0d1d725d5eb1df83c8211d2cdbe528c (diff)
ilo: refactor transfer mapping
Add tex_get_box_offset() to compute transfer offet from the pipe_box. Add tex_get_slice_stride() to compute slice stride for a transfer.
-rw-r--r--src/gallium/drivers/ilo/ilo_transfer.c79
1 files changed, 52 insertions, 27 deletions
diff --git a/src/gallium/drivers/ilo/ilo_transfer.c b/src/gallium/drivers/ilo/ilo_transfer.c
index 3d38fe88452..c4a36d7c670 100644
--- a/src/gallium/drivers/ilo/ilo_transfer.c
+++ b/src/gallium/drivers/ilo/ilo_transfer.c
@@ -150,6 +150,52 @@ choose_transfer_method(struct ilo_context *ilo, struct ilo_transfer *xfer)
return true;
}
+static unsigned
+tex_get_box_offset(const struct ilo_texture *tex, unsigned level,
+ const struct pipe_box *box)
+{
+ unsigned x, y;
+
+ x = tex->slice_offsets[level][box->z].x;
+ y = tex->slice_offsets[level][box->z].y;
+
+ x += box->x;
+ y += box->y;
+
+ /* in blocks */
+ assert(x % tex->block_width == 0 && y % tex->block_height == 0);
+ x /= tex->block_width;
+ y /= tex->block_height;
+
+ return y * tex->bo_stride + x * tex->bo_cpp;
+}
+
+static unsigned
+tex_get_slice_stride(const struct ilo_texture *tex, unsigned level)
+{
+ unsigned qpitch;
+
+ /* there is no 3D array texture */
+ assert(tex->base.array_size == 1 || tex->base.depth0 == 1);
+
+ if (tex->base.array_size == 1) {
+ /* non-array, non-3D */
+ if (tex->base.depth0 == 1)
+ return 0;
+
+ /* only the first level has a fixed slice stride */
+ if (level > 0) {
+ assert(!"no slice stride for 3D texture with level > 0");
+ return 0;
+ }
+ }
+
+ qpitch = tex->slice_offsets[level][1].y - tex->slice_offsets[level][0].y;
+ assert(qpitch % tex->block_height == 0);
+
+ return (qpitch / tex->block_height) * tex->bo_stride;
+}
+
static void
tex_staging_sys_convert_write(enum pipe_format dst_fmt,
const struct pipe_transfer *dst_xfer,
@@ -271,7 +317,7 @@ tex_direct_map(struct ilo_context *ilo,
struct ilo_texture *tex,
struct ilo_transfer *xfer)
{
- int err, x, y;
+ int err;
if (xfer->base.usage & PIPE_TRANSFER_UNSYNCHRONIZED)
err = tex->bo->map_unsynchronized(tex->bo);
@@ -288,35 +334,14 @@ tex_direct_map(struct ilo_context *ilo,
/* note that stride is for a block row, not a texel row */
xfer->base.stride = tex->bo_stride;
- /*
- * we can walk through layers when the resource is a texture array or
- * when this is the first level of a 3D texture being mapped
- */
- if (tex->base.array_size > 1 ||
- (tex->base.target == PIPE_TEXTURE_3D && xfer->base.level == 0)) {
- const unsigned qpitch = tex->slice_offsets[xfer->base.level][1].y -
- tex->slice_offsets[xfer->base.level][0].y;
-
- assert(qpitch % tex->block_height == 0);
- xfer->base.layer_stride = (qpitch / tex->block_height) * xfer->base.stride;
- }
- else {
+ /* slice stride is not always available */
+ if (xfer->base.box.depth > 1)
+ xfer->base.layer_stride = tex_get_slice_stride(tex, xfer->base.level);
+ else
xfer->base.layer_stride = 0;
- }
-
- x = tex->slice_offsets[xfer->base.level][xfer->base.box.z].x;
- y = tex->slice_offsets[xfer->base.level][xfer->base.box.z].y;
-
- x += xfer->base.box.x;
- y += xfer->base.box.y;
-
- /* in blocks */
- assert(x % tex->block_width == 0 && y % tex->block_height == 0);
- x /= tex->block_width;
- y /= tex->block_height;
xfer->ptr = tex->bo->get_virtual(tex->bo);
- xfer->ptr += y * tex->bo_stride + x * tex->bo_cpp;
+ xfer->ptr += tex_get_box_offset(tex, xfer->base.level, &xfer->base.box);
return true;
}