etnaviv: move resource seqnos to level
authorLucas Stach <l.stach@pengutronix.de>
Thu, 17 Nov 2022 17:57:42 +0000 (18:57 +0100)
committerMarge Bot <emma+marge@anholt.net>
Fri, 14 Jul 2023 14:21:35 +0000 (14:21 +0000)
Resource maps, blits and surfaces all target a specific level of a
resource, so they can have different ages. Move the seqnos tracking
the age to etna_resource_level.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19964>

src/gallium/drivers/etnaviv/etnaviv_blt.c
src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
src/gallium/drivers/etnaviv/etnaviv_context.c
src/gallium/drivers/etnaviv/etnaviv_resource.c
src/gallium/drivers/etnaviv/etnaviv_resource.h
src/gallium/drivers/etnaviv/etnaviv_rs.c
src/gallium/drivers/etnaviv/etnaviv_state.c
src/gallium/drivers/etnaviv/etnaviv_texture.c
src/gallium/drivers/etnaviv/etnaviv_transfer.c

index 59c8d91..6c1128b 100644 (file)
@@ -270,7 +270,7 @@ etna_blit_clear_color_blt(struct pipe_context *pctx, struct pipe_surface *dst,
 
    surf->level->clear_value = new_clear_value;
    resource_written(ctx, surf->base.texture);
-   etna_resource(surf->base.texture)->seqno++;
+   surf->level->seqno++;
 }
 
 static void
@@ -351,7 +351,7 @@ etna_blit_clear_zs_blt(struct pipe_context *pctx, struct pipe_surface *dst,
    }
 
    resource_written(ctx, surf->base.texture);
-   etna_resource(surf->base.texture)->seqno++;
+   surf->level->seqno++;
 }
 
 static void
@@ -573,7 +573,7 @@ etna_try_blt_blit(struct pipe_context *pctx,
    resource_read(ctx, &src->base);
    resource_written(ctx, &dst->base);
 
-   dst->seqno++;
+   dst_lev->seqno++;
    dst_lev->ts_valid = false;
 
    return true;
index 4ce4eeb..4422571 100644 (file)
@@ -188,13 +188,10 @@ etna_flush_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
    struct etna_resource *rsc = etna_resource(prsc);
 
    if (rsc->render) {
-      if (etna_resource_older(rsc, etna_resource(rsc->render))) {
+      if (etna_resource_older(rsc, etna_resource(rsc->render)))
          etna_copy_resource(pctx, prsc, rsc->render, 0, 0);
-         rsc->seqno = etna_resource(rsc->render)->seqno;
-      }
    } else if (!etna_resource_ext_ts(rsc) && etna_resource_needs_flush(rsc)) {
       etna_copy_resource(pctx, prsc, prsc, 0, 0);
-      rsc->flush_seqno = rsc->seqno;
    }
 }
 
@@ -235,6 +232,11 @@ etna_copy_resource(struct pipe_context *pctx, struct pipe_resource *dst,
          blit.src.box.z = blit.dst.box.z = z;
          pctx->blit(pctx, &blit);
       }
+
+      if (src == dst)
+         dst_priv->levels[level].flush_seqno = src_priv->levels[level].seqno;
+      else
+         dst_priv->levels[level].seqno = src_priv->levels[level].seqno;
    }
 }
 
@@ -243,9 +245,12 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst,
                        struct pipe_resource *src, int level,
                        struct pipe_box *box)
 {
+   struct etna_resource *src_priv = etna_resource(src);
+   struct etna_resource *dst_priv = etna_resource(dst);
+
    assert(src->format == dst->format);
    assert(src->array_size == dst->array_size);
-   assert(!etna_resource_needs_flush(etna_resource(dst)));
+   assert(!etna_resource_level_needs_flush(&dst_priv->levels[level]));
 
    struct pipe_blit_info blit = {};
    blit.mask = util_format_get_mask(dst->format);
@@ -264,6 +269,11 @@ etna_copy_resource_box(struct pipe_context *pctx, struct pipe_resource *dst,
       blit.src.box.z = blit.dst.box.z = box->z + z;
       pctx->blit(pctx, &blit);
    }
+
+   if (src == dst)
+      dst_priv->levels[level].flush_seqno = src_priv->levels[level].seqno;
+   else
+      dst_priv->levels[level].seqno = src_priv->levels[level].seqno;
 }
 
 void
index de951d0..feb6d7c 100644 (file)
@@ -419,9 +419,9 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info,
       pctx->flush(pctx, NULL, 0);
 
    if (ctx->framebuffer_s.cbufs[0])
-      etna_resource(ctx->framebuffer_s.cbufs[0]->texture)->seqno++;
+      etna_surface(ctx->framebuffer_s.cbufs[0])->level->seqno++;
    if (ctx->framebuffer_s.zsbuf)
-      etna_resource(ctx->framebuffer_s.zsbuf->texture)->seqno++;
+      etna_surface(ctx->framebuffer_s.zsbuf)->level->seqno++;
    if (info->index_size && indexbuf != info->index.resource)
       pipe_resource_reference(&indexbuf, NULL);
 }
