etnaviv: add resource render compatible check

Untangle the convoluted render compatible check from
etna_render_handle_incompatible to make it easier to read and move it
into a separate function so it can be reused from other callers.

As this is intended to be called also at resource creation time, where
we don't know the exact level of the resource that might be rendered to,
the stride check for linear resources is made a bit more conservative by
checking that the last level (the one with the smallest stride) still
meets the render target stride alignment requirement.

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/34488>
This commit is contained in:
Lucas Stach
2025-04-11 22:42:36 +02:00
committed by Marge Bot
parent 4717022cb0
commit 83ab7a8d58
3 changed files with 33 additions and 13 deletions
@@ -81,6 +81,32 @@ static uint64_t etna_resource_modifier(struct etna_resource *rsc)
return layout_to_modifier(rsc->layout);
}
bool
etna_resource_is_render_compatible(struct pipe_screen *pscreen,
struct etna_resource *rsc)
{
struct etna_screen *screen = etna_screen(pscreen);
if (rsc->layout == ETNA_LAYOUT_LINEAR) {
if (!VIV_FEATURE(screen, ETNA_FEATURE_LINEAR_PE))
return false;
if (VIV_FEATURE(screen, ETNA_FEATURE_FAST_CLEAR)) {
unsigned int min_tilesize = etna_screen_get_tile_size(screen, TS_MODE_128B,
rsc->base.nr_samples > 1);
if (rsc->levels[rsc->base.last_level].stride % min_tilesize != 0)
return false;
}
}
if (screen->specs.pixel_pipes > 1 && !screen->specs.single_buffer &&
!(rsc->layout & ETNA_LAYOUT_BIT_MULTI))
return false;
return true;
}
/* A tile is either 64 bytes or, when the GPU has the CACHE128B256BPERLINE
* feature, 128/256 bytes of color/depth data, tracked by
* 'screen->specs.bits_per_tile' bits of tile status.
@@ -281,6 +281,10 @@ etna_resource_hw_tileable(bool use_blt, const struct pipe_resource *pres)
util_format_get_blocksize(pres->format) == 4;
}
bool
etna_resource_is_render_compatible(struct pipe_screen *pscreen,
struct etna_resource *rsc);
/* returns TRUE if resource TS buffer is exposed externally */
static inline bool
etna_resource_ext_ts(const struct etna_resource *res)
+3 -13
View File
@@ -40,25 +40,15 @@
static struct etna_resource *
etna_render_handle_incompatible(struct pipe_context *pctx,
struct pipe_resource *prsc,
unsigned int level)
struct pipe_resource *prsc)
{
struct etna_context *ctx = etna_context(pctx);
struct etna_screen *screen = ctx->screen;
struct etna_resource *res = etna_resource(prsc);
bool need_multitiled = screen->specs.pixel_pipes > 1 && !screen->specs.single_buffer;
bool want_supertiled = screen->specs.can_supertile;
unsigned int min_tilesize = etna_screen_get_tile_size(screen, TS_MODE_128B,
prsc->nr_samples > 1);
/* Resource is compatible if it is tiled or PE is able to render to linear
* and has multi tiling when required.
*/
if ((res->layout != ETNA_LAYOUT_LINEAR ||
(VIV_FEATURE(screen, ETNA_FEATURE_LINEAR_PE) &&
(!VIV_FEATURE(screen, ETNA_FEATURE_FAST_CLEAR) ||
res->levels[level].stride % min_tilesize == 0))) &&
(!need_multitiled || (res->layout & ETNA_LAYOUT_BIT_MULTI)))
if (etna_resource_is_render_compatible(pctx->screen, res))
return res;
if (!res->render) {
@@ -87,7 +77,7 @@ etna_create_surface(struct pipe_context *pctx, struct pipe_resource *prsc,
struct etna_screen *screen = ctx->screen;
unsigned layer = templat->u.tex.first_layer;
unsigned level = templat->u.tex.level;
struct etna_resource *rsc = etna_render_handle_incompatible(pctx, prsc, level);
struct etna_resource *rsc = etna_render_handle_incompatible(pctx, prsc);
struct etna_resource_level *lev = &rsc->levels[level];
struct etna_surface *surf = CALLOC_STRUCT(etna_surface);