freedreno/a5xx: provoking vertex

Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Rob Clark 2017-05-17 10:17:10 -04:00
parent d7f296de26
commit 6ccbbd8d05
6 changed files with 40 additions and 44 deletions

View 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 *

View 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;

View 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);

View 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);

View 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;

View 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 *