tradeonsi: fix preamble state producing incorrect packets
authorPierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Fri, 10 Jun 2022 08:44:39 +0000 (10:44 +0200)
committerMarge Bot <emma+marge@anholt.net>
Fri, 10 Jun 2022 17:40:18 +0000 (17:40 +0000)
If the first time the preamble is written, one of the rings
isn't allocated, we wouldn't write the RING_SIZE to the preamble.

Later, when the preamble gets updated after the ring allocation,
the new RING_SIZE packet would overwrite other packets.

To prevent this, always write the RING_SIZE (the alternative would
be to write NOP packets).

This fix "*ERROR* Illegal register access in command stream" hangs
I observed on GFX8.

Fixes: 32c7805ccca ("radeonsi: merge all preamble states into one")
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16962>

src/gallium/drivers/radeonsi/si_state_shaders.cpp

index 85c0bca..6f09ce4 100644 (file)
@@ -3832,18 +3832,19 @@ bool si_update_gs_ring_buffers(struct si_context *sctx)
          pm4->ndw = *gs_ring_state_dw_offset;
       }
 
+      /* Unallocated rings are written to reserve the space in the pm4
+       * (to be able to overwrite them later). */
       if (sctx->gfx_level >= GFX7) {
-         if (sctx->esgs_ring) {
-            assert(sctx->gfx_level <= GFX8);
-            si_pm4_set_reg(pm4, R_030900_VGT_ESGS_RING_SIZE, sctx->esgs_ring->width0 / 256);
-         }
-         if (sctx->gsvs_ring)
-            si_pm4_set_reg(pm4, R_030904_VGT_GSVS_RING_SIZE, sctx->gsvs_ring->width0 / 256);
+         if (sctx->gfx_level <= GFX8)
+            si_pm4_set_reg(pm4, R_030900_VGT_ESGS_RING_SIZE,
+                           sctx->esgs_ring ? sctx->esgs_ring->width0 / 256 : 0);
+         si_pm4_set_reg(pm4, R_030904_VGT_GSVS_RING_SIZE,
+                        sctx->gsvs_ring ? sctx->gsvs_ring->width0 / 256 : 0);
       } else {
-         if (sctx->esgs_ring)
-            si_pm4_set_reg(pm4, R_0088C8_VGT_ESGS_RING_SIZE, sctx->esgs_ring->width0 / 256);
-         if (sctx->gsvs_ring)
-            si_pm4_set_reg(pm4, R_0088CC_VGT_GSVS_RING_SIZE, sctx->gsvs_ring->width0 / 256);
+         si_pm4_set_reg(pm4, R_0088C8_VGT_ESGS_RING_SIZE,
+                        sctx->esgs_ring ? sctx->esgs_ring->width0 / 256 : 0);
+         si_pm4_set_reg(pm4, R_0088CC_VGT_GSVS_RING_SIZE,
+                        sctx->gsvs_ring ? sctx->gsvs_ring->width0 / 256 : 0);
       }
 
       if (old_ndw) {