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 <l.stach@pengutronix.de>
Reviewed-by: Christian Gmeiner <cgmeiner@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19964>
This commit is contained in:
Lucas Stach
2022-11-17 18:57:42 +01:00
committed by Marge Bot
parent 73c1eb50dc
commit ff3741eee1
9 changed files with 80 additions and 43 deletions

View 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;

View 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

View 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);
}

View 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;

View 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,26 +141,30 @@ 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;
return false;
}
/* 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);
}
bool etna_resource_needs_flush(struct etna_resource *res);
/* is the resource only used on the sampler? */
static inline bool

View 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;

View 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

View 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;
}
}

View 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;