From: Lucas Stach Date: Wed, 23 Nov 2022 17:11:18 +0000 (+0100) Subject: etnaviv: optimize transfers when whole resource level is discarded X-Git-Tag: upstream/23.3.3~5611 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=6d312c616004a6063621fa6c8fe155fac9233fc9;p=platform%2Fupstream%2Fmesa.git etnaviv: optimize transfers when whole resource level is discarded Now that all our age tracking is moved to etna_resource_level we can unlock some more optimizations in the transfers by skipping copies or flushes when the whole level is discarded. Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner Part-of: --- diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c index 39e5070..2a6a4f8 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c +++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c @@ -45,6 +45,8 @@ #include "drm-uapi/drm_fourcc.h" +#define ETNA_PIPE_MAP_DISCARD_LEVEL (PIPE_MAP_DRV_PRV << 0) + /* Compute offset into a 1D/2D/3D buffer of a certain box. * This box must be aligned to the block width and height of the * underlying format. */ @@ -128,7 +130,7 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) if (ptrans->usage & PIPE_MAP_WRITE) { if (etna_resource_level_needs_flush(res_level)) { - if (ptrans->usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE) + if (ptrans->usage & ETNA_PIPE_MAP_DISCARD_LEVEL) etna_resource_level_mark_flushed(res_level); else etna_copy_resource(pctx, &rsc->base, &rsc->base, ptrans->level, ptrans->level); @@ -214,6 +216,8 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, if (!trans) return NULL; + assert(level <= prsc->last_level); + /* * Upgrade to UNSYNCHRONIZED if target is PIPE_BUFFER and range is uninitialized. */ @@ -240,14 +244,19 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, usage |= PIPE_MAP_DISCARD_WHOLE_RESOURCE; } + if ((usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE) || + ((usage & PIPE_MAP_DISCARD_RANGE) && + util_texrange_covers_whole_level(prsc, level, box->x, box->y, box->z, + box->width, box->height, box->depth))) + usage |= ETNA_PIPE_MAP_DISCARD_LEVEL; + + ptrans = &trans->base; pipe_resource_reference(&ptrans->resource, prsc); ptrans->level = level; ptrans->usage = usage; ptrans->box = *box; - assert(level <= prsc->last_level); - /* This one is a little tricky: if we have a separate render resource, which * is newer than the base resource we want the transfer to target this one, * to get the most up-to-date content, but only if we don't have a texture @@ -314,7 +323,7 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, ptrans->box.height = align(ptrans->box.height, ETNA_RS_HEIGHT_MASK + 1); } - if (!(usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE)) + if ((usage & PIPE_MAP_READ) || !(usage & ETNA_PIPE_MAP_DISCARD_LEVEL)) etna_copy_resource_box(pctx, trans->rsc, &rsc->base, level, &ptrans->box); /* Switch to using the temporary resource instead */