a5xx: fix primitive restart
authorIlia Mirkin <imirkin@alum.mit.edu>
Sat, 8 Jul 2017 01:10:05 +0000 (21:10 -0400)
committerIlia Mirkin <imirkin@alum.mit.edu>
Sun, 9 Jul 2017 01:14:58 +0000 (21:14 -0400)
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/freedreno/a5xx/a5xx.xml.h
src/gallium/drivers/freedreno/a5xx/fd5_emit.c

index 5203799bd2d3348c2a86cb6fcc65e02acc9841c4..ae946d81bd58239bb4b3c4bfae8d2070992ad7f6 100644 (file)
@@ -8,7 +8,7 @@ http://github.com/freedreno/envytools/
 git clone https://github.com/freedreno/envytools.git
 
 The rules-ng-ng source files this header was generated from are:
-- /home/ilia/src/freedreno/envytools/rnndb/adreno/a5xx.xml          ( 141876 bytes, from 2017-07-07 04:12:33)
+- /home/ilia/src/freedreno/envytools/rnndb/adreno/a5xx.xml          ( 141938 bytes, from 2017-07-08 01:02:47)
 - /home/ilia/src/freedreno/envytools/rnndb/freedreno_copyright.xml  (   1572 bytes, from 2016-02-11 01:04:14)
 - /home/ilia/src/freedreno/envytools/rnndb/adreno/adreno_common.xml (  13324 bytes, from 2017-07-04 02:59:47)
 - /home/ilia/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml    (  31866 bytes, from 2017-07-04 02:59:47)
@@ -3703,6 +3703,7 @@ static inline uint32_t A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC(uint32_t val)
 {
        return ((val) << A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC__SHIFT) & A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC__MASK;
 }
+#define A5XX_PC_PRIMITIVE_CNTL_PRIMITIVE_RESTART               0x00000100
 #define A5XX_PC_PRIMITIVE_CNTL_PROVOKING_VTX_LAST              0x00000400
 
 #define REG_A5XX_PC_PRIM_VTX_CNTL                              0x0000e385
index bede05e98128ba77aa4bf6e562b76440a6a6c520..2939aaca86820e4e5f4e682f99042ebab2a11da0 100644 (file)
@@ -580,15 +580,9 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
        if (dirty & FD_DIRTY_PROG)
                fd5_program_emit(ctx, ring, emit);
 
-       /* note: must come after program emit.. because there is some overlap
-        * in registers, ex. PC_PRIMITIVE_CNTL and we rely on some cached
-        * values from fd5_program_emit() to avoid having to re-emit the prog
-        * every time rast state changes.
-        */
-       if (dirty & (FD_DIRTY_PROG | FD_DIRTY_RASTERIZER)) {
+       if (dirty & FD_DIRTY_RASTERIZER) {
                struct fd5_rasterizer_stateobj *rasterizer =
                                fd5_rasterizer_stateobj(ctx->rasterizer);
-               unsigned max_loc = fd5_context(ctx)->max_loc;
 
                OUT_PKT4(ring, REG_A5XX_GRAS_SU_CNTL, 1);
                OUT_RING(ring, rasterizer->gras_su_cntl);
@@ -602,10 +596,6 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_RING(ring, rasterizer->gras_su_poly_offset_offset);
                OUT_RING(ring, rasterizer->gras_su_poly_offset_clamp);
 
-               OUT_PKT4(ring, REG_A5XX_PC_PRIMITIVE_CNTL, 1);
-               OUT_RING(ring, rasterizer->pc_primitive_cntl |
-                                A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC(max_loc));
-
                OUT_PKT4(ring, REG_A5XX_PC_RASTER_CNTL, 1);
                OUT_RING(ring, rasterizer->pc_raster_cntl);
 
@@ -613,6 +603,26 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                OUT_RING(ring, rasterizer->gras_cl_clip_cntl);
        }
 
+       /* note: must come after program emit.. because there is some overlap
+        * in registers, ex. PC_PRIMITIVE_CNTL and we rely on some cached
+        * values from fd5_program_emit() to avoid having to re-emit the prog
+        * every time rast state changes.
+        *
+        * Since the primitive restart state is not part of a tracked object, we
+        * re-emit this register every time.
+        */
+       if (emit->info && ctx->rasterizer) {
+               struct fd5_rasterizer_stateobj *rasterizer =
+                               fd5_rasterizer_stateobj(ctx->rasterizer);
+               unsigned max_loc = fd5_context(ctx)->max_loc;
+
+               OUT_PKT4(ring, REG_A5XX_PC_PRIMITIVE_CNTL, 1);
+               OUT_RING(ring, rasterizer->pc_primitive_cntl |
+                                A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC(max_loc) |
+                                COND(emit->info->primitive_restart && emit->info->index_size,
+                                         A5XX_PC_PRIMITIVE_CNTL_PRIMITIVE_RESTART));
+       }
+
        if (dirty & (FD_DIRTY_FRAMEBUFFER | FD_DIRTY_RASTERIZER)) {
                uint32_t posz_regid = ir3_find_output_regid(fp, FRAG_RESULT_DEPTH);
                unsigned nr = pfb->nr_cbufs;