From ff3741eee1d2eb50226d75315ca0bc48d9848f1c Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 17 Nov 2022 18:57:42 +0100 Subject: [PATCH] etnaviv: move resource seqnos to level 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 Reviewed-by: Christian Gmeiner Part-of: --- src/gallium/drivers/etnaviv/etnaviv_blt.c | 6 +-- src/gallium/drivers/etnaviv/etnaviv_clear_blit.c | 20 ++++++--- src/gallium/drivers/etnaviv/etnaviv_context.c | 4 +- src/gallium/drivers/etnaviv/etnaviv_resource.c | 11 +++-- src/gallium/drivers/etnaviv/etnaviv_resource.h | 54 ++++++++++++++++++------ src/gallium/drivers/etnaviv/etnaviv_rs.c | 6 +-- src/gallium/drivers/etnaviv/etnaviv_state.c | 4 +- src/gallium/drivers/etnaviv/etnaviv_texture.c | 3 -- src/gallium/drivers/etnaviv/etnaviv_transfer.c | 15 ++++--- 9 files changed, 80 insertions(+), 43 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_blt.c b/src/gallium/drivers/etnaviv/etnaviv_blt.c index 59c8d91..6c1128b 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_blt.c +++ b/src/gallium/drivers/etnaviv/etnaviv_blt.c @@ -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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c index 4ce4eeb..4422571 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c @@ -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 diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c index de951d0..feb6d7c 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_context.c +++ b/src/gallium/drivers/etnaviv/etnaviv_context.c @@ -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); } diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index c7dbb8e..8e1d5fb 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h index 7d692c1..6bce94e 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.h +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h @@ -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) diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c index a22ec04..f8abf14 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c @@ -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, ©_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; diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 0b49afd..8cc09fb 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -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 diff --git a/src/gallium/drivers/etnaviv/etnaviv_texture.c b/src/gallium/drivers/etnaviv/etnaviv_texture.c index c629bda..9108803 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_texture.c +++ b/src/gallium/drivers/etnaviv/etnaviv_texture.c @@ -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; } } diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c index b77cd4b..b569fac 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c +++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c @@ -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; -- 2.7.4