From 8af0f91fd379ab696e32f9fbdd3e3983b3323288 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 16 Jun 2020 14:01:16 -0400 Subject: radeonsi: add reg shadowing codepaths to GS and tess ring setup Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- src/gallium/drivers/radeonsi/si_state_shaders.c | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index 3d3c688fbb1..a3712ed96da 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -3298,6 +3298,9 @@ static void si_emit_spi_map(struct si_context *sctx) */ static void si_cs_preamble_add_vgt_flush(struct si_context *sctx) { + /* We shouldn't get here if registers are shadowed. */ + assert(!sctx->shadowed_regs); + if (sctx->cs_preamble_has_vgt_flush) return; @@ -3311,6 +3314,20 @@ static void si_cs_preamble_add_vgt_flush(struct si_context *sctx) sctx->cs_preamble_has_vgt_flush = true; } +/** + * Writing CONFIG or UCONFIG VGT registers requires VGT_FLUSH before that. + */ +static void si_emit_vgt_flush(struct radeon_cmdbuf *cs) +{ + /* This is required before VGT_FLUSH. */ + radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); + radeon_emit(cs, EVENT_TYPE(V_028A90_VS_PARTIAL_FLUSH) | EVENT_INDEX(4)); + + /* VGT_FLUSH is required even if VGT is idle. It resets VGT pointers. */ + radeon_emit(cs, PKT3(PKT3_EVENT_WRITE, 0, 0)); + radeon_emit(cs, EVENT_TYPE(V_028A90_VGT_FLUSH) | EVENT_INDEX(0)); +} + /* Initialize state related to ESGS / GSVS ring buffers */ static bool si_update_gs_ring_buffers(struct si_context *sctx) { @@ -3390,6 +3407,28 @@ static bool si_update_gs_ring_buffers(struct si_context *sctx) false, 0, 0, 0); } + if (sctx->shadowed_regs) { + /* These registers will be shadowed, so set them only once. */ + struct radeon_cmdbuf *cs = sctx->gfx_cs; + + assert(sctx->chip_class >= GFX7); + + si_emit_vgt_flush(cs); + + /* Set the GS registers. */ + if (sctx->esgs_ring) { + assert(sctx->chip_class <= GFX8); + radeon_set_uconfig_reg(cs, R_030900_VGT_ESGS_RING_SIZE, + sctx->esgs_ring->width0 / 256); + } + if (sctx->gsvs_ring) { + radeon_set_uconfig_reg(cs, R_030904_VGT_GSVS_RING_SIZE, + sctx->gsvs_ring->width0 / 256); + } + return true; + } + + /* The codepath without register shadowing. */ /* Create the "cs_preamble_gs_rings" state. */ pm4 = CALLOC_STRUCT(si_pm4_state); if (!pm4) @@ -3638,6 +3677,33 @@ static void si_init_tess_factor_ring(struct si_context *sctx) uint64_t factor_va = si_resource(sctx->tess_rings)->gpu_address + sctx->screen->tess_offchip_ring_size; + if (sctx->shadowed_regs) { + /* These registers will be shadowed, so set them only once. */ + struct radeon_cmdbuf *cs = sctx->gfx_cs; + + assert(sctx->chip_class >= GFX7); + + radeon_add_to_buffer_list(sctx, sctx->gfx_cs, si_resource(sctx->tess_rings), + RADEON_USAGE_READWRITE, RADEON_PRIO_SHADER_RINGS); + si_emit_vgt_flush(cs); + + /* Set tessellation registers. */ + radeon_set_uconfig_reg(cs, R_030938_VGT_TF_RING_SIZE, + S_030938_SIZE(sctx->screen->tess_factor_ring_size / 4)); + radeon_set_uconfig_reg(cs, R_030940_VGT_TF_MEMORY_BASE, factor_va >> 8); + if (sctx->chip_class >= GFX10) { + radeon_set_uconfig_reg(cs, R_030984_VGT_TF_MEMORY_BASE_HI_UMD, + S_030984_BASE_HI(factor_va >> 40)); + } else if (sctx->chip_class == GFX9) { + radeon_set_uconfig_reg(cs, R_030944_VGT_TF_MEMORY_BASE_HI, + S_030944_BASE_HI(factor_va >> 40)); + } + radeon_set_uconfig_reg(cs, R_03093C_VGT_HS_OFFCHIP_PARAM, + sctx->screen->vgt_hs_offchip_param); + return; + } + + /* The codepath without register shadowing. */ si_cs_preamble_add_vgt_flush(sctx); /* Append these registers to the init config state. */ -- cgit v1.2.3