diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.c b/src/gallium/drivers/etnaviv/etnaviv_resource.c index a36e727abc8..7ebe1dab6f3 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.c +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.c @@ -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. diff --git a/src/gallium/drivers/etnaviv/etnaviv_resource.h b/src/gallium/drivers/etnaviv/etnaviv_resource.h index c29e019362d..b2721d0ed40 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_resource.h +++ b/src/gallium/drivers/etnaviv/etnaviv_resource.h @@ -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) diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c b/src/gallium/drivers/etnaviv/etnaviv_surface.c index 321407f767b..cb27c8cfd27 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_surface.c +++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c @@ -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);