From 1acc101b3f3886db0f1d456f1e239ef0cdfe5919 Mon Sep 17 00:00:00 2001 From: Ilia Mirkin Date: Fri, 7 Jul 2017 21:10:05 -0400 Subject: [PATCH] a5xx: fix primitive restart Signed-off-by: Ilia Mirkin --- src/gallium/drivers/freedreno/a5xx/a5xx.xml.h | 3 +- src/gallium/drivers/freedreno/a5xx/fd5_emit.c | 32 ++++++++++++------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/freedreno/a5xx/a5xx.xml.h b/src/gallium/drivers/freedreno/a5xx/a5xx.xml.h index 5203799bd2d..ae946d81bd5 100644 --- a/src/gallium/drivers/freedreno/a5xx/a5xx.xml.h +++ b/src/gallium/drivers/freedreno/a5xx/a5xx.xml.h @@ -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 diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c index bede05e9812..2939aaca868 100644 --- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c +++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c @@ -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; -- 2.30.2