*/
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;
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)
{
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)
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. */