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@marek.ca> Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user