From 3508f2fb185042aae31555321c9eff0ec47a9369 Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Wed, 24 Jul 2019 10:30:08 -0400 Subject: [PATCH] etnaviv: fix 3d texture upload Fix uploading of 3D textures and 2D array textures: * Remove asserts in BLT and RS checking z * Use box->z/box->depth in etna_copy_resource_box and CPU tile/untile * Track mip level depth and use it in etna_copy_resource Signed-off-by: Jonathan Marek Reviewed-by: Christian Gmeiner --- src/gallium/drivers/etnaviv/etnaviv_blt.c | 6 ----- .../drivers/etnaviv/etnaviv_clear_blit.c | 13 ++++++--- .../drivers/etnaviv/etnaviv_resource.c | 2 ++ .../drivers/etnaviv/etnaviv_resource.h | 1 + src/gallium/drivers/etnaviv/etnaviv_rs.c | 9 ------- .../drivers/etnaviv/etnaviv_transfer.c | 27 +++++++++++-------- 6 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.c b/src/gallium/drivers/etnaviv/etnaviv_blt.c index 471ed90d3ee..f3067a7ac2d 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blt.c +++ b/src/gallium/drivers/etnaviv/etnaviv_blt.c @@ -403,12 +403,6 @@ etna_try_blt_blit(struct pipe_context *pctx, return false; } - /* Ensure that the Z coordinate is sane */ - assert(dst->base.target == PIPE_TEXTURE_CUBE || blit_info->dst.box.z == 0); - assert(src->base.target == PIPE_TEXTURE_CUBE || blit_info->src.box.z == 0); - assert(blit_info->src.box.z < src->base.array_size); - assert(blit_info->dst.box.z < dst->base.array_size); - struct etna_resource_level *src_lev = &src->levels[blit_info->src.level]; struct etna_resource_level *dst_lev = &dst->levels[blit_info->dst.level]; diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c index 45c30cbf507..df12e609ac9 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c @@ -179,9 +179,14 @@ etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst, MIN2(src_priv->levels[level].padded_width, dst_priv->levels[level].padded_width); blit.src.box.height = blit.dst.box.height = MIN2(src_priv->levels[level].padded_height, dst_priv->levels[level].padded_height); + unsigned depth = MIN2(src_priv->levels[level].depth, dst_priv->levels[level].depth); + if (dst->array_size > 1) { + assert(depth == 1); /* no array of 3d texture */ + depth = dst->array_size; + } - for (int layer = 0; layer < dst->array_size; layer++) { - blit.src.box.z = blit.dst.box.z = layer; + for (int z = 0; z < depth; z++) { + blit.src.box.z = blit.dst.box.z = z; pctx->blit(pctx, &blit); } } @@ -208,8 +213,8 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst, blit.dst.box.depth = blit.src.box.depth = 1; blit.src.level = blit.dst.level = level; - for (int layer = 0; layer < dst->array_size; layer++) { - blit.src.box.z = blit.dst.box.z = layer; + for (int z = 0; z < box->depth; z++) { + blit.src.box.z = blit.dst.box.z = box->z + z; pctx->blit(pctx, &blit); } } diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index 48fad858fc2..34d4d2449a9 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -173,6 +173,7 @@ setup_miptree(struct etna_resource *rsc, unsigned paddingX, unsigned paddingY, mip->width = width; mip->height = height; + mip->depth = depth; mip->padded_width = align(width * msaa_xscale, paddingX); mip->padded_height = align(height * msaa_yscale, paddingY); mip->stride = util_format_get_stride(prsc->format, mip->padded_width); @@ -554,6 +555,7 @@ etna_resource_from_handle(struct pipe_screen *pscreen, level->width = tmpl->width0; level->height = tmpl->height0; + level->depth = tmpl->depth0; /* Determine padding of the imported resource. */ unsigned paddingX = 0, paddingY = 0; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h index e86639b7f4d..90e04f5159b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.h +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h @@ -41,6 +41,7 @@ struct util_dynarray; struct etna_resource_level { unsigned width, padded_width; /* in pixels */ unsigned height, padded_height; /* in samples */ + unsigned depth; unsigned offset; /* offset into memory area */ uint32_t stride; /* row stride */ uint32_t layer_stride; /* layer stride */ diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c index 013563185b5..0979607cdc2 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c @@ -598,15 +598,6 @@ etna_try_rs_blit(struct pipe_context *pctx, if ((blit_info->dst.box.x & w_mask) || (blit_info->dst.box.y & h_mask)) return false; - /* Ensure that the Z coordinate is sane */ - if (dst->base.target != PIPE_TEXTURE_CUBE) - assert(blit_info->dst.box.z == 0); - if (src->base.target != PIPE_TEXTURE_CUBE) - assert(blit_info->src.box.z == 0); - - assert(blit_info->src.box.z < src->base.array_size); - assert(blit_info->dst.box.z < dst->base.array_size); - struct etna_resource_level *src_lev = &src->levels[blit_info->src.level]; struct etna_resource_level *dst_lev = &dst->levels[blit_info->dst.level]; diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c index 78face1ee90..de2d6ed9ba2 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c +++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c @@ -134,11 +134,14 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) struct etna_resource_level *res_level = &rsc->levels[ptrans->level]; if (rsc->layout == ETNA_LAYOUT_TILED) { - etna_texture_tile( - trans->mapped + ptrans->box.z * res_level->layer_stride, - trans->staging, ptrans->box.x, ptrans->box.y, - res_level->stride, ptrans->box.width, ptrans->box.height, - ptrans->stride, util_format_get_blocksize(rsc->base.format)); + for (unsigned z = 0; z < ptrans->box.depth; z++) { + etna_texture_tile( + trans->mapped + (ptrans->box.z + z) * res_level->layer_stride, + trans->staging + z * ptrans->layer_stride, + ptrans->box.x, ptrans->box.y, + res_level->stride, ptrans->box.width, ptrans->box.height, + ptrans->stride, util_format_get_blocksize(rsc->base.format)); + } } else if (rsc->layout == ETNA_LAYOUT_LINEAR) { util_copy_box(trans->mapped, rsc->base.format, res_level->stride, res_level->layer_stride, ptrans->box.x, @@ -240,7 +243,7 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, return NULL; } - if (prsc->depth0 > 1) { + if (prsc->depth0 > 1 && rsc->ts_bo) { slab_free(&ctx->transfer_pool, trans); BUG("resource has depth >1 with tile status"); return NULL; @@ -427,11 +430,13 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, if (usage & PIPE_TRANSFER_READ) { if (rsc->layout == ETNA_LAYOUT_TILED) { - etna_texture_untile(trans->staging, - trans->mapped + ptrans->box.z * res_level->layer_stride, - ptrans->box.x, ptrans->box.y, res_level->stride, - ptrans->box.width, ptrans->box.height, ptrans->stride, - util_format_get_blocksize(rsc->base.format)); + for (unsigned z = 0; z < ptrans->box.depth; z++) { + etna_texture_untile(trans->staging + z * ptrans->layer_stride, + trans->mapped + (ptrans->box.z + z) * res_level->layer_stride, + ptrans->box.x, ptrans->box.y, res_level->stride, + ptrans->box.width, ptrans->box.height, ptrans->stride, + util_format_get_blocksize(rsc->base.format)); + } } else if (rsc->layout == ETNA_LAYOUT_LINEAR) { util_copy_box(trans->staging, rsc->base.format, ptrans->stride, ptrans->layer_stride, 0, 0, 0, /* dst x,y,z */ -- 2.30.2