[Mesa-dev] [PATCH 3/6] intel/blorp_blit: Adjust blorp surface parameters for split blits

Jordan Justen jordan.l.justen at intel.com
Wed Nov 23 03:04:00 UTC 2016


If try_blorp_blit() previously returned that a blit was too large,
shrink_surface_params() will be used to update the surface parameters
for the smaller blit so the blit operation can proceed.

Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
---
 src/intel/blorp/blorp_blit.c | 124 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 121 insertions(+), 3 deletions(-)

diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c
index caa3e33..383b64e 100644
--- a/src/intel/blorp/blorp_blit.c
+++ b/src/intel/blorp/blorp_blit.c
@@ -1521,6 +1521,12 @@ dump_blorp_surf(const struct blorp_context *blorp,
       blorp->unmap(blorp, &surf->aux_addr);
 }
 
+static bool
+can_shrink_surfaces(const struct blorp_params *params)
+{
+   return false;
+}
+
 struct blt_axis {
    float src0, src1, dst0, dst1;
    bool mirror;
@@ -1767,12 +1773,114 @@ adjust_split_coords(const struct blt_axis *orig,
    split_coords->src1 = orig->src1 + (scale >= 0.0 ? delta1 : delta0);
 }
 
+static const struct isl_extent2d
+get_px_size_sa(const struct isl_surf *surf)
+{
+   static const struct isl_extent2d one_to_one = { .w = 1, .h = 1 };
+
+   if (surf->msaa_layout != ISL_MSAA_LAYOUT_INTERLEAVED)
+      return one_to_one;
+   else
+      return isl_get_interleaved_msaa_px_size_sa(surf->samples);
+}
+
+static void
+shrink_surface_params(const struct isl_device *dev,
+                      struct brw_blorp_surface_info *info,
+                      int rgb_offset,
+                      float *x0, float *x1, float *y0, float *y1)
+{
+   uint32_t byte_offset, x_offset_sa, y_offset_sa, size;
+   struct isl_extent2d px_size_sa;
+   int adjust;
+
+   uint32_t rgb_adjust = MAX2(rgb_offset, 0);
+
+   surf_convert_to_single_slice(dev, info);
+
+   px_size_sa = get_px_size_sa(&info->surf);
+
+   x_offset_sa =
+      (uint32_t)*x0 * px_size_sa.w + info->tile_x_sa - rgb_adjust;
+   y_offset_sa = (uint32_t)*y0 * px_size_sa.h + info->tile_y_sa;
+   isl_tiling_get_intratile_offset_sa(dev, info->surf.tiling,
+                                      info->surf.format, info->surf.row_pitch,
+                                      x_offset_sa, y_offset_sa,
+                                      &byte_offset,
+                                      &info->tile_x_sa, &info->tile_y_sa);
+
+   info->addr.offset += byte_offset;
+
+   adjust = (int)info->tile_x_sa / px_size_sa.w - (int)*x0;
+   uint32_t rgb_x_tile_offset =
+      rgb_offset >= 0 ? (((int)*x0 + adjust) % 3) : 0u;
+   adjust += (int)rgb_adjust - rgb_x_tile_offset;
+   *x0 += adjust;
+   assert(rgb_offset < 0 || (uint32_t)*x0 % 3 == rgb_adjust);
+   *x1 += adjust;
+   info->tile_x_sa = rgb_x_tile_offset;
+
+   adjust = (int)info->tile_y_sa / px_size_sa.h - (int)*y0;
+   *y0 += adjust;
+   *y1 += adjust;
+   info->tile_y_sa = 0;
+
+   size = ceilf(*x1 + rgb_x_tile_offset);
+   size = MIN2(size, info->surf.logical_level0_px.width);
+   float phys_scale =
+      info->surf.phys_level0_sa.width / info->surf.logical_level0_px.width;
+   info->surf.logical_level0_px.width = size;
+   info->surf.phys_level0_sa.width =
+      (uint32_t)ceilf(phys_scale * size);
+
+   size = ceilf(*y1);
+   size = MIN2(size, info->surf.logical_level0_px.height);
+   phys_scale =
+      info->surf.phys_level0_sa.height / info->surf.logical_level0_px.height;
+   info->surf.logical_level0_px.height = (uint32_t)ceilf(size);
+   info->surf.phys_level0_sa.height =
+      (uint32_t)ceilf(phys_scale * size);
+}
+
+static void
+shrink_surfaces(const struct isl_device *dev,
+                struct blorp_params *params,
+                struct brw_blorp_blit_prog_key *wm_prog_key,
+                const struct blt_coords *orig_coords,
+                struct blt_coords *coords)
+{
+   /* Shrink source surface */
+   shrink_surface_params(dev,
+                         &params->src,
+                         -1,
+                         &coords->x.src0,
+                         &coords->x.src1,
+                         &coords->y.src0,
+                         &coords->y.src1);
+   wm_prog_key->need_src_offset = false;
+
+   /* Shrink destination surface */
+   int rgb_offset =
+      wm_prog_key->dst_rgb ?
+      (uint32_t)(coords->x.dst0 - orig_coords->x.dst0) % 3 : -1;
+   shrink_surface_params(dev,
+                         &params->dst,
+                         rgb_offset,
+                         &coords->x.dst0,
+                         &coords->x.dst1,
+                         &coords->y.dst0,
+                         &coords->y.dst1);
+   wm_prog_key->need_dst_offset = wm_prog_key->dst_rgb;
+}
+
 static void
 do_blorp_blit(struct blorp_batch *batch,
-              struct blorp_params *params,
+              const struct blorp_params *orig_params,
               struct brw_blorp_blit_prog_key *wm_prog_key,
               const struct blt_coords *orig)
 {
+   struct blorp_params params;
+   struct blt_coords blit_coords;
    struct blt_coords split_coords = *orig;
    float w = orig->x.dst1 - orig->x.dst0;
    float h = orig->y.dst1 - orig->y.dst0;
@@ -1784,9 +1892,16 @@ do_blorp_blit(struct blorp_batch *batch,
       y_scale = -y_scale;
 
    bool x_done, y_done;
+   bool shrink = false;
    do {
+      params = *orig_params;
+      blit_coords = split_coords;
+      if (shrink) {
+         shrink_surfaces(batch->blorp->isl_dev, &params, wm_prog_key, orig,
+                         &blit_coords);
+      }
       unsigned result =
-         try_blorp_blit(batch, params, wm_prog_key, &split_coords);
+         try_blorp_blit(batch, &params, wm_prog_key, &blit_coords);
 
       if (result & BLIT_WIDTH_TOO_LARGE) {
          w /= 2.0;
@@ -1801,8 +1916,11 @@ do_blorp_blit(struct blorp_batch *batch,
          adjust_split_coords(&orig->y, &split_coords.y, y_scale);
       }
 
-      if (result != 0)
+      if (result != 0) {
+         assert(can_shrink_surfaces(orig_params));
+         shrink = true;
          continue;
+      }
 
       y_done = (orig->y.dst1 - split_coords.y.dst1 < 0.5);
       x_done = y_done && (orig->x.dst1 - split_coords.x.dst1 < 0.5);
-- 
2.10.2



More information about the mesa-dev mailing list