index c7dbb8e..8e1d5fb 100644 (file)
@@ -567,7 +567,10 @@ etna_resource_create_modifiers(struct pipe_screen *pscreen,
 static void
 etna_resource_changed(struct pipe_screen *pscreen, struct pipe_resource *prsc)
 {
-   etna_resource(prsc)->seqno++;
+   struct etna_resource *rsc = etna_resource(prsc);
+
+   for (int level = 0; level <= prsc->last_level; level++)
+      rsc->levels[level].seqno++;
 }
 
 static void
@@ -671,7 +674,6 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
    if (modifier == DRM_FORMAT_MOD_INVALID)
       modifier = DRM_FORMAT_MOD_LINEAR;
 
-   rsc->seqno = 1;
    rsc->layout = modifier_to_layout(modifier);
    rsc->modifier = modifier;
 
@@ -683,6 +685,7 @@ etna_resource_from_handle(struct pipe_screen *pscreen,
    level->depth = tmpl->depth0;
    level->stride = handle->stride;
    level->offset = handle->offset;
+   level->seqno = 1;
 
    /* Determine padding of the imported resource. */
    unsigned paddingX, paddingY;
@@ -894,13 +897,13 @@ etna_resource_status(struct etna_context *ctx, struct etna_resource *res)
 }
 
 bool
-etna_resource_has_valid_ts(struct etna_resource *rsc)
+etna_resource_needs_flush(struct etna_resource *rsc)
 {
    if (!rsc->ts_bo)
       return false;
 
    for (int level = 0; level <= rsc->base.last_level; level++)
-      if (rsc->levels[level].ts_valid)
+      if (etna_resource_level_needs_flush(&rsc->levels[level]))
          return true;
 
    return false;
index 7d692c1..6bce94e 100644 (file)
@@ -73,8 +73,34 @@ struct etna_resource_level {
    /* keep track if we have done some per block patching */
    bool patched;
    struct util_dynarray *patch_offsets;
+
+   uint32_t seqno;
+   uint32_t flush_seqno;
 };
 
+/* returns TRUE if a is newer than b */
+static inline bool
+etna_resource_level_newer(struct etna_resource_level *a,
+                          struct etna_resource_level *b)
+{
+   return (int)(a->seqno - b->seqno) > 0;
+}
+
+/* returns TRUE if a is older than b */
+static inline bool
+etna_resource_level_older(struct etna_resource_level *a,
+                          struct etna_resource_level *b)
+{
+   return (int)(a->seqno - b->seqno) < 0;
+}
+
+/* returns TRUE if a is older than b */
+static inline bool
+etna_resource_level_needs_flush(struct etna_resource_level *lvl)
+{
+   return lvl->ts_valid && ((int)(lvl->seqno - lvl->flush_seqno) > 0);
+}
+
 /* status of queued up but not flushed reads and write operations.
  * In _transfer_map() we need to know if queued up rendering needs
  * to be flushed to preserve the order of cpu and gpu access. */
@@ -86,8 +112,6 @@ enum etna_resource_status {
 struct etna_resource {
    struct pipe_resource base;
    struct renderonly_scanout *scanout;
-   uint32_t seqno;
-   uint32_t flush_seqno;
 
    /* only lod 0 used for non-texture buffers */
    /* Layout for surface (tiled, multitiled, split tiled, ...) */
@@ -117,27 +141,31 @@ struct etna_resource {
 static inline bool
 etna_resource_newer(struct etna_resource *a, struct etna_resource *b)
 {
-   return (int)(a->seqno - b->seqno) > 0;
+   assert(a->base.last_level == b->base.last_level);
+
+   for (int level = 0; level <= a->base.last_level; level++)
+      if (etna_resource_level_newer(&a->levels[level], &b->levels[level]))
+         return true;
+
+   return false;
 }
 
 /* returns TRUE if a is older than b */
 static inline bool
 etna_resource_older(struct etna_resource *a, struct etna_resource *b)
 {
-   return (int)(a->seqno - b->seqno) < 0;
-}
+   assert(a->base.last_level == b->base.last_level);
 
-/* returns TRUE if a resource has a TS, and it is valid for at least one level */
-bool
-etna_resource_has_valid_ts(struct etna_resource *res);
+   for (int level = 0; level <= a->base.last_level; level++)
+      if (etna_resource_level_older(&a->levels[level], &b->levels[level]))
+         return true;
 
-/* returns TRUE if the resource needs a resolve to itself */
-static inline bool
-etna_resource_needs_flush(struct etna_resource *res)
-{
-   return etna_resource_has_valid_ts(res) && ((int)(res->seqno - res->flush_seqno) > 0);
+   return false;
 }
 
+/* returns TRUE if the resource needs a resolve to itself */
+bool etna_resource_needs_flush(struct etna_resource *res);
+
 /* is the resource only used on the sampler? */
 static inline bool
 etna_resource_sampler_only(const struct pipe_resource *pres)
index a22ec04..f8abf14 100644 (file)
@@ -359,7 +359,7 @@ etna_blit_clear_color_rs(struct pipe_context *pctx, struct pipe_surface *dst,
 
    surf->level->clear_value = new_clear_value;
    resource_written(ctx, surf->base.texture);
-   etna_resource(surf->base.texture)->seqno++;
+   surf->level->seqno++;
 }
 
 static void
@@ -422,7 +422,7 @@ etna_blit_clear_zs_rs(struct pipe_context *pctx, struct pipe_surface *dst,
 
    surf->level->clear_value = new_clear_value;
    resource_written(ctx, surf->base.texture);
-   etna_resource(surf->base.texture)->seqno++;
+   surf->level->seqno++;
 }
 
 static void
@@ -801,7 +801,7 @@ etna_try_rs_blit(struct pipe_context *pctx,
    etna_submit_rs_state(ctx, &copy_to_screen);
    resource_read(ctx, &src->base);
    resource_written(ctx, &dst->base);
-   dst->seqno++;
+   dst_lev->seqno++;
    dst_lev->ts_valid = false;
    ctx->dirty |= ETNA_DIRTY_DERIVE_TS;
 
index 0b49afd..8cc09fb 100644 (file)
@@ -120,10 +120,8 @@ etna_update_render_resource(struct pipe_context *pctx, struct etna_resource *bas
    if (base->render)
       to = etna_resource(base->render);
 
-   if ((to != from) && etna_resource_older(to, from)) {
+   if ((to != from) && etna_resource_older(to, from))
       etna_copy_resource(pctx, &to->base, &from->base, 0, base->base.last_level);
-      to->seqno = from->seqno;
-   }
 }
 
 static void
index c629bda..9108803 100644 (file)
@@ -174,17 +174,14 @@ etna_update_sampler_source(struct pipe_sampler_view *view, int num)
    if ((to != from) && etna_resource_older(to, from)) {
       etna_copy_resource(view->context, &to->base, &from->base, 0,
                          view->texture->last_level);
-      to->seqno = from->seqno;
       ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
    } else if ((to == from) && etna_resource_needs_flush(to)) {
       if (etna_can_use_sampler_ts(view, num)) {
          enable_sampler_ts = true;
-         /* Do not set flush_seqno because the resolve-to-self was bypassed */
       } else {
          /* Resolve TS if needed */
          etna_copy_resource(view->context, &to->base, &from->base, 0,
                             view->texture->last_level);
-         to->flush_seqno = from->seqno;
          ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;
       }
    }
index b77cd4b..b569fac 100644 (file)
@@ -104,6 +104,7 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
    struct etna_context *ctx = etna_context(pctx);
    struct etna_transfer *trans = etna_transfer(ptrans);
    struct etna_resource *rsc = etna_resource(ptrans->resource);
+   struct etna_resource_level *res_level;
 
    /* XXX
     * When writing to a resource that is already in use, replace the resource
@@ -116,6 +117,8 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
    if (rsc->texture && !etna_resource_newer(rsc, etna_resource(rsc->texture)))
       rsc = etna_resource(rsc->texture); /* switch to using the texture resource */
 
+   res_level = &rsc->levels[ptrans->level];
+
    /*
     * Temporary resources are always pulled into the CPU domain, must push them
     * back into GPU domain before the RS execs the blit to the base resource.
@@ -124,11 +127,11 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
       etna_bo_cpu_fini(etna_resource(trans->rsc)->bo);
 
    if (ptrans->usage & PIPE_MAP_WRITE) {
-      if (etna_resource_needs_flush(rsc)) {
+      if (etna_resource_level_needs_flush(res_level)) {
          if (ptrans->usage & PIPE_MAP_DISCARD_WHOLE_RESOURCE)
-            rsc->flush_seqno = rsc->seqno;
+            res_level->flush_seqno = res_level->seqno;
          else
-            etna_copy_resource(pctx, &rsc->base, &rsc->base, 0, rsc->base.last_level);
+            etna_copy_resource(pctx, &rsc->base, &rsc->base, ptrans->level, ptrans->level);
       }
 
       if (trans->rsc) {
@@ -138,8 +141,6 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
          etna_copy_resource_box(pctx, ptrans->resource, trans->rsc, ptrans->level, &ptrans->box);
       } else if (trans->staging) {
          /* map buffer object */
-         struct etna_resource_level *res_level = &rsc->levels[ptrans->level];
-
          if (rsc->layout == ETNA_LAYOUT_TILED) {
             for (unsigned z = 0; z < ptrans->box.depth; z++) {
                etna_texture_tile(
@@ -163,8 +164,8 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans)
          FREE(trans->staging);
       }
 
-      rsc->levels[ptrans->level].ts_valid = false;
-      rsc->seqno++;
+      res_level->ts_valid = false;
+      res_level->seqno++;
 
       if (rsc->base.bind & PIPE_BIND_SAMPLER_VIEW) {
          ctx->dirty |= ETNA_DIRTY_TEXTURE_CACHES;