Module: Mesa
Branch: main
Commit: 6d312c616004a6063621fa6c8fe155fac9233fc9
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=6d312c616004a6063621fa6c8fe155fac9233fc9

Author: Lucas Stach <[email protected]>
Date:   Wed Nov 23 18:11:18 2022 +0100

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 <[email protected]>
Reviewed-by: Christian Gmeiner <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19964>

---

 src/gallium/drivers/etnaviv/etnaviv_transfer.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c 
b/src/gallium/drivers/etnaviv/etnaviv_transfer.c
index 39e5070ffd5..2a6a4f8b5e7 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 */

Reply via email to