Mesa (master): etnaviv: HALTI2+ instanced draw

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Jan 8 17:58:10 UTC 2020


Module: Mesa
Branch: master
Commit: 93ff6f59199800c2b3bf339500fb5f9d92cd43c0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=93ff6f59199800c2b3bf339500fb5f9d92cd43c0

Author: Jonathan Marek <jonathan at marek.ca>
Date:   Sun Jan  5 21:38:15 2020 -0500

etnaviv: HALTI2+ instanced draw

Fixes:
dEQP-GLES3.functional.draw.draw_arrays_instanced.*
dEQP-GLES3.functional.draw.draw_elements_instanced.*

Signed-off-by: Jonathan Marek <jonathan at marek.ca>
Reviewed-by: Christian Gmeiner <christian.gmeiner at gmail.com>

---

 src/gallium/drivers/etnaviv/etnaviv_context.c  |  2 +-
 src/gallium/drivers/etnaviv/etnaviv_emit.c     | 12 +++++++-----
 src/gallium/drivers/etnaviv/etnaviv_internal.h |  3 ++-
 src/gallium/drivers/etnaviv/etnaviv_screen.c   |  3 +++
 src/gallium/drivers/etnaviv/etnaviv_state.c    | 19 +++++++++++++++----
 5 files changed, 28 insertions(+), 11 deletions(-)

diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c
index 5652107f4dc..533b4033adc 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -327,7 +327,7 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
    if (ctx->specs.halti >= 2) {
       /* On HALTI2+ (GC3000 and higher) only use instanced drawing commands, as the blob does */
-      etna_draw_instanced(ctx->stream, info->index_size, draw_mode, 1,
+      etna_draw_instanced(ctx->stream, info->index_size, draw_mode, info->instance_count,
          info->count, info->index_size ? info->index_bias : info->start);
    } else {
       if (info->index_size)
diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.c b/src/gallium/drivers/etnaviv/etnaviv_emit.c
index 4982cdb9074..977f156958a 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_emit.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_emit.c
@@ -327,11 +327,6 @@ etna_emit_state(struct etna_context *ctx)
                /*14640*/ EMIT_STATE(NFE_VERTEX_STREAMS_CONTROL(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_CONTROL);
             }
          }
-         for (int x = 0; x < ctx->vertex_buffer.count; ++x) {
-            if (ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR.bo) {
-               /*14680*/ EMIT_STATE(NFE_VERTEX_STREAMS_VERTEX_DIVISOR(x), ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_VERTEX_DIVISOR);
-            }
-         }
       } else if(ctx->specs.stream_count > 1) { /* hw w/ multiple vertex streams */
          for (int x = 0; x < ctx->vertex_buffer.count; ++x) {
             /*00680*/ EMIT_STATE_RELOC(FE_VERTEX_STREAMS_BASE_ADDR(x), &ctx->vertex_buffer.cvb[x].FE_VERTEX_STREAM_BASE_ADDR);
@@ -346,6 +341,13 @@ etna_emit_state(struct etna_context *ctx)
          /*00650*/ EMIT_STATE(FE_VERTEX_STREAM_CONTROL, ctx->vertex_buffer.cvb[0].FE_VERTEX_STREAM_CONTROL);
       }
    }
+   /* gallium has instance divisor as part of elements state */
+   if ((dirty & (ETNA_DIRTY_VERTEX_ELEMENTS)) && ctx->specs.halti >= 2) {
+      for (int x = 0; x < ctx->vertex_elements->num_buffers; ++x) {
+         /*14680*/ EMIT_STATE(NFE_VERTEX_STREAMS_VERTEX_DIVISOR(x), ctx->vertex_elements->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[x]);
+      }
+   }
+
    if (unlikely(dirty & (ETNA_DIRTY_SHADER | ETNA_DIRTY_RASTERIZER))) {
 
       /*00804*/ EMIT_STATE(VS_OUTPUT_COUNT, vs_output_count);
diff --git a/src/gallium/drivers/etnaviv/etnaviv_internal.h b/src/gallium/drivers/etnaviv/etnaviv_internal.h
index 25f6a38ab98..b226526410d 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_internal.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_internal.h
@@ -228,12 +228,13 @@ struct compiled_vertex_elements_state {
    uint32_t NFE_GENERIC_ATTRIB_CONFIG0[VIVS_NFE_GENERIC_ATTRIB__LEN];
    uint32_t NFE_GENERIC_ATTRIB_SCALE[VIVS_NFE_GENERIC_ATTRIB__LEN];
    uint32_t NFE_GENERIC_ATTRIB_CONFIG1[VIVS_NFE_GENERIC_ATTRIB__LEN];
+   unsigned num_buffers;
+   uint32_t NFE_VERTEX_STREAMS_VERTEX_DIVISOR[VIVS_NFE_VERTEX_STREAMS__LEN];
 };
 
 /* Compiled context->set_vertex_buffer result */
 struct compiled_set_vertex_buffer {
    uint32_t FE_VERTEX_STREAM_CONTROL;
-   uint32_t FE_VERTEX_STREAM_VERTEX_DIVISOR;
    struct etna_reloc FE_VERTEX_STREAM_BASE_ADDR;
 };
 
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
index df537f285bf..3f687c4314a 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
@@ -190,6 +190,9 @@ etna_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 255;
    case PIPE_CAP_MAX_VERTEX_BUFFERS:
       return screen->specs.stream_count;
+   case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR:
+      return VIV_FEATURE(screen, chipMinorFeatures4, HALTI2);
+
 
    /* Texturing. */
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
diff --git a/src/gallium/drivers/etnaviv/etnaviv_state.c b/src/gallium/drivers/etnaviv/etnaviv_state.c
index 67f9512f74e..34d83f9a3fa 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_state.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_state.c
@@ -551,7 +551,7 @@ etna_vertex_elements_state_create(struct pipe_context *pctx,
    /* TODO: does mesa this for us? */
    bool incompatible = false;
    for (unsigned idx = 0; idx < num_elements; ++idx) {
-      if (elements[idx].vertex_buffer_index >= ctx->specs.stream_count || elements[idx].instance_divisor > 0)
+      if (elements[idx].vertex_buffer_index >= ctx->specs.stream_count)
          incompatible = true;
    }
 
@@ -564,8 +564,10 @@ etna_vertex_elements_state_create(struct pipe_context *pctx,
 
    unsigned start_offset = 0; /* start of current consecutive stretch */
    bool nonconsecutive = true; /* previous value of nonconsecutive */
+   uint32_t buffer_mask = 0; /* mask of buffer_idx already seen */
 
    for (unsigned idx = 0; idx < num_elements; ++idx) {
+      unsigned buffer_idx = elements[idx].vertex_buffer_index;
       unsigned element_size = util_format_get_blocksize(elements[idx].src_format);
       unsigned end_offset = elements[idx].src_offset + element_size;
       uint32_t format_type, normalize;
@@ -578,7 +580,7 @@ etna_vertex_elements_state_create(struct pipe_context *pctx,
 
       /* check whether next element is consecutive to this one */
       nonconsecutive = (idx == (num_elements - 1)) ||
-                       elements[idx + 1].vertex_buffer_index != elements[idx].vertex_buffer_index ||
+                       elements[idx + 1].vertex_buffer_index != buffer_idx ||
                        end_offset != elements[idx + 1].src_offset;
 
       format_type = translate_vertex_format_type(elements[idx].src_format);
@@ -593,7 +595,7 @@ etna_vertex_elements_state_create(struct pipe_context *pctx,
             format_type |
             VIVS_FE_VERTEX_ELEMENT_CONFIG_NUM(util_format_get_nr_components(elements[idx].src_format)) |
             normalize | VIVS_FE_VERTEX_ELEMENT_CONFIG_ENDIAN(ENDIAN_MODE_NO_SWAP) |
-            VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(elements[idx].vertex_buffer_index) |
+            VIVS_FE_VERTEX_ELEMENT_CONFIG_STREAM(buffer_idx) |
             VIVS_FE_VERTEX_ELEMENT_CONFIG_START(elements[idx].src_offset) |
             VIVS_FE_VERTEX_ELEMENT_CONFIG_END(end_offset - start_offset);
       } else { /* HALTI5 spread vertex attrib config over two registers */
@@ -601,7 +603,7 @@ etna_vertex_elements_state_create(struct pipe_context *pctx,
             format_type |
             VIVS_NFE_GENERIC_ATTRIB_CONFIG0_NUM(util_format_get_nr_components(elements[idx].src_format)) |
             normalize | VIVS_NFE_GENERIC_ATTRIB_CONFIG0_ENDIAN(ENDIAN_MODE_NO_SWAP) |
-            VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(elements[idx].vertex_buffer_index) |
+            VIVS_NFE_GENERIC_ATTRIB_CONFIG0_STREAM(buffer_idx) |
             VIVS_NFE_GENERIC_ATTRIB_CONFIG0_START(elements[idx].src_offset);
          cs->NFE_GENERIC_ATTRIB_CONFIG1[idx] =
             COND(nonconsecutive, VIVS_NFE_GENERIC_ATTRIB_CONFIG1_NONCONSECUTIVE) |
@@ -612,6 +614,15 @@ etna_vertex_elements_state_create(struct pipe_context *pctx,
          cs->NFE_GENERIC_ATTRIB_SCALE[idx] = 1;
       else
          cs->NFE_GENERIC_ATTRIB_SCALE[idx] = fui(1.0f);
+
+      /* instance_divisor is part of elements state but should be the same for all buffers */
+      if (buffer_mask & 1 << buffer_idx)
+         assert(cs->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[buffer_idx] == elements[idx].instance_divisor);
+      else
+         cs->NFE_VERTEX_STREAMS_VERTEX_DIVISOR[buffer_idx] = elements[idx].instance_divisor;
+
+      buffer_mask |= 1 << buffer_idx;
+      cs->num_buffers = MAX2(cs->num_buffers, buffer_idx + 1);
    }
 
    return cs;




More information about the mesa-commit mailing list