freedreno/a5xx: provoking vertex
authorRob Clark <robdclark@gmail.com>
Wed, 17 May 2017 14:17:10 +0000 (10:17 -0400)
committerRob Clark <robdclark@gmail.com>
Tue, 23 May 2017 16:26:35 +0000 (12:26 -0400)
Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a5xx/fd5_context.h
src/gallium/drivers/freedreno/a5xx/fd5_emit.c
src/gallium/drivers/freedreno/a5xx/fd5_program.c
src/gallium/drivers/freedreno/a5xx/fd5_program.h
src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.c
src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.h

index c8db470f71ab0b28483499c6873c9d998e6c0134..f6de6ca2ae6b790a3b8916aa86c01b39b6c0652f 100644 (file)
@@ -83,6 +83,9 @@ struct fd5_context {
 
        /* number of active samples-passed queries: */
        int samples_passed_queries;
+
+       /* cached state about current emitted shader program (3d): */
+       unsigned max_loc;
 };
 
 static inline struct fd5_context *
index d959f09fc20aa25cf8828e779e3f801ddd59144c..73684c9f900befc6e53b5ece8fcf47cc3ae8d12b 100644 (file)
@@ -525,39 +525,6 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                COND(fragz && fp->frag_coord, A5XX_GRAS_SU_DEPTH_PLANE_CNTL_UNK1));
        }
 
-       if (dirty & FD_DIRTY_RASTERIZER) {
-               struct fd5_rasterizer_stateobj *rasterizer =
-                               fd5_rasterizer_stateobj(ctx->rasterizer);
-
-               OUT_PKT4(ring, REG_A5XX_GRAS_SU_CNTL, 1);
-               OUT_RING(ring, rasterizer->gras_su_cntl);
-
-               OUT_PKT4(ring, REG_A5XX_GRAS_SU_POINT_MINMAX, 2);
-               OUT_RING(ring, rasterizer->gras_su_point_minmax);
-               OUT_RING(ring, rasterizer->gras_su_point_size);
-
-               OUT_PKT4(ring, REG_A5XX_GRAS_SU_POLY_OFFSET_SCALE, 3);
-               OUT_RING(ring, rasterizer->gras_su_poly_offset_scale);
-               OUT_RING(ring, rasterizer->gras_su_poly_offset_offset);
-               OUT_RING(ring, rasterizer->gras_su_poly_offset_clamp);
-       }
-
-       /* NOTE: since primitive_restart is not actually part of any
-        * state object, we need to make sure that we always emit
-        * PRIM_VTX_CNTL.. either that or be more clever and detect
-        * when it changes.
-        */
-       if (emit->info) {
-               struct fd5_rasterizer_stateobj *rast =
-                       fd5_rasterizer_stateobj(ctx->rasterizer);
-               uint32_t val = rast->pc_prim_vtx_cntl;
-
-               val |= COND(vp->writes_psize, A5XX_PC_PRIM_VTX_CNTL_PSIZE);
-
-               OUT_PKT4(ring, REG_A5XX_PC_PRIM_VTX_CNTL, 1);
-               OUT_RING(ring, val);
-       }
-
        if (dirty & FD_DIRTY_SCISSOR) {
                struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
 
@@ -591,7 +558,34 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
        }
 
        if (dirty & FD_DIRTY_PROG)
-               fd5_program_emit(ring, emit);
+               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)) {
+               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);
+
+               OUT_PKT4(ring, REG_A5XX_GRAS_SU_POINT_MINMAX, 2);
+               OUT_RING(ring, rasterizer->gras_su_point_minmax);
+               OUT_RING(ring, rasterizer->gras_su_point_size);
+
+               OUT_PKT4(ring, REG_A5XX_GRAS_SU_POLY_OFFSET_SCALE, 3);
+               OUT_RING(ring, rasterizer->gras_su_poly_offset_scale);
+               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));
+       }
 
        if (dirty & (FD_DIRTY_FRAMEBUFFER | FD_DIRTY_RASTERIZER)) {
                struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
index fffdc14691c2e4c27a259a44afa9b2ca0cc999b5..aa4babdf5b199adde1b8d16f3ee7d2ea78ddff95 100644 (file)
@@ -324,7 +324,8 @@ setup_stages(struct fd5_emit *emit, struct stage *s)
 }
 
 void
-fd5_program_emit(struct fd_ringbuffer *ring, struct fd5_emit *emit)
+fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
+                                struct fd5_emit *emit)
 {
        struct stage s[MAX_STAGES];
        uint32_t pos_regid, psize_regid, color_regid[8];
@@ -539,9 +540,7 @@ fd5_program_emit(struct fd_ringbuffer *ring, struct fd5_emit *emit)
                        COND(s[FS].v->frag_coord, A5XX_VPC_CNTL_0_VARYING) |
                        0x10000);    // XXX
 
-       OUT_PKT4(ring, REG_A5XX_PC_PRIMITIVE_CNTL, 1);
-       OUT_RING(ring, A5XX_PC_PRIMITIVE_CNTL_STRIDE_IN_VPC(l.max_loc) |
-                       0x400);      // XXX
+       fd5_context(ctx)->max_loc = l.max_loc;
 
        if (emit->key.binning_pass) {
                OUT_PKT4(ring, REG_A5XX_SP_FS_OBJ_START_LO, 2);
index 2f82f7f73d37bbbe4ebb233f67578550f1bb67d4..585263e0a87d7f42ad2cc5ebf9a2061e54db2875 100644 (file)
@@ -39,7 +39,8 @@ struct fd5_emit;
 
 void fd5_emit_shader(struct fd_ringbuffer *ring, const struct ir3_shader_variant *so);
 
-void fd5_program_emit(struct fd_ringbuffer *ring, struct fd5_emit *emit);
+void fd5_program_emit(struct fd_context *ctx, struct fd_ringbuffer *ring,
+                                         struct fd5_emit *emit);
 
 void fd5_prog_init(struct pipe_context *pctx);
 
index 822cbb9ee69b2788d9a4f21bd2e70959a07964a1..5fd957835fd223d64f2d24b9db4b4888546b476d 100644 (file)
@@ -83,12 +83,12 @@ fd5_rasterizer_state_create(struct pipe_context *pctx,
                so->gras_su_cntl |= A5XX_GRAS_SU_CNTL_CULL_BACK;
        if (!cso->front_ccw)
                so->gras_su_cntl |= A5XX_GRAS_SU_CNTL_FRONT_CW;
-//     if (!cso->flatshade_first)
-//             so->pc_prim_vtx_cntl |= A5XX_PC_PRIM_VTX_CNTL_PROVOKING_VTX_LAST;
-
        if (cso->offset_tri)
                so->gras_su_cntl |= A5XX_GRAS_SU_CNTL_POLY_OFFSET;
 
+       if (!cso->flatshade_first)
+               so->pc_primitive_cntl |= A5XX_PC_PRIMITIVE_CNTL_PROVOKING_VTX_LAST;
+
 //     if (!cso->depth_clip)
 //             so->gras_cl_clip_cntl |= A5XX_GRAS_CL_CLIP_CNTL_ZNEAR_CLIP_DISABLE |
 //                     A5XX_GRAS_CL_CLIP_CNTL_ZFAR_CLIP_DISABLE;
index 1c8771fb1ba174743740ce9df8a0efbf3b2fd441..f02bf4198bb1bf1b96229499d5bf4526264ab489 100644 (file)
@@ -41,8 +41,7 @@ struct fd5_rasterizer_stateobj {
 
        uint32_t gras_su_cntl;
        uint32_t gras_cl_clip_cntl;
-       uint32_t pc_prim_vtx_cntl;
-       uint32_t pc_prim_vtx_cntl2;
+       uint32_t pc_primitive_cntl;
 };
 
 static inline struct fd5_rasterizer_stateobj *