summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/freedreno/a3xx
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/freedreno/a3xx')
-rw-r--r--src/gallium/drivers/freedreno/a3xx/fd3_emit.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
index 1c17e2ddde0..ad5fcb35cf5 100644
--- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
+++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c
@@ -351,21 +351,31 @@ fd3_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf
void
fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
{
- uint32_t i, j, last = 0;
+ int32_t i, j, last = -1;
uint32_t total_in = 0;
const struct fd_vertex_state *vtx = emit->vtx;
struct ir3_shader_variant *vp = fd3_emit_get_vp(emit);
- unsigned n = MIN2(vtx->vtx->num_elements, vp->inputs_count);
+ unsigned vertex_regid = regid(63, 0), instance_regid = regid(63, 0);
+
+ for (i = 0; i < vp->inputs_count; i++) {
+ uint8_t semantic = sem2name(vp->inputs[i].semantic);
+ if (semantic == TGSI_SEMANTIC_VERTEXID_NOBASE)
+ vertex_regid = vp->inputs[i].regid;
+ else if (semantic == TGSI_SEMANTIC_INSTANCEID)
+ instance_regid = vp->inputs[i].regid;
+ else if (i < vtx->vtx->num_elements && vp->inputs[i].compmask)
+ last = i;
+ }
/* hw doesn't like to be configured for zero vbo's, it seems: */
- if (vtx->vtx->num_elements == 0)
+ if (vtx->vtx->num_elements == 0 &&
+ vertex_regid == regid(63, 0) &&
+ instance_regid == regid(63, 0))
return;
- for (i = 0; i < n; i++)
- if (vp->inputs[i].compmask)
- last = i;
-
for (i = 0, j = 0; i <= last; i++) {
+ uint8_t semantic = sem2name(vp->inputs[i].semantic);
+ assert(semantic == 0);
if (vp->inputs[i].compmask) {
struct pipe_vertex_element *elem = &vtx->vtx->pipe[i];
const struct pipe_vertex_buffer *vb =
@@ -373,7 +383,9 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
struct fd_resource *rsc = fd_resource(vb->buffer);
enum pipe_format pfmt = elem->src_format;
enum a3xx_vtx_fmt fmt = fd3_pipe2vtx(pfmt);
- bool switchnext = (i != last);
+ bool switchnext = (i != last) ||
+ vertex_regid != regid(63, 0) ||
+ instance_regid != regid(63, 0);
bool isint = util_format_is_pure_integer(pfmt);
uint32_t fs = util_format_get_blocksize(pfmt);
@@ -409,8 +421,8 @@ fd3_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd3_emit *emit)
A3XX_VFD_CONTROL_0_STRMDECINSTRCNT(j) |
A3XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(j));
OUT_RING(ring, A3XX_VFD_CONTROL_1_MAXSTORAGE(1) | // XXX
- A3XX_VFD_CONTROL_1_REGID4VTX(regid(63,0)) |
- A3XX_VFD_CONTROL_1_REGID4INST(regid(63,0)));
+ A3XX_VFD_CONTROL_1_REGID4VTX(vertex_regid) |
+ A3XX_VFD_CONTROL_1_REGID4INST(instance_regid));
}
void
@@ -580,6 +592,20 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
}
}
+ /* emit driver params every time */
+ if (emit->info && emit->prog == &ctx->prog) {
+ uint32_t vertex_params[4] = {
+ emit->info->indexed ? emit->info->index_bias : emit->info->start,
+ 0,
+ 0,
+ 0
+ };
+ if (vp->constlen > vp->first_driver_param) {
+ fd3_emit_constant(ring, SB_VERT_SHADER, vp->first_driver_param * 4,
+ 0, 4, vertex_params, NULL);
+ }
+ }
+
if ((dirty & (FD_DIRTY_BLEND | FD_DIRTY_FRAMEBUFFER)) && ctx->blend) {
struct fd3_blend_stateobj *blend = fd3_blend_stateobj(ctx->blend);
uint32_t i;