[Mesa-dev] [PATCH] r600g/compute: Emit DEALLOC_STATE on cayman after dispatching a compute shader.

Alex Deucher alexdeucher at gmail.com
Mon Jan 27 06:19:52 PST 2014


On Mon, Jan 27, 2014 at 9:05 AM, Tom Stellard <tom at stellard.net> wrote:
> From: Tom Stellard <thomas.stellard at amd.com>
>
> This is necessary to prevent the next SURFACE_SYNC packet from
> hanging the GPU.
>
> https://bugs.freedesktop.org/show_bug.cgi?id=73418
>
> CC: "9.2" "10.0" <mesa-stable at lists.freedesktop.org>


Reviewed-by: Alex Deucher <alexander.deucher at amd.com>

> ---
>  src/gallium/drivers/r600/evergreen_compute.c |  9 ++++++++-
>  src/gallium/drivers/r600/evergreend.h        |  1 +
>  src/gallium/drivers/r600/r600_hw_context.c   |  4 +---
>  src/gallium/drivers/r600/r600_pipe.h         | 10 ----------
>  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 a2db69b..70efe5c 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 2f2e145..9ba3db7 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 da90d63..7afd4b0 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 7350479..88b0860 100644
> --- a/src/gallium/drivers/r600/r600_pipe.h
> +++ b/src/gallium/drivers/r600/r600_pipe.h
> @@ -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,
> --
> 1.8.1.5
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list