[Mesa-dev] [PATCH v2 4/6] i965/blit: Break blits into chunks in set_alpha_to_one

Pohjolainen, Topi topi.pohjolainen at gmail.com
Tue Oct 25 20:43:59 UTC 2016


On Mon, Oct 24, 2016 at 08:40:44PM -0700, Jason Ekstrand wrote:
> v2: Properly handle linear blit alignment restrictions
> 
> Signed-off-by: Jason Ekstrand <jason at jlekstrand.net>
> ---
>  src/mesa/drivers/dri/i965/intel_blit.c | 88 ++++++++++++++++++++++++++++------
>  1 file changed, 73 insertions(+), 15 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/intel_blit.c b/src/mesa/drivers/dri/i965/intel_blit.c
> index bc97e66..02a1fd9 100644
> --- a/src/mesa/drivers/dri/i965/intel_blit.c
> +++ b/src/mesa/drivers/dri/i965/intel_blit.c
> @@ -179,6 +179,42 @@ intel_miptree_blit_compatible_formats(mesa_format src, mesa_format dst)
>     return false;
>  }
>  
> +static void
> +get_blit_intratile_offset_el(const struct brw_context *brw,
> +                             struct intel_mipmap_tree *mt,
> +                             uint32_t total_x_offset_el,
> +                             uint32_t total_y_offset_el,
> +                             uint32_t *base_address_offset,
> +                             uint32_t *x_offset_el,
> +                             uint32_t *y_offset_el)
> +{
> +   enum isl_tiling tiling = intel_miptree_get_isl_tiling(mt);
> +   isl_tiling_get_intratile_offset_el(&brw->isl_dev,
> +                                      tiling, mt->cpp, mt->pitch,
> +                                      total_x_offset_el, total_y_offset_el,
> +                                      base_address_offset,
> +                                      x_offset_el, y_offset_el);
> +   if (tiling == ISL_TILING_LINEAR) {
> +      /* From the Broadwell PRM docs for XY_SRC_COPY_BLT::SourceBaseAddress:
> +       *
> +       *    "Base address of the destination surface: X=0, Y=0. Lower 32bits
> +       *    of the 48bit addressing. When Src Tiling is enabled (Bit_15
> +       *    enabled), this address must be 4KB-aligned. When Tiling is not
> +       *    enabled, this address should be CL (64byte) aligned."
> +       *
> +       * The offsets we get from ISL in the tiled case are already aligned.
> +       * In the linear case, we need to do some of our own aligning.
> +       */
> +      assert(mt->pitch % 64 == 0);
> +      uint32_t delta = *base_address_offset & 63;

Could be const. Series looks good to me:

Reviewed-by: Topi Pohjolainen <topi.pohjolainen at intel.com>

> +      assert(delta % mt->cpp == 0);
> +      *base_address_offset -= delta;
> +      *x_offset_el += delta / mt->cpp;
> +   } else {
> +      assert(*base_address_offset % 4096 == 0);
> +   }
> +}
> +
>  /**
>   * Implements a rectangular block transfer (blit) of pixels between two
>   * miptrees.
> @@ -804,22 +840,44 @@ intel_miptree_set_alpha_to_one(struct brw_context *brw,
>     unsigned length = brw->gen >= 8 ? 7 : 6;
>     bool dst_y_tiled = mt->tiling == I915_TILING_Y;
>  
> -   BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, false);
> -   OUT_BATCH(CMD | (length - 2));
> -   OUT_BATCH(BR13);
> -   OUT_BATCH(SET_FIELD(y, BLT_Y) | SET_FIELD(x, BLT_X));
> -   OUT_BATCH(SET_FIELD(y + height, BLT_Y) | SET_FIELD(x + width, BLT_X));
> -   if (brw->gen >= 8) {
> -      OUT_RELOC64(mt->bo,
> -                  I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
> -                  0);
> -   } else {
> -      OUT_RELOC(mt->bo,
> -                I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
> -                0);
> +   /* We need to split the blit into chunks that each fit within the blitter's
> +    * restrictions.  We can't use a chunk size of 32768 because wee need to
> +    * ensure that src_tile_x + chunk_size fits.  We choose 16384 because it's
> +    * a nice round power of two, big enough that performance won't suffer, and
> +    * small enough to guarantee everything fits.
> +    */
> +   const uint32_t max_chunk_size = 16384;
> +
> +   for (uint32_t chunk_x = 0; chunk_x < width; chunk_x += max_chunk_size) {
> +      for (uint32_t chunk_y = 0; chunk_y < height; chunk_y += max_chunk_size) {
> +         const uint32_t chunk_w = MIN2(max_chunk_size, width - chunk_x);
> +         const uint32_t chunk_h = MIN2(max_chunk_size, height - chunk_y);
> +
> +         uint32_t offset, tile_x, tile_y;
> +         get_blit_intratile_offset_el(brw, mt,
> +                                      x + chunk_x, y + chunk_y,
> +                                      &offset, &tile_x, &tile_y);
> +
> +         BEGIN_BATCH_BLT_TILED(length, dst_y_tiled, false);
> +         OUT_BATCH(CMD | (length - 2));
> +         OUT_BATCH(BR13);
> +         OUT_BATCH(SET_FIELD(y + chunk_y, BLT_Y) |
> +                   SET_FIELD(x + chunk_x, BLT_X));
> +         OUT_BATCH(SET_FIELD(y + chunk_y + chunk_h, BLT_Y) |
> +                   SET_FIELD(x + chunk_x + chunk_w, BLT_X));
> +         if (brw->gen >= 8) {
> +            OUT_RELOC64(mt->bo,
> +                        I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
> +                        offset);
> +         } else {
> +            OUT_RELOC(mt->bo,
> +                      I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
> +                      offset);
> +         }
> +         OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
> +         ADVANCE_BATCH_TILED(dst_y_tiled, false);
> +      }
>     }
> -   OUT_BATCH(0xffffffff); /* white, but only alpha gets written */
> -   ADVANCE_BATCH_TILED(dst_y_tiled, false);
>  
>     brw_emit_mi_flush(brw);
>  }
> -- 
> 2.5.0.400.gff86faf
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list