<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 22, 2016 at 7:04 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:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);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>
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 | 124 ++++++++++++++++++++++++++++++<wbr>+++++++++++--<br>
 1 file changed, 121 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c<br>
index caa3e33..383b64e 100644<br>
--- a/src/intel/blorp/blorp_blit.c<br>
+++ b/src/intel/blorp/blorp_blit.c<br>
@@ -1521,6 +1521,12 @@ dump_blorp_surf(const struct blorp_context *blorp,<br>
       blorp->unmap(blorp, &surf->aux_addr);<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>
    float src0, src1, dst0, dst1;<br>
    bool mirror;<br>
@@ -1767,12 +1773,114 @@ 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>
+                      int rgb_offset,<br>
+                      float *x0, float *x1, float *y0, float *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>
+   uint32_t rgb_adjust = MAX2(rgb_offset, 0);<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 =<br>
+      (uint32_t)*x0 * px_size_sa.w + info->tile_x_sa - rgb_adjust;<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>
+<br>
+   info->addr.offset += byte_offset;<br>
+<br>
+   adjust = (int)info->tile_x_sa / px_size_sa.w - (int)*x0;<br>
+   uint32_t rgb_x_tile_offset =<br>
+      rgb_offset >= 0 ? (((int)*x0 + adjust) % 3) : 0u;<br>
+   adjust += (int)rgb_adjust - rgb_x_tile_offset;<br>
+   *x0 += adjust;<br>
+   assert(rgb_offset < 0 || (uint32_t)*x0 % 3 == rgb_adjust);<br>
+   *x1 += adjust;<br>
+   info->tile_x_sa = rgb_x_tile_offset;<br>
+<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><div><br></div><div>Ugh... These calculations are painful.  (Not a comment on your coding ability; just a comment on the calculations.)<br><br>I think a lot of the pain is coming from the fact that you're doing it before try_blorp_blit rather than at the end of try_blorp_blit.  This means that you have to deal with partially lowered things (RGB in particular) but can't actually take advantage of the offset parameters we pass to the shader (because they aren't calculated yet).  If you did it at the end of try_blorp_blit, you could probably do something like this (WARNING: This may not even compile):<br><br></div><div>shrink_surface_to_fit(const struct isl_dev *isl_dev, struct *blorp_surface_info *info, struct rect rect)<br>{<br></div><div>
   surf_convert_to_single_slice(d<wbr>ev, info);<br>
   px_size_sa = get_px_size_sa(&info->surf);<br></div><div>   const uint32_t rect_x_sa = (uint32_t)rect.x0 / pix_size_sa.w;<br>   const uint32_t rect_y_sa = (uint32_t)rect.y0 / pix_size_sa.h;<br></div><div>   const uint32_t rect_w_px = ceilf(rect.x1) - floorf(rect.x0);<br><div>   const uint32_t rect_h_px = ceilf(rect.y1) - floorf(rect.y0);<br></div><br></div><div>   uint32_t tile_x_sa, tile_y_sa, byte_offsets;<br>   isl_tiling_get_intratile_offse<wbr>t_sa(dev, info->surf.tiling,<br>
                                      info->surf.format, info->surf.row_pitch,<br>
                                      rect_x_sa, rect_y_sa,<br>
                                      &byte_offset,<br>
                                      &tile_x_sa, &tile_y_sa);<br></div><div>   assert(tile_x_sa % px_size_sa.w == 0);<br></div><div>   assert(tile_y_sa % px_size_sa.h == 0);<br><br></div><div>   /* What we actually want here is the offset to the tile, not the intratile offset */<br></div><div>   const uint32_t tile_pos_x_sa = rect_x_sa - tile_x_sa;<br></div><div>   const uint32_t tile_pos_y_sa = rect_y_sa - tile_y_sa;<br><br></div><div>   /* Tell the shader that the origin of the surface is actually somewhere above and to the left of the actual top-left corner. */<br></div><div>   info->tile_x_sa -= tile_pos_x_sa;<br></div><div>   info->tile_y_sa -= tile_pos_y_sa;<br><br></div><div>   /* Adjust the surface */<br></div><div>   info->addr.offset += byte_offset;<br></div><div>   info->surf.logical_level0_px.w = rect_w_px + (tile_x_sa / px_size_sa.w);<br></div><div>   info->surf.logical_level0_px.h = rect_w_px + (tile_x_sa / px_size_sa.h);<br></div><div>   info->surf.phys_level0_sa.w = rect_w_px * px_size_sa.w + tile_x_sa;<br><div>   info->surf.phys_level0_sa.h = rect_h_px * px_size_sa.h + tile_y_sa;<br></div></div><div>}<br><br></div><div>Of course, this requires that we have the source rectangle as well as the destination rectangle, but that shouldn't be too hard to get.   You would just have to move all of the rectangle adjustment code into the surface adjustement helper so that it happens on both source and destination.  It would also require tweaking some of the shader code.  Am I making any sense?  Am I crazy?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+   size = ceilf(*x1 + rgb_x_tile_offset);<br>
+   size = MIN2(size, info->surf.logical_level0_px.w<wbr>idth);<br>
+   float 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>
+<br>
+   size = ceilf(*y1);<br>
+   size = MIN2(size, 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>
+                const struct blt_coords *orig_coords,<br>
+                struct blt_coords *coords)<br>
+{<br>
+   /* Shrink source surface */<br>
+   shrink_surface_params(dev,<br>
+                         &params->src,<br>
+                         -1,<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>
+   int rgb_offset =<br>
+      wm_prog_key->dst_rgb ?<br>
+      (uint32_t)(coords->x.dst0 - orig_coords->x.dst0) % 3 : -1;<br>
+   shrink_surface_params(dev,<br>
+                         &params->dst,<br>
+                         rgb_offset,<br>
+                         &coords->x.dst0,<br>
+                         &coords->x.dst1,<br>
+                         &coords->y.dst0,<br>
+                         &coords->y.dst1);<br>
+   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>
    float w = orig->x.dst1 - orig->x.dst0;<br>
    float h = orig->y.dst1 - orig->y.dst0;<br>
@@ -1784,9 +1892,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, orig,<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>
@@ -1801,8 +1916,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_6023482492704616351m_-2428526377276321362gmail-m_1947106234062438904HOEnZb"><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>