diff options
-rw-r--r-- | src/gallium/drivers/freedreno/a4xx/fd4_emit.c | 33 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_screen.c | 2 |
2 files changed, 24 insertions, 11 deletions
diff --git a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c index 0e00e387f14..c1d7c4083ea 100644 --- a/src/gallium/drivers/freedreno/a4xx/fd4_emit.c +++ b/src/gallium/drivers/freedreno/a4xx/fd4_emit.c @@ -278,21 +278,32 @@ fd4_emit_gmem_restore_tex(struct fd_ringbuffer *ring, struct pipe_surface *psurf void fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_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 = fd4_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) + 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 != TGSI_SEMANTIC_VERTEXID); + assert(semantic != TGSI_SEMANTIC_INSTANCEID); if (vp->inputs[i].compmask) { struct pipe_vertex_element *elem = &vtx->vtx->pipe[i]; const struct pipe_vertex_buffer *vb = @@ -300,7 +311,9 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit) struct fd_resource *rsc = fd_resource(vb->buffer); enum pipe_format pfmt = elem->src_format; enum a4xx_vtx_fmt fmt = fd4_pipe2vtx(pfmt); - bool switchnext = (i != last); + bool switchnext = (i != last) || + (vertex_regid != regid(63, 0)) || + (instance_regid != regid(63, 0)); uint32_t fs = util_format_get_blocksize(pfmt); uint32_t off = vb->buffer_offset + elem->src_offset; uint32_t size = fd_bo_size(rsc->bo) - off; @@ -335,8 +348,8 @@ fd4_emit_vertex_bufs(struct fd_ringbuffer *ring, struct fd4_emit *emit) A4XX_VFD_CONTROL_0_STRMDECINSTRCNT(j) | A4XX_VFD_CONTROL_0_STRMFETCHINSTRCNT(j)); OUT_RING(ring, A4XX_VFD_CONTROL_1_MAXSTORAGE(129) | // XXX - A4XX_VFD_CONTROL_1_REGID4VTX(regid(63,0)) | - A4XX_VFD_CONTROL_1_REGID4INST(regid(63,0))); + A4XX_VFD_CONTROL_1_REGID4VTX(vertex_regid) | + A4XX_VFD_CONTROL_1_REGID4INST(instance_regid)); OUT_RING(ring, 0x00000000); /* XXX VFD_CONTROL_2 */ OUT_RING(ring, 0x0000fc00); /* XXX VFD_CONTROL_3 */ OUT_RING(ring, 0x00000000); /* XXX VFD_CONTROL_4 */ diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index b17ea580d7e..97bab9dd242 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -169,9 +169,9 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_SM3: case PIPE_CAP_PRIMITIVE_RESTART: + case PIPE_CAP_TGSI_INSTANCEID: return is_a3xx(screen) || is_a4xx(screen); - case PIPE_CAP_TGSI_INSTANCEID: case PIPE_CAP_VERTEX_ELEMENT_INSTANCE_DIVISOR: return is_a3xx(screen) && glsl130; |