[Mesa-dev] [PATCH v2] etnaviv: Do GC3000 resolve-in-place when possible

Lucas Stach l.stach at pengutronix.de
Tue Oct 10 11:57:44 UTC 2017


Am Samstag, den 30.09.2017, 10:11 +0200 schrieb Wladimir J. van der Laan:
> If an RS blit is done with source exactly the same as destination, and
> the hardware supports this, do an in-place resolve. This only fills in
> tiles that have not been rendered to using information from the TS.
> 
> This is the same as the blob does and potentially saves significant
> bandwidth when doing i.MX6qp scanout using PRE, and when rendering to
> textures (though here using sampler TS would be even better).
> 
> Signed-off-by: Wladimir J. van der Laan <laanwj at gmail.com>

Reviewed-by: Lucas Stach <l.stach at pengutronix.de>

> ---
>  src/gallium/drivers/etnaviv/etnaviv_clear_blit.c |  1 +
>  src/gallium/drivers/etnaviv/etnaviv_emit.c       |  9 ++++++++-
>  src/gallium/drivers/etnaviv/etnaviv_rs.c         | 17 ++++++++++++++---
>  src/gallium/drivers/etnaviv/etnaviv_rs.h         |  2 ++
>  4 files changed, 25 insertions(+), 4 deletions(-)
> 
> This depends (for updating the rnndb headers) on Lucas Stach's patch
> "etnaviv: update HW headers and fix provoking vertex".
> 
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> index c85ada9..c62287b 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_clear_blit.c
> @@ -591,6 +591,7 @@ etna_try_rs_blit(struct pipe_context *pctx,
>        .source = src->bo,
>        .source_offset = src_offset,
>        .source_stride = src_lev->stride,
> +      .source_padded_width = src_lev->padded_width,
>        .source_padded_height = src_lev->padded_height,
>        .dest_format = translate_rs_format(dst_format),
>        .dest_tiling = dst->layout,
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c
> index c2117d5..707b1e7 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_emit.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c
> @@ -173,7 +173,14 @@ etna_submit_rs_state(struct etna_context *ctx,
>  
>     ctx->stats.rs_operations++;
>  
> -   if (screen->specs.pixel_pipes == 1) {
> +   if (cs->RS_KICKER_INPLACE) {
> +      etna_cmd_stream_reserve(stream, 6);
> +      etna_coalesce_start(stream, &coalesce);
> +      /* 0/1 */ EMIT_STATE(RS_EXTRA_CONFIG, cs->RS_EXTRA_CONFIG);
> +      /* 2/3 */ EMIT_STATE(RS_SOURCE_STRIDE, cs->RS_SOURCE_STRIDE);
> +      /* 4/5 */ EMIT_STATE(RS_KICKER_INPLACE, cs->RS_KICKER_INPLACE);
> +      etna_coalesce_end(stream, &coalesce);
> +   } else if (screen->specs.pixel_pipes == 1) {
>        etna_cmd_stream_reserve(stream, 22);
>        etna_coalesce_start(stream, &coalesce);
>        /* 0/1 */ EMIT_STATE(RS_CONFIG, cs->RS_CONFIG);
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.c b/src/gallium/drivers/etnaviv/etnaviv_rs.c
> index 5c108a6..c9072c2 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_rs.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c
> @@ -118,10 +118,21 @@ etna_compile_rs_state(struct etna_context *ctx, struct compiled_rs_state *cs,
>     cs->RS_FILL_VALUE[3] = rs->clear_value[3];
>     cs->RS_EXTRA_CONFIG = VIVS_RS_EXTRA_CONFIG_AA(rs->aa) |
>                           VIVS_RS_EXTRA_CONFIG_ENDIAN(rs->endian_mode);
> -   /* TODO: cs->RS_UNK016B0 = s->size / 64 ?
> -    * The blob does this consistently but there seems to be no currently supported
> -    * model that needs it.
> +
> +   /* If source the same as destination, and the hardware supports this,
> +    * do an in-place resolve to fill in unrendered tiles.
>      */
> +   if (ctx->specs.single_buffer && rs->source == rs->dest &&
> +         rs->source_offset == rs->dest_offset &&
> +         rs->source_format == rs->dest_format &&
> +         rs->source_tiling == rs->dest_tiling &&
> +         rs->source_stride == rs->dest_stride &&
> +         !rs->downsample_x && !rs->downsample_y &&
> +         !rs->swap_rb && !rs->flip &&
> +         !rs->clear_mode && rs->source_padded_width) {
> +      /* Total number of tiles (same as for autodisable) */
> +      cs->RS_KICKER_INPLACE = rs->source_padded_width * rs->source_padded_height / 16;
> +   }
>  }
>  
>  void
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.h b/src/gallium/drivers/etnaviv/etnaviv_rs.h
> index ec5b659..171d3fa 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_rs.h
> +++ b/src/gallium/drivers/etnaviv/etnaviv_rs.h
> @@ -43,6 +43,7 @@ struct rs_state {
>     struct etna_bo *source;
>     uint32_t source_offset;
>     uint32_t source_stride;
> +   uint32_t source_padded_width; /* total padded width (only needed for source) */
>     uint32_t source_padded_height; /* total padded height */
>     struct etna_bo *dest;
>     uint32_t dest_offset;
> @@ -69,6 +70,7 @@ struct compiled_rs_state {
>     uint32_t RS_FILL_VALUE[4];
>     uint32_t RS_EXTRA_CONFIG;
>     uint32_t RS_PIPE_OFFSET[2];
> +   uint32_t RS_KICKER_INPLACE; /* Set if source is destination */
>  
>     struct etna_reloc source[2];
>     struct etna_reloc dest[2];


More information about the mesa-dev mailing list