aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorJonathan Marek <[email protected]>2020-01-05 21:38:15 -0500
committerJonathan Marek <[email protected]>2020-01-08 12:27:34 -0500
commit93ff6f59199800c2b3bf339500fb5f9d92cd43c0 (patch)
tree2c1182d3077ee3cf9e73119042499b04816b7453 /src/gallium/drivers
parentea608ae23b69e2264c3bacdf2776745e15dbf2e9 (diff)
etnaviv: HALTI2+ instanced draw
Fixes: dEQP-GLES3.functional.draw.draw_arrays_instanced.* dEQP-GLES3.functional.draw.draw_elements_instanced.* Signed-off-by: Jonathan Marek <[email protected]> Reviewed-by: Christian Gmeiner <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_context.c2
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_emit.c12
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_internal.h3
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_screen.c3
-rw-r--r--src/gallium/drivers/etnaviv/etnaviv_state.c19
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;