From 7695ea0c02166c7173437f120cbf8dceeec7fc37 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Thu, 27 Oct 2016 00:10:13 +0200 Subject: radeonsi/gfx9: add linear address computations for texture transfers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-by: Nicolai Hähnle --- src/gallium/drivers/radeon/r600_texture.c | 73 ++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 20 deletions(-) (limited to 'src/gallium') diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 0231fe2068c..c6d2381b122 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; } -- cgit v1.2.3