From 53445284a427f79e94607dc4ca2f8bd8ac293356 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 19 May 2022 20:29:38 +0200 Subject: [PATCH] etnaviv: add linear PE support GPUs with the LINEAR_PE feature bit have the ability to render into linear buffers. While this decreases PE cache effectiveness and is thus slower than rendering into a (super-)tiled buffer, it's still preferable for cases where we would need a blit to get into linear otherwise, i.e. when importing a linear buffer or when linear is forced on allocation by usage flags or modifiers. Signed-off-by: Lucas Stach Reviewed-by: Christian Gmeiner Part-of: --- src/gallium/drivers/etnaviv/etnaviv_state.c | 11 +++++++++-- src/gallium/drivers/etnaviv/etnaviv_surface.c | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c index 6b2f9bcdd17..66aaabd289f 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_state.c +++ b/src/gallium/drivers/etnaviv/etnaviv_state.c @@ -136,6 +136,7 @@ etna_set_framebuffer_state(struct pipe_context *pctx, int nr_samples_color = -1; int nr_samples_depth = -1; bool target_16bpp = false; + bool target_linear = false; /* Set up TS as well. Warning: this state is used by both the RS and PE */ uint32_t ts_mem_config = 0; @@ -148,9 +149,13 @@ etna_set_framebuffer_state(struct pipe_context *pctx, bool color_supertiled = (res->layout & ETNA_LAYOUT_BIT_SUPER) != 0; uint32_t fmt = translate_pe_format(cbuf->base.format); - assert(res->layout & ETNA_LAYOUT_BIT_TILE); /* Cannot render to linear surfaces */ + assert((res->layout & ETNA_LAYOUT_BIT_TILE) || + VIV_FEATURE(screen, chipMinorFeatures2, LINEAR_PE)); etna_update_render_resource(pctx, etna_resource(cbuf->prsc)); + if (res->layout == ETNA_LAYOUT_LINEAR) + target_linear = true; + if (fmt >= PE_FORMAT_R16F) cs->PE_COLOR_FORMAT = VIVS_PE_COLOR_FORMAT_FORMAT_EXT(fmt) | VIVS_PE_COLOR_FORMAT_FORMAT_MASK; @@ -366,7 +371,9 @@ etna_set_framebuffer_state(struct pipe_context *pctx, * one per color buffer / depth buffer. To keep the logic simple always use * single buffer when this feature is available. */ - if (screen->specs.single_buffer) + if (unlikely(target_linear)) + pe_logic_op |= VIVS_PE_LOGIC_OP_SINGLE_BUFFER(1); + else if (screen->specs.single_buffer) pe_logic_op |= VIVS_PE_LOGIC_OP_SINGLE_BUFFER(target_16bpp ? 3 : 2); cs->PE_LOGIC_OP = pe_logic_op; diff --git a/src/gallium/drivers/etnaviv/etnaviv_surface.c b/src/gallium/drivers/etnaviv/etnaviv_surface.c index 52a937652d2..0850f44613d 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_surface.c +++ b/src/gallium/drivers/etnaviv/etnaviv_surface.c @@ -48,10 +48,11 @@ etna_render_handle_incompatible(struct pipe_context *pctx, struct pipe_resource bool need_multitiled = screen->specs.pixel_pipes > 1 && !screen->specs.single_buffer; bool want_supertiled = screen->specs.can_supertile; - /* Resource is compatible if it is tiled and has multi tiling when required - * TODO: LINEAR_PE feature means render to linear is possible ? + /* 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 && + if ((res->layout != ETNA_LAYOUT_LINEAR || + VIV_FEATURE(screen, chipMinorFeatures2, LINEAR_PE)) && (!need_multitiled || (res->layout & ETNA_LAYOUT_BIT_MULTI))) return res;