surf->level->clear_value = new_clear_value;
resource_written(ctx, surf->base.texture);
- etna_resource(surf->base.texture)->seqno++;
+ surf->level->seqno++;
}
static void
}
resource_written(ctx, surf->base.texture);
- etna_resource(surf->base.texture)->seqno++;
+ surf->level->seqno++;
}
static void
resource_read(ctx, &src->base);
resource_written(ctx, &dst->base);
- dst->seqno++;
+ dst_lev->seqno++;
dst_lev->ts_valid = false;
return true;
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;
}
}
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;
}
}
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);
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
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);
}
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
if (modifier == DRM_FORMAT_MOD_INVALID)
modifier = DRM_FORMAT_MOD_LINEAR;
- rsc->seqno = 1;
rsc->layout = modifier_to_layout(modifier);
rsc->modifier = modifier;
level->depth = tmpl->depth0;
level->stride = handle->stride;
level->offset = handle->offset;
+ level->seqno = 1;
/* Determine padding of the imported resource. */
unsigned paddingX, paddingY;
}
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;
/* 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. */
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, ...) */
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)
surf->level->clear_value = new_clear_value;
resource_written(ctx, surf->base.texture);
- etna_resource(surf->base.texture)->seqno++;
+ surf->level->seqno++;
}
static void
surf->level->clear_value = new_clear_value;
resource_written(ctx, surf->base.texture);
- etna_resource(surf->base.texture)->seqno++;
+ surf->level->seqno++;
}
static void
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;
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
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;
}
}
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
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.
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) {
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(
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;