<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Nov 30, 2016 at 8:12 PM, Jordan Justen <span dir="ltr"><<a href="mailto:jordan.l.justen@intel.com" target="_blank">jordan.l.justen@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">If try_blorp_blit() previously returned that a blit was too large,<br>
shrink_surface_params() will be used to update the surface parameters<br>
for the smaller blit so the blit operation can proceed.<br>
<br>
v2:<br>
 * Use double instead of float. (Jason)<br>
<br>
Signed-off-by: Jordan Justen <<a href="mailto:jordan.l.justen@intel.com" target="_blank">jordan.l.justen@intel.com</a>><br>
---<br>
 src/intel/blorp/blorp_blit.c | 108 ++++++++++++++++++++++++++++++<wbr>+++++++++++--<br>
 1 file changed, 105 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c<br>
index b12a4ec..5ca3190 100644<br>
--- a/src/intel/blorp/blorp_blit.c<br>
+++ b/src/intel/blorp/blorp_blit.c<br>
@@ -1486,6 +1486,12 @@ surf_retile_w_to_y(const struct isl_device *isl_dev,<br>
    info->tile_y_sa /= 2;<br>
 }<br>
<br>
+static bool<br>
+can_shrink_surfaces(const struct blorp_params *params)<br>
+{<br>
+   return false;<br>
+}<br>
+<br>
 struct blt_axis {<br>
    double src0, src1, dst0, dst1;<br>
    bool mirror;<br>
@@ -1732,12 +1738,98 @@ adjust_split_coords(const struct blt_axis *orig,<br>
    split_coords->src1 = orig->src1 + (scale >= 0.0 ? delta1 : delta0);<br>
 }<br>
<br>
+static const struct isl_extent2d<br>
+get_px_size_sa(const struct isl_surf *surf)<br>
+{<br>
+   static const struct isl_extent2d one_to_one = { .w = 1, .h = 1 };<br>
+<br>
+   if (surf->msaa_layout != ISL_MSAA_LAYOUT_INTERLEAVED)<br>
+      return one_to_one;<br>
+   else<br>
+      return isl_get_interleaved_msaa_px_si<wbr>ze_sa(surf->samples);<br>
+}<br>
+<br>
+static void<br>
+shrink_surface_params(const struct isl_device *dev,<br>
+                      struct brw_blorp_surface_info *info,<br>
+                      double *x0, double *x1, double *y0, double *y1)<br>
+{<br>
+   uint32_t byte_offset, x_offset_sa, y_offset_sa, size;<br>
+   struct isl_extent2d px_size_sa;<br>
+   int adjust;<br>
+<br>
+   surf_convert_to_single_slice(<wbr>dev, info);<br>
+<br>
+   px_size_sa = get_px_size_sa(&info->surf);<br>
+<br>
+   x_offset_sa = (uint32_t)*x0 * px_size_sa.w + info->tile_x_sa;<br>
+   y_offset_sa = (uint32_t)*y0 * px_size_sa.h + info->tile_y_sa;<br>
+   isl_tiling_get_intratile_offs<wbr>et_sa(dev, info->surf.tiling,<br>
+                                      info->surf.format, info->surf.row_pitch,<br>
+                                      x_offset_sa, y_offset_sa,<br>
+                                      &byte_offset,<br>
+                                      &info->tile_x_sa, &info->tile_y_sa);<br></blockquote><div><br></div><div>If we're going to do things this early, we should just make our own temporary variables for tile_x/y instead of trying to re-use the ones from info<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   info->addr.offset += byte_offset;<br>
+<br>
+   adjust = (int)info->tile_x_sa / px_size_sa.w - (int)*x0;<br>
+   *x0 += adjust;<br>
+   *x1 += adjust;<br>
+   info->tile_x_sa = 0; <br></blockquote><div><br></div><div>That way we don't have to reset them to 0.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   adjust = (int)info->tile_y_sa / px_size_sa.h - (int)*y0;<br>
+   *y0 += adjust;<br>
+   *y1 += adjust;<br>
+   info->tile_y_sa = 0; <br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   size = MIN2((uint32_t)ceilf(*x1), info->surf.logical_level0_px.w<wbr>idth);<br>
+   double phys_scale =<br>
+      info->surf.phys_level0_sa.widt<wbr>h / info->surf.logical_level0_px.w<wbr>idth;<br>
+   info->surf.logical_level0_px.<wbr>width = size;<br>
+   info->surf.phys_level0_sa.wid<wbr>th =<br>
+      (uint32_t)ceilf(phys_scale * size);<br></blockquote><div><br></div><div>Why not juts set logical_level0_px and then multiply by px_size_sa to get the physical size?  That seems more reliable by using a double to help with integer calculations.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+   size = MIN2((uint32_t)ceilf(*y1), info->surf.logical_level0_px.h<wbr>eight);<br>
+   phys_scale =<br>
+      info->surf.phys_level0_sa.heig<wbr>ht / info->surf.logical_level0_px.h<wbr>eight;<br>
+   info->surf.logical_level0_px.<wbr>height = (uint32_t)ceilf(size);<br>
+   info->surf.phys_level0_sa.hei<wbr>ght =<br>
+      (uint32_t)ceilf(phys_scale * size);<br>
+}<br>
+<br>
+static void<br>
+shrink_surfaces(const struct isl_device *dev,<br>
+                struct blorp_params *params,<br>
+                struct brw_blorp_blit_prog_key *wm_prog_key,<br>
+                struct blt_coords *coords)<br>
+{<br>
+   /* Shrink source surface */<br>
+   shrink_surface_params(dev,<br>
+                         &params->src,<br>
+                         &coords->x.src0,<br>
+                         &coords->x.src1,<br>
+                         &coords->y.src0,<br>
+                         &coords->y.src1);<br>
+   wm_prog_key->need_src_offset = false;<br>
+<br>
+   /* Shrink destination surface */<br>
+   shrink_surface_params(dev,<br>
+                         &params->dst,<br>
+                         &coords->x.dst0,<br>
+                         &coords->x.dst1,<br>
+                         &coords->y.dst0,<br>
+                         &coords->y.dst1);<br></blockquote><div><br></div><div>I commented in our meeting that we probably want to support splitting only one of the surfaces.  Let's merge it first and plan to fix it as a follow-up.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+   wm_prog_key->need_dst_offset = wm_prog_key->dst_rgb;<br>
+}<br>
+<br>
 static void<br>
 do_blorp_blit(struct blorp_batch *batch,<br>
-              struct blorp_params *params,<br>
+              const struct blorp_params *orig_params,<br>
               struct brw_blorp_blit_prog_key *wm_prog_key,<br>
               const struct blt_coords *orig)<br>
 {<br>
+   struct blorp_params params;<br>
+   struct blt_coords blit_coords;<br>
    struct blt_coords split_coords = *orig;<br>
    double w = orig->x.dst1 - orig->x.dst0;<br>
    double h = orig->y.dst1 - orig->y.dst0;<br>
@@ -1749,9 +1841,16 @@ do_blorp_blit(struct blorp_batch *batch,<br>
       y_scale = -y_scale;<br>
<br>
    bool x_done, y_done;<br>
+   bool shrink = false;<br>
    do {<br>
+      params = *orig_params;<br>
+      blit_coords = split_coords;<br>
+      if (shrink) {<br>
+         shrink_surfaces(batch->blorp-<wbr>>isl_dev, &params, wm_prog_key,<br>
+                         &blit_coords);<br>
+      }<br>
       unsigned result =<br>
-         try_blorp_blit(batch, params, wm_prog_key, &split_coords);<br>
+         try_blorp_blit(batch, &params, wm_prog_key, &blit_coords);<br>
<br>
       if (result & BLIT_WIDTH_TOO_LARGE) {<br>
          w /= 2.0;<br>
@@ -1766,8 +1865,11 @@ do_blorp_blit(struct blorp_batch *batch,<br>
          adjust_split_coords(&orig->y, &split_coords.y, y_scale);<br>
       }<br>
<br>
-      if (result != 0)<br>
+      if (result != 0) {<br>
+         assert(can_shrink_surfaces(or<wbr>ig_params));<br>
+         shrink = true;<br>
          continue;<br>
+      }<br>
<br>
       y_done = (orig->y.dst1 - split_coords.y.dst1 < 0.5);<br>
       x_done = y_done && (orig->x.dst1 - split_coords.x.dst1 < 0.5);<br>
<span class="m_-3206260684756618332HOEnZb"><font color="#888888">--<br>
2.10.2<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org" target="_blank">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>