[Mesa-dev] [PATCH 03/10] i965: Create a helper function for emitting PIPE_CONTROL flushes.

Eric Anholt eric at anholt.net
Thu Jan 9 19:52:47 PST 2014


Kenneth Graunke <kenneth at whitecape.org> writes:

> These days, we need to emit PIPE_CONTROL flushes all over the place.
> Being able to do that via a single function call seems convenient.
>
> Broadwell will also increase the length of these packets by 1; with the
> refactoring, we should have to do this in substantially fewer places.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>

> diff --git a/src/mesa/drivers/dri/i965/intel_batchbuffer.c b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
> index d9b6c15..d2f0e90 100644
> --- a/src/mesa/drivers/dri/i965/intel_batchbuffer.c
> +++ b/src/mesa/drivers/dri/i965/intel_batchbuffer.c
> @@ -475,6 +475,32 @@ emit:
>  }
>  
>  /**
> + * Emit a PIPE_CONTROL with various flushing flags.
> + *
> + * The caller is responsible for deciding what flags are appropriate for the
> + * given generation.
> + */
> +void
> +brw_emit_pipe_control_flush(struct brw_context *brw, uint32_t flags)
> +{
> +   if (brw->gen >= 6) {
> +      BEGIN_BATCH(4);
> +      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> +      OUT_BATCH(flags);
> +      OUT_BATCH(0);
> +      OUT_BATCH(0);
> +      ADVANCE_BATCH();
> +   } else {
> +      BEGIN_BATCH(4);
> +      OUT_BATCH(_3DSTATE_PIPE_CONTROL | flags | (4 - 2));
> +      OUT_BATCH(0);
> +      OUT_BATCH(0);
> +      OUT_BATCH(0);
> +      ADVANCE_BATCH();
> +   }
> +}
> +
> +/**
>   * Restriction [DevSNB, DevIVB]:
>   *
>   * Prior to changing Depth/Stencil Buffer state (i.e. any combination of
> @@ -491,26 +517,9 @@ intel_emit_depth_stall_flushes(struct brw_context *brw)
>  {
>     assert(brw->gen >= 6 && brw->gen <= 7);
>  
> -   BEGIN_BATCH(4);
> -   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> -   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
> -   OUT_BATCH(0); /* address */
> -   OUT_BATCH(0); /* write data */
> -   ADVANCE_BATCH()
> -
> -   BEGIN_BATCH(4);
> -   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> -   OUT_BATCH(PIPE_CONTROL_DEPTH_CACHE_FLUSH);
> -   OUT_BATCH(0); /* address */
> -   OUT_BATCH(0); /* write data */
> -   ADVANCE_BATCH();
> -
> -   BEGIN_BATCH(4);
> -   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> -   OUT_BATCH(PIPE_CONTROL_DEPTH_STALL);
> -   OUT_BATCH(0); /* address */
> -   OUT_BATCH(0); /* write data */
> -   ADVANCE_BATCH();
> +   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_STALL);
> +   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_CACHE_FLUSH);
> +   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_DEPTH_STALL);
>  }
>  
>  /**
> @@ -608,13 +617,8 @@ intel_emit_post_sync_nonzero_flush(struct brw_context *brw)
>     if (!brw->batch.need_workaround_flush)
>        return;
>  
> -   BEGIN_BATCH(4);
> -   OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> -   OUT_BATCH(PIPE_CONTROL_CS_STALL |
> -	     PIPE_CONTROL_STALL_AT_SCOREBOARD);
> -   OUT_BATCH(0); /* address */
> -   OUT_BATCH(0); /* write data */
> -   ADVANCE_BATCH();
> +   brw_emit_pipe_control_flush(brw, PIPE_CONTROL_CS_STALL |
> +                               PIPE_CONTROL_STALL_AT_SCOREBOARD);
>  
>     BEGIN_BATCH(4);
>     OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> @@ -636,46 +640,22 @@ intel_emit_post_sync_nonzero_flush(struct brw_context *brw)
>  void
>  intel_batchbuffer_emit_mi_flush(struct brw_context *brw)
>  {
> -   if (brw->gen >= 6) {
> -      if (brw->batch.ring == BLT_RING) {
> -	 BEGIN_BATCH_BLT(4);
> -	 OUT_BATCH(MI_FLUSH_DW);
> -	 OUT_BATCH(0);
> -	 OUT_BATCH(0);
> -	 OUT_BATCH(0);
> -	 ADVANCE_BATCH();
> -      } else {
> -	 if (brw->gen == 6) {
> -	    /* Hardware workaround: SNB B-Spec says:
> -	     *
> -	     * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache
> -	     * Flush Enable =1, a PIPE_CONTROL with any non-zero
> -	     * post-sync-op is required.
> -	     */
> -	    intel_emit_post_sync_nonzero_flush(brw);
> -	 }
> -
> -	 BEGIN_BATCH(4);
> -	 OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2));
> -	 OUT_BATCH(PIPE_CONTROL_INSTRUCTION_FLUSH |
> -		   PIPE_CONTROL_WRITE_FLUSH |
> -		   PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> -                   PIPE_CONTROL_VF_CACHE_INVALIDATE |
> -		   PIPE_CONTROL_TC_FLUSH |
> -		   PIPE_CONTROL_NO_WRITE |
> -                   PIPE_CONTROL_CS_STALL);
> -	 OUT_BATCH(0); /* write address */
> -	 OUT_BATCH(0); /* write data */
> -	 ADVANCE_BATCH();
> -      }
> -   } else {
> -      BEGIN_BATCH(4);
> -      OUT_BATCH(_3DSTATE_PIPE_CONTROL | (4 - 2) |
> -		PIPE_CONTROL_WRITE_FLUSH |
> -		PIPE_CONTROL_NO_WRITE);
> -      OUT_BATCH(0); /* write address */
> -      OUT_BATCH(0); /* write data */
> -      OUT_BATCH(0); /* write data */
> +   if (unlikely(brw->batch.ring == BLT_RING) && brw->gen >= 6) {
> +      BEGIN_BATCH_BLT(4);
> +      OUT_BATCH(MI_FLUSH_DW);
> +      OUT_BATCH(0);
> +      OUT_BATCH(0);
> +      OUT_BATCH(0);
>        ADVANCE_BATCH();

This shouldn't be marked unlikely.  You should use unlikely for "this
path should be never executed in a performance-sensitive way", not just
"I bet this will be used a bit less frequently than the alternative."
(the compiler does more than just try to hint branch prediction using
this information)

> +   } else {
> +      int flags = PIPE_CONTROL_NO_WRITE | PIPE_CONTROL_WRITE_FLUSH;
> +      if (brw->gen >= 6) {
> +         flags |= PIPE_CONTROL_INSTRUCTION_FLUSH |
> +                  PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> +                  PIPE_CONTROL_VF_CACHE_INVALIDATE |
> +                  PIPE_CONTROL_TC_FLUSH |
> +                  PIPE_CONTROL_CS_STALL;
> +      }

Lost the emit_post_sync_nonzero_flush() from the previous code.

> +      brw_emit_pipe_control_flush(brw, flags);
>     }
>  }

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20140110/24001885/attachment.pgp>


More information about the mesa-dev mailing list