From 17e16ba9db2aef353babd84bfe9d874bbbc59c6a Mon Sep 17 00:00:00 2001 From: Jonathan Marek Date: Thu, 21 Jun 2018 17:06:27 -0400 Subject: [PATCH] freedreno: add a20x this patch adds support for a20x, which has some differences with a220: -no VGT_MAX_VTX_INDX register -no CLEAR_COLOR register -set RB_BC_CONTROL in restore (hangs without) -different CP_DRAW_INDX format tested with kmscube and glmark2 scenes, on par with a220 Signed-off-by: Jonathan Marek Signed-off-by: Rob Clark --- src/gallium/drivers/freedreno/a2xx/fd2_draw.c | 37 +++++++++++++------ src/gallium/drivers/freedreno/a2xx/fd2_emit.c | 10 +++++ src/gallium/drivers/freedreno/a2xx/fd2_gmem.c | 22 ++++++----- .../drivers/freedreno/freedreno_draw.h | 27 +++++++++----- .../drivers/freedreno/freedreno_screen.c | 1 + .../drivers/freedreno/freedreno_screen.h | 6 +++ .../drivers/freedreno/freedreno_util.h | 13 +++++++ 7 files changed, 85 insertions(+), 31 deletions(-) diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c index 8df1793a35f..ca634d794ad 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_draw.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_draw.c @@ -101,12 +101,14 @@ fd2_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info, OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1); OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE); - OUT_WFI (ring); + if (!is_a20x(ctx->screen)) { + OUT_WFI (ring); - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); - OUT_RING(ring, info->max_index); /* VGT_MAX_VTX_INDX */ - OUT_RING(ring, info->min_index); /* VGT_MIN_VTX_INDX */ + OUT_PKT3(ring, CP_SET_CONSTANT, 3); + OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); + OUT_RING(ring, info->max_index); /* VGT_MAX_VTX_INDX */ + OUT_RING(ring, info->min_index); /* VGT_MIN_VTX_INDX */ + } fd_draw_emit(ctx->batch, ring, ctx->primtypes[info->mode], IGNORE_VISIBILITY, info, index_offset); @@ -157,9 +159,18 @@ fd2_clear(struct fd_context *ctx, unsigned buffers, OUT_PKT0(ring, REG_A2XX_TC_CNTL_STATUS, 1); OUT_RING(ring, A2XX_TC_CNTL_STATUS_L2_INVALIDATE); - OUT_PKT3(ring, CP_SET_CONSTANT, 2); - OUT_RING(ring, CP_REG(REG_A2XX_CLEAR_COLOR)); - OUT_RING(ring, colr); + if (is_a20x(ctx->screen)) { + OUT_PKT3(ring, CP_SET_CONSTANT, 5); + OUT_RING(ring, 0x00000480); + OUT_RING(ring, color->ui[0]); + OUT_RING(ring, color->ui[1]); + OUT_RING(ring, color->ui[2]); + OUT_RING(ring, color->ui[3]); + } else { + OUT_PKT3(ring, CP_SET_CONSTANT, 2); + OUT_RING(ring, CP_REG(REG_A2XX_CLEAR_COLOR)); + OUT_RING(ring, colr); + } OUT_PKT3(ring, CP_SET_CONSTANT, 2); OUT_RING(ring, CP_REG(REG_A2XX_A220_RB_LRZ_VSC_CONTROL)); @@ -264,10 +275,12 @@ fd2_clear(struct fd_context *ctx, unsigned buffers, OUT_RING(ring, 0x0); } - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); - OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ - OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ + if (!is_a20x(ctx->screen)) { + OUT_PKT3(ring, CP_SET_CONSTANT, 3); + OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); + OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ + OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ + } fd_draw(ctx->batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL); diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c index d749eb0324a..4bf41b2c678 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_emit.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_emit.c @@ -332,6 +332,16 @@ fd2_emit_state(struct fd_context *ctx, const enum fd_dirty_3d_state dirty) void fd2_emit_restore(struct fd_context *ctx, struct fd_ringbuffer *ring) { + if (is_a20x(ctx->screen)) { + OUT_PKT0(ring, REG_A2XX_RB_BC_CONTROL, 1); + OUT_RING(ring, + A2XX_RB_BC_CONTROL_ACCUM_TIMEOUT_SELECT(3) | + A2XX_RB_BC_CONTROL_DISABLE_LZ_NULL_ZCMD_DROP | + A2XX_RB_BC_CONTROL_ENABLE_CRC_UPDATE | + A2XX_RB_BC_CONTROL_ACCUM_DATA_FIFO_LIMIT(8) | + A2XX_RB_BC_CONTROL_MEM_EXPORT_TIMEOUT_SELECT(3)); + } + OUT_PKT0(ring, REG_A2XX_TP0_CHICKEN, 1); OUT_RING(ring, 0x00000002); diff --git a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c index 46a7d18ef09..62382995c09 100644 --- a/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c +++ b/src/gallium/drivers/freedreno/a2xx/fd2_gmem.c @@ -89,12 +89,14 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base, A2XX_RB_COPY_DEST_INFO_WRITE_BLUE | A2XX_RB_COPY_DEST_INFO_WRITE_ALPHA); - OUT_WFI (ring); + if (!is_a20x(batch->ctx->screen)) { + OUT_WFI (ring); - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); - OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ - OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ + OUT_PKT3(ring, CP_SET_CONSTANT, 3); + OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); + OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ + OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ + } fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL); @@ -214,10 +216,12 @@ emit_mem2gmem_surf(struct fd_batch *batch, uint32_t base, OUT_RING(ring, 0x00000000); OUT_RING(ring, 0x00000200); - OUT_PKT3(ring, CP_SET_CONSTANT, 3); - OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); - OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ - OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ + if (!is_a20x(batch->ctx->screen)) { + OUT_PKT3(ring, CP_SET_CONSTANT, 3); + OUT_RING(ring, CP_REG(REG_A2XX_VGT_MAX_VTX_INDX)); + OUT_RING(ring, 3); /* VGT_MAX_VTX_INDX */ + OUT_RING(ring, 0); /* VGT_MIN_VTX_INDX */ + } fd_draw(batch, ring, DI_PT_RECTLIST, IGNORE_VISIBILITY, DI_SRC_SEL_AUTO_INDEX, 3, 0, INDEX_SIZE_IGN, 0, 0, NULL); diff --git a/src/gallium/drivers/freedreno/freedreno_draw.h b/src/gallium/drivers/freedreno/freedreno_draw.h index b293f73b82e..4a922d9ca3b 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.h +++ b/src/gallium/drivers/freedreno/freedreno_draw.h @@ -74,18 +74,25 @@ fd_draw(struct fd_batch *batch, struct fd_ringbuffer *ring, OUT_RING(ring, 0); } - OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 5 : 3); - OUT_RING(ring, 0x00000000); /* viz query info. */ - if (vismode == USE_VISIBILITY) { - /* leave vis mode blank for now, it will be patched up when - * we know if we are binning or not - */ - OUT_RINGP(ring, DRAW(primtype, src_sel, idx_type, 0, instances), - &batch->draw_patches); + if (is_a20x(batch->ctx->screen)) { + OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 4 : 2); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, DRAW_A20X(primtype, src_sel, idx_type, vismode, count)); } else { - OUT_RING(ring, DRAW(primtype, src_sel, idx_type, vismode, instances)); + OUT_PKT3(ring, CP_DRAW_INDX, idx_buffer ? 5 : 3); + OUT_RING(ring, 0x00000000); /* viz query info. */ + if (vismode == USE_VISIBILITY) { + /* leave vis mode blank for now, it will be patched up when + * we know if we are binning or not + */ + OUT_RINGP(ring, DRAW(primtype, src_sel, idx_type, 0, instances), + &batch->draw_patches); + } else { + OUT_RING(ring, DRAW(primtype, src_sel, idx_type, vismode, instances)); + } + OUT_RING(ring, count); /* NumIndices */ } - OUT_RING(ring, count); /* NumIndices */ + if (idx_buffer) { OUT_RELOC(ring, fd_resource(idx_buffer)->bo, idx_offset, 0, 0); OUT_RING (ring, idx_size); diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index 2e842a8da7d..042e0384f1a 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -875,6 +875,7 @@ fd_screen_create(struct fd_device *dev) * send a patch ;-) */ switch (screen->gpu_id) { + case 205: case 220: fd2_screen_init(pscreen); break; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 6be739ae287..013dba1a6d3 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -106,6 +106,12 @@ struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen, struct pipe_screen * fd_screen_create(struct fd_device *dev); +static inline boolean +is_a20x(struct fd_screen *screen) +{ + return (screen->gpu_id >= 200) && (screen->gpu_id < 210); +} + /* is a3xx patch revision 0? */ /* TODO a306.0 probably doesn't need this.. be more clever?? */ static inline boolean diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h index 9645561e071..cdac08be6e2 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.h +++ b/src/gallium/drivers/freedreno/freedreno_util.h @@ -112,6 +112,19 @@ static inline uint32_t DRAW(enum pc_di_primtype prim_type, (instances << 24); } +static inline uint32_t DRAW_A20X(enum pc_di_primtype prim_type, + enum pc_di_src_sel source_select, enum pc_di_index_size index_size, + enum pc_di_vis_cull_mode vis_cull_mode, + uint16_t count) +{ + return (prim_type << 0) | + (source_select << 6) | + ((index_size & 1) << 11) | + ((index_size >> 1) << 13) | + (vis_cull_mode << 9) | + (count << 16); +} + /* for tracking cmdstream positions that need to be patched: */ struct fd_cs_patch { uint32_t *cs; -- 2.30.2