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

Wladimir J. van der Laan laanwj at gmail.com
Fri Sep 29 16:00:13 UTC 2017


If an RS blit is done with source exactly the same as destination, and
the hardware supports this, do an in-place resolve.

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>
---
 src/gallium/drivers/etnaviv/etnaviv_emit.c |  9 ++++++++-
 src/gallium/drivers/etnaviv/etnaviv_rs.c   | 16 +++++++++++++---
 src/gallium/drivers/etnaviv/etnaviv_rs.h   |  1 +
 3 files changed, 22 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_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..7e90ab7 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_rs.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_rs.c
@@ -118,10 +118,20 @@ 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.
+
+   /* Is source the same as destination, if so do an in-place resolve if
+    * the hardware supports this.
     */
+   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) {
+       cs->RS_KICKER_INPLACE = (rs->width / 4) * (rs->height / 4);
+   }
 }
 
 void
diff --git a/src/gallium/drivers/etnaviv/etnaviv_rs.h b/src/gallium/drivers/etnaviv/etnaviv_rs.h
index ec5b659..b354a26 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_rs.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_rs.h
@@ -69,6 +69,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];
-- 
2.7.4



More information about the etnaviv mailing list