radeonsi: add reg shadowing codepaths to GS and tess ring setup
authorMarek Olšák <marek.olsak@amd.com>
Tue, 16 Jun 2020 18:01:16 +0000 (14:01 -0400)
committerMarek Olšák <marek.olsak@amd.com>
Wed, 22 Jul 2020 16:08:33 +0000 (12:08 -0400)
Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5798>

src/gallium/drivers/radeonsi/si_state_shaders.c

index 3d3c688fbb1d1269d39781f6d55275aec54f2c4f..a3712ed96da797e4f170a547f66af3bb99338049 100644 (file)
@@ -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. */