diff options
author | Tom Stellard <[email protected]> | 2013-11-19 22:05:52 -0500 |
---|---|---|
committer | Tom Stellard <[email protected]> | 2013-11-21 15:55:16 -0800 |
commit | 7a30cd7085b6879d3858f5c1a6945fbe30c818a6 (patch) | |
tree | 2d1d76e52dfd83a9cabacf4a404f5034ac4dcbed | |
parent | 544e3129c5addeb6c9539339782dd54616ef0499 (diff) |
r600g/compute: Add a work-around for flushing issues on Cayman
Reviewed-by: Alex Deucher <[email protected]>
Reviewed-by: Marek Olšák <[email protected]>
https://bugs.freedesktop.org/show_bug.cgi?id=69321
CC: "10.0" <[email protected]>
-rw-r--r-- | src/gallium/drivers/r600/evergreen_compute.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_hw_context.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 10 |
3 files changed, 17 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c index ffdc5c3b454..d668c8e2746 100644 --- a/src/gallium/drivers/r600/evergreen_compute.c +++ b/src/gallium/drivers/r600/evergreen_compute.c @@ -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++) { diff --git a/src/gallium/drivers/r600/r600_hw_context.c b/src/gallium/drivers/r600/r600_hw_context.c index 5f3a9bd5d7b..191a81dab42 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) { + 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) diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index d7af6180641..f0d4be48142 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -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, |