freedreno/a4xx: add support for vertexid and instanceid sysvals
authorRob Clark <robclark@freedesktop.org>
Sun, 21 Dec 2014 16:38:34 +0000 (11:38 -0500)
committerRob Clark <robclark@freedesktop.org>
Tue, 24 Feb 2015 19:23:38 +0000 (14:23 -0500)
ir3 bits of it already in place from a3xx patch..

Signed-off-by: Rob Clark <robclark@freedesktop.org>
src/gallium/drivers/freedreno/a4xx/fd4_emit.c
src/gallium/drivers/freedreno/freedreno_screen.c

index 0e00e387f14ea4eb3fb6e07003b00ace818982d1..c1d7c4083ea0f78b7abe43bdfdb29689adc8fa0b 100644 (file)
@@ -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 */
index b17ea580d7e4b856b74f2b32a4d1aebc27e1a56a..97bab9dd242788668b41cf52b6661c755fc1e5c9 100644 (file)
@@ -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;