r600g/compute: Add a work-around for flushing issues on Cayman
authorTom Stellard <thomas.stellard@amd.com>
Wed, 20 Nov 2013 03:05:52 +0000 (22:05 -0500)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 21 Nov 2013 23:55:16 +0000 (15:55 -0800)
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
https://bugs.freedesktop.org/show_bug.cgi?id=69321

CC: "10.0" <mesa-stable@lists.freedesktop.org>
src/gallium/drivers/r600/evergreen_compute.c
src/gallium/drivers/r600/r600_hw_context.c
src/gallium/drivers/r600/r600_pipe.h

index ffdc5c3b4541284c7bd7bc5186446724fd2e450c..d668c8e27462c524e97017cd7269b52c0bb271db 100644 (file)
@@ -474,6 +474,10 @@ static void compute_emit_cs(struct r600_context *ctx, const uint *block_layout,
        r600_flush_emit(ctx);
        ctx->b.flags = 0;
 
+       if (ctx->b.chip_class >= CAYMAN) {
+               ctx->skip_surface_sync_on_next_cs_flush = true;
+       }
+
 #if 0
        COMPUTE_DBG(ctx->screen, "cdw: %i\n", cs->cdw);
        for (i = 0; i < cs->cdw; i++) {
index 5f3a9bd5d7bc9062c811cfd1e8b5128de8b97d53..191a81dab42424f25cda4aa7a504ab2deb8c51a2 100644 (file)
@@ -293,7 +293,7 @@ void r600_flush_emit(struct r600_context *rctx)
                                S_0085F0_SMX_ACTION_ENA(1);
        }
 
-       if (cp_coher_cntl) {
+       if (cp_coher_cntl && !rctx->skip_surface_sync_on_next_cs_flush) {
                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,6 +354,8 @@ 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 d7af618064164fb645f6ef8b26506753827acab8..f0d4be481420e0453d2dd4dc044f59890a40d192 100644 (file)
@@ -507,6 +507,16 @@ 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,