From 3511a51be07aac4a4f9378db7b5c83347174755d Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 18 Dec 2017 15:09:49 -0500 Subject: [PATCH] freedreno/ir3: handle VTXID_BASE for indirect draws Need to do some gymnastics to copy the parameter from the indirect parameters buffer to uniform so shader sees the correct base-vertex-id. Fixes ./bin/arb_draw_indirect-vertexid on a5xx and probably a4xx too. Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/ir3/ir3_shader.c | 43 ++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/freedreno/ir3/ir3_shader.c b/src/gallium/drivers/freedreno/ir3/ir3_shader.c index 3b1fcdfd5f9..5d67d4877f5 100644 --- a/src/gallium/drivers/freedreno/ir3/ir3_shader.c +++ b/src/gallium/drivers/freedreno/ir3/ir3_shader.c @@ -827,8 +827,47 @@ ir3_emit_vs_consts(const struct ir3_shader_variant *v, struct fd_ringbuffer *rin } fd_wfi(ctx->batch, ring); - ctx->emit_const(ring, SHADER_VERTEX, offset * 4, 0, - vertex_params_size, vertex_params, NULL); + + bool needs_vtxid_base = + ir3_find_sysval_regid(v, SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) != regid(63, 0); + + /* for indirect draw, we need to copy VTXID_BASE from + * indirect-draw parameters buffer.. which is annoying + * and means we can't easily emit these consts in cmd + * stream so need to copy them to bo. + */ + if (info->indirect && needs_vtxid_base) { + struct pipe_draw_indirect_info *indirect = info->indirect; + struct pipe_resource *vertex_params_rsc = + pipe_buffer_create(&ctx->screen->base, + PIPE_BIND_CONSTANT_BUFFER, PIPE_USAGE_STREAM, + vertex_params_size * 4); + unsigned src_off = info->indirect->offset;; + void *ptr; + + ptr = fd_bo_map(fd_resource(vertex_params_rsc)->bo); + memcpy(ptr, vertex_params, vertex_params_size * 4); + + if (info->index_size) { + /* indexed draw, index_bias is 4th field: */ + src_off += 3 * 4; + } else { + /* non-indexed draw, start is 3rd field: */ + src_off += 2 * 4; + } + + /* copy index_bias or start from draw params: */ + ctx->mem_to_mem(ring, vertex_params_rsc, 0, + indirect->buffer, src_off, 1); + + ctx->emit_const(ring, SHADER_VERTEX, offset * 4, 0, + vertex_params_size, NULL, vertex_params_rsc); + + pipe_resource_reference(&vertex_params_rsc, NULL); + } else { + ctx->emit_const(ring, SHADER_VERTEX, offset * 4, 0, + vertex_params_size, vertex_params, NULL); + } /* if needed, emit stream-out buffer addresses: */ if (vertex_params[IR3_DP_VTXCNT_MAX] > 0) { -- 2.11.0