r600g/compute: Emit DEALLOC_STATE on cayman after dispatching a compute shader.
authorTom Stellard <thomas.stellard@amd.com>
Fri, 24 Jan 2014 20:48:26 +0000 (15:48 -0500)
committerTom Stellard <thomas.stellard@amd.com>
Mon, 27 Jan 2014 16:09:15 +0000 (11:09 -0500)
This is necessary to prevent the next SURFACE_SYNC packet from
hanging the GPU.

https://bugs.freedesktop.org/show_bug.cgi?id=73418

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
CC: "9.2" "10.0" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/r600/evergreen_compute.c
src/gallium/drivers/r600/evergreend.h
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h

index a2db69b6fac441b745f771fba96289bf56a7e53a..70efe5c5a8731fd65c01a976cda2c54ac1f765a8 100644 (file)
@@ -489,7 +489,14 @@ static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
        ctx->b.flags = 0;
 
        if (ctx->b.chip_class >= CAYMAN) {
-               ctx->skip_surface_sync_on_next_cs_flush = true;
+               cs->buf[cs->cdw++] = PKT3(PKT3_EVENT_WRITE, 0, 0);
+               cs->buf[cs->cdw++] = EVENT_TYPE(EVENT_TYPE_CS_PARTIAL_FLUSH) | EVENT_INDEX(4);
+               /* DEALLOC_STATE prevents the GPU from hanging when a
+                * SURFACE_SYNC packet is emitted some time after a DISPATCH_DIRECT
+                * with any of the CB*_DEST_BASE_ENA or DB_DEST_BASE_ENA bits set.
+                */
+               cs->buf[cs->cdw++] = PKT3C(PKT3_DEALLOC_STATE, 0, 0);
+               cs->buf[cs->cdw++] = 0;
        }
 
 #if 0
index 2f2e1455d590c208feeba5c16e7f40e14c8f3421..9ba3db7847c93e6845b16a5a71272bcecb5fd082 100644 (file)
@@ -63,6 +63,7 @@
 #define R600_TEXEL_PITCH_ALIGNMENT_MASK        0x7
 
 #define PKT3_NOP                               0x10
+#define PKT3_DEALLOC_STATE                     0x14
 #define PKT3_DISPATCH_DIRECT                   0x15
 #define PKT3_DISPATCH_INDIRECT                 0x16
 #define PKT3_INDIRECT_BUFFER_END               0x17
index da90d631633f431e47e28ddaeb82531bf801e318..7afd4b0099f49c138f5645988ca052dff4388304 100644 (file)
@@ -293,7 +293,7 @@ void r600_flush_emit(struct r600_context *rctx)
                                S_0085F0_SMX_ACTION_ENA(1);
        }
 
-       if (cp_coher_cntl && !rctx->skip_surface_sync_on_next_cs_flush) {
+       if (cp_coher_cntl) {
                cs->buf[cs->cdw++] = PKT3(PKT3_SURFACE_SYNC, 3, 0);
                cs->buf[cs->cdw++] = cp_coher_cntl;   /* CP_COHER_CNTL */
                cs->buf[cs->cdw++] = 0xffffffff;      /* CP_COHER_SIZE */
@@ -354,8 +354,6 @@ void r600_context_flush(struct r600_context *ctx, unsigned flags)
 
        /* Flush the CS. */
        ctx->b.ws->cs_flush(ctx->b.rings.gfx.cs, flags, ctx->screen->cs_count++);
-
-       ctx->skip_surface_sync_on_next_cs_flush = false;
 }
 
 void r600_begin_new_cs(struct r600_context *ctx)
index 735047920ff1b7a0fa7a6e4aedec6019c059d8ae..88b0860494058f2cf498ac2dcf90ab802938ce7c 100644 (file)
@@ -499,16 +499,6 @@ struct r600_context {
 
        void                            *sb_context;
        struct r600_isa         *isa;
-
-       /* Work-around for flushing problems with compute shaders on Cayman:
-        * Emitting a SURFACE_SYNC packet with any of the CB*_DEST_BASE_ENA
-        * or DB_DEST_BASE_ENA bits set after dispatching a compute shader
-        * hangs the GPU.
-        *
-        * Setting this to true will prevent r600_flush_emit() from emitting
-        * a SURFACE_SYNC packet.  This field will be cleared by
-        * by r600_context_flush() after flushing the command stream. */
-       boolean                         skip_surface_sync_on_next_cs_flush;
 };
 
 static INLINE void r600_emit_command_buffer(struct radeon_winsys_cs *cs,