[Mesa-dev,128/140] radeonsi/gfx9: add linear address computations for texture transfers

Submitted by Marek Olšák on March 20, 2017, 10:49 p.m.

Details

Message ID 1490050166-6119-37-git-send-email-maraeo@gmail.com
State Accepted
Commit 7695ea0c02166c7173437f120cbf8dceeec7fc37
Headers show
Series "RadeonSI: Initial Vega10 support" ( rev: 30 ) in Mesa

Not browsing as part of any series.

Commit Message

Marek Olšák March 20, 2017, 10:49 p.m.
From: Marek Olšák <marek.olsak@amd.com>

---
 src/gallium/drivers/radeon/r600_texture.c | 73 ++++++++++++++++++++++---------
 1 file changed, 53 insertions(+), 20 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 0231fe2..c6d2381 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -177,14 +177,42 @@  static void r600_copy_from_staging_texture(struct pipe_context *ctx, struct r600
 		       src, 0, &sbox);
 }
 
-static unsigned r600_texture_get_offset(struct r600_texture *rtex, unsigned level,
-					const struct pipe_box *box)
+static unsigned r600_texture_get_offset(struct r600_common_screen *rscreen,
+					struct r600_texture *rtex, unsigned level,
+					const struct pipe_box *box,
+					unsigned *stride,
+					unsigned *layer_stride)
 {
-	return rtex->surface.u.legacy.level[level].offset +
-	       box->z * rtex->surface.u.legacy.level[level].slice_size +
-	       (box->y / rtex->surface.blk_h *
-		rtex->surface.u.legacy.level[level].nblk_x +
-		box->x / rtex->surface.blk_w) * rtex->surface.bpe;
+	if (rscreen->chip_class >= GFX9) {
+		*stride = rtex->surface.u.gfx9.surf_pitch * rtex->surface.bpe;
+		*layer_stride = rtex->surface.u.gfx9.surf_slice_size;
+
+		if (!box)
+			return 0;
+
+		/* Each texture is an array of slices. Each slice is an array
+		 * of mipmap levels. */
+		return box->z * rtex->surface.u.gfx9.surf_slice_size +
+		       ((rtex->surface.u.gfx9.surf_ymip_offset[level] +
+			 box->y / rtex->surface.blk_h) *
+			rtex->surface.u.gfx9.surf_pitch +
+			box->x / rtex->surface.blk_w) * rtex->surface.bpe;
+	} else {
+		*stride = rtex->surface.u.legacy.level[level].nblk_x *
+			  rtex->surface.bpe;
+		*layer_stride = rtex->surface.u.legacy.level[level].slice_size;
+
+		if (!box)
+			return rtex->surface.u.legacy.level[level].offset;
+
+		/* Each texture is an array of mipmap levels. Each level is
+		 * an array of slices. */
+		return rtex->surface.u.legacy.level[level].offset +
+		       box->z * rtex->surface.u.legacy.level[level].slice_size +
+		       (box->y / rtex->surface.blk_h *
+		        rtex->surface.u.legacy.level[level].nblk_x +
+		        box->x / rtex->surface.blk_w) * rtex->surface.bpe;
+	}
 }
 
 static int r600_init_surface(struct r600_common_screen *rscreen,
@@ -1662,8 +1690,12 @@  static void *r600_texture_transfer_map(struct pipe_context *ctx,
 							    0, 0, 0, box->depth, 0, 0);
 				pipe_resource_reference(&temp, NULL);
 			}
-		}
-		else {
+
+			/* Just get the strides. */
+			r600_texture_get_offset(rctx->screen, staging_depth, level, NULL,
+						&trans->transfer.stride,
+						&trans->transfer.layer_stride);
+		} else {
 			/* XXX: only readback the rectangle which is being mapped? */
 			/* XXX: when discard is true, no need to read back from depth texture */
 			if (!r600_init_flushed_depth_texture(ctx, texture, &staging_depth)) {
@@ -1677,12 +1709,12 @@  static void *r600_texture_transfer_map(struct pipe_context *ctx,
 						    box->z, box->z + box->depth - 1,
 						    0, 0);
 
-			offset = r600_texture_get_offset(staging_depth, level, box);
+			offset = r600_texture_get_offset(rctx->screen, staging_depth,
+							 level, box,
+							 &trans->transfer.stride,
+							 &trans->transfer.layer_stride);
 		}
 
-		trans->transfer.stride = staging_depth->surface.u.legacy.level[level].nblk_x *
-					 staging_depth->surface.bpe;
-		trans->transfer.layer_stride = staging_depth->surface.u.legacy.level[level].slice_size;
 		trans->staging = (struct r600_resource*)staging_depth;
 		buf = trans->staging;
 	} else if (use_staging_texture) {
@@ -1702,9 +1734,11 @@  static void *r600_texture_transfer_map(struct pipe_context *ctx,
 			return NULL;
 		}
 		trans->staging = &staging->resource;
-		trans->transfer.stride = staging->surface.u.legacy.level[0].nblk_x *
-					 staging->surface.bpe;
-		trans->transfer.layer_stride = staging->surface.u.legacy.level[0].slice_size;
+
+		/* Just get the strides. */
+		r600_texture_get_offset(rctx->screen, staging, 0, NULL,
+					&trans->transfer.stride,
+					&trans->transfer.layer_stride);
 
 		if (usage & PIPE_TRANSFER_READ)
 			r600_copy_to_staging_texture(ctx, trans);
@@ -1714,10 +1748,9 @@  static void *r600_texture_transfer_map(struct pipe_context *ctx,
 		buf = trans->staging;
 	} else {
 		/* the resource is mapped directly */
-		trans->transfer.stride = rtex->surface.u.legacy.level[level].nblk_x *
-					 rtex->surface.bpe;
-		trans->transfer.layer_stride = rtex->surface.u.legacy.level[level].slice_size;
-		offset = r600_texture_get_offset(rtex, level, box);
+		offset = r600_texture_get_offset(rctx->screen, rtex, level, box,
+						 &trans->transfer.stride,
+						 &trans->transfer.layer_stride);
 		buf = &rtex->resource;
 	}