summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWladimir J. van der Laan <[email protected]>2017-11-18 10:44:27 +0100
committerChristian Gmeiner <[email protected]>2017-11-30 07:26:55 +0100
commit150d8766eae9870bc7fc59bad0f8be8dcf6a24cd (patch)
treea56c5b08d18095ec16053dc6f415238865702914
parent23630ab1b66af437267cdbc19d3f70a3922dfc59 (diff)
etnaviv: Use only DRAW_INSTANCED on GC3000+
The blob does this, as DRAW_INSTANCED can replace fully all the other draw commands. It is also required to handle integer vertex formats. The other path is only there for compatibility and might go away (or at least rot to become buggy due to dis-use) in newer hardware. As a by-effect this changes the behavior for GC3000-, by no longer using the index offset for DRAW_INDEXED but instead adding it to INDEX_ADDR. This should make no difference. Preparation for GC7000 support. Signed-off-by: Wladimir J. van der Laan <[email protected]> Reviewed-by: Philipp Zabel <[email protected]>
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_context.c16
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_emit.h21
2 files changed, 33 insertions, 4 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_context.c b/src/gallium/drivers/etnaviv/etnaviv_context.c
index 65c20d2f83a..5aa9c66ed16 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_context.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_context.c
@@ -188,6 +188,8 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
BUG("Index buffer upload failed.");
return;
}
+ /* Add start to index offset, when rendering indexed */
+ index_offset += info->start * info->index_size;
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.bo = etna_resource(indexbuf)->bo;
ctx->index_buffer.FE_INDEX_STREAM_BASE_ADDR.offset = index_offset;
@@ -273,10 +275,16 @@ etna_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
/* First, sync state, then emit DRAW_PRIMITIVES or DRAW_INDEXED_PRIMITIVES */
etna_emit_state(ctx);
- if (info->index_size)
- etna_draw_indexed_primitives(ctx->stream, draw_mode, info->start, prims, info->index_bias);
- else
- etna_draw_primitives(ctx->stream, draw_mode, info->start, prims);
+ 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,
+ info->count, info->index_size ? info->index_bias : info->start);
+ } else {
+ if (info->index_size)
+ etna_draw_indexed_primitives(ctx->stream, draw_mode, 0, prims, info->index_bias);
+ else
+ etna_draw_primitives(ctx->stream, draw_mode, info->start, prims);
+ }
if (DBG_ENABLED(ETNA_DBG_DRAW_STALL)) {
/* Stall the FE after every draw operation. This allows better
diff --git a/src/gallium/drivers/etnaviv/etnaviv_emit.h b/src/gallium/drivers/etnaviv/etnaviv_emit.h
index e0c0edab08a..3c3d1294dc8 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_emit.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_emit.h
@@ -117,6 +117,27 @@ etna_draw_indexed_primitives(struct etna_cmd_stream *stream,
etna_cmd_stream_emit(stream, 0);
}
+/* important: this takes a vertex count, not a primitive count */
+static inline void
+etna_draw_instanced(struct etna_cmd_stream *stream,
+ uint32_t indexed, uint32_t primitive_type,
+ uint32_t instance_count,
+ uint32_t vertex_count, uint32_t offset)
+{
+ etna_cmd_stream_reserve(stream, 3 + 1);
+ etna_cmd_stream_emit(stream,
+ VIV_FE_DRAW_INSTANCED_HEADER_OP_DRAW_INSTANCED |
+ COND(indexed, VIV_FE_DRAW_INSTANCED_HEADER_INDEXED) |
+ VIV_FE_DRAW_INSTANCED_HEADER_TYPE(primitive_type) |
+ VIV_FE_DRAW_INSTANCED_HEADER_INSTANCE_COUNT_LO(instance_count & 0xffff));
+ etna_cmd_stream_emit(stream,
+ VIV_FE_DRAW_INSTANCED_COUNT_INSTANCE_COUNT_HI(instance_count >> 16) |
+ VIV_FE_DRAW_INSTANCED_COUNT_VERTEX_COUNT(vertex_count));
+ etna_cmd_stream_emit(stream,
+ VIV_FE_DRAW_INSTANCED_START_INDEX(offset));
+ etna_cmd_stream_emit(stream, 0);
+}
+
void
etna_emit_state(struct etna_context *ctx);