From 6ccbbd8d0545d3a8ef15eb151a3a6efce153dfc9 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 17 May 2017 10:17:10 -0400 Subject: [PATCH] freedreno/a5xx: provoking vertex Signed-off-by: Rob Clark --- .../drivers/freedreno/a5xx/fd5_context.h | 3 + src/gallium/drivers/freedreno/a5xx/fd5_emit.c | 62 +++++++++---------- .../drivers/freedreno/a5xx/fd5_program.c | 7 +-- .../drivers/freedreno/a5xx/fd5_program.h | 3 +- .../drivers/freedreno/a5xx/fd5_rasterizer.c | 6 +- .../drivers/freedreno/a5xx/fd5_rasterizer.h | 3 +- 6 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_context.h b/src/gallium/drivers/freedreno/a5xx/fd5_context.h index c8db470f71a..f6de6ca2ae6 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_context.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_context.h @@ -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 * diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index d959f09fc20..73684c9f900 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -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; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_program.c b/src/gallium/drivers/freedreno/a5xx/fd5_program.c index fffdc14691c..aa4babdf5b1 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_program.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_program.c @@ -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); diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_program.h b/src/gallium/drivers/freedreno/a5xx/fd5_program.h index 2f82f7f73d3..585263e0a87 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_program.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_program.h @@ -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); diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.c b/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.c index 822cbb9ee69..5fd957835fd 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.c @@ -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; diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.h b/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.h index 1c8771fb1ba..f02bf4198bb 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.h +++ b/src/gallium/drivers/freedreno/a5xx/fd5_rasterizer.h @@ -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 * -- 2.30.2