summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2014-01-24 15:48:26 -0500
committerCarl Worth <cworth@cworth.org>2014-01-28 13:21:25 -0800
commit6f27353c202885f819d7e0aac60f43ba109d85d8 (patch)
treecae7091c55d6a9d0c5e6dab4b0f14928a5694751
parent99f695f716ef69b78204625cffcffe1b745a6c0e (diff)
r600g/compute: Emit DEALLOC_STATE on cayman after dispatching a compute shader.
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> (cherry picked from commit d51dbe048afd2131eb3675e9cd868ce73325a61d)
-rw-r--r--src/gallium/drivers/r600/evergreen_compute.c9
-rw-r--r--src/gallium/drivers/r600/evergreend.h1
-rw-r--r--src/gallium/drivers/r600/r600_hw_context.c4
-rw-r--r--src/gallium/drivers/r600/r600_pipe.h10
4 files changed, 10 insertions, 14 deletions
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 251021c6d9c..4492919ddfe 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -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
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index 2f2e1455d59..9ba3db7847c 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -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
diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c
index 191a81dab42..5f3a9bd5d7b 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -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)
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index f0d4be48142..d7af6180641 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -507,16 +507,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,