<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Sep 6, 2016 at 4:12 PM, Nanley Chery <span dir="ltr"><<a href="mailto:nanleychery@gmail.com" target="_blank">nanleychery@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Wed, Aug 31, 2016 at 02:22:33PM -0700, Jason Ekstrand wrote:<br>
</span><div><div class="h5">> ---<br>
>  src/intel/blorp/blorp.h      |  10 ++++<br>
>  src/intel/blorp/blorp_blit.c | 133 ++++++++++++++++++++++++++++++<wbr>+++++++++++++<br>
>  2 files changed, 143 insertions(+)<br>
><br>
> diff --git a/src/intel/blorp/blorp.h b/src/intel/blorp/blorp.h<br>
> index c1e93fd..6574124 100644<br>
> --- a/src/intel/blorp/blorp.h<br>
> +++ b/src/intel/blorp/blorp.h<br>
> @@ -109,6 +109,16 @@ blorp_blit(struct blorp_batch *batch,<br>
>             uint32_t filter, bool mirror_x, bool mirror_y);<br>
><br>
>  void<br>
> +blorp_copy(struct blorp_batch *batch,<br>
> +           const struct blorp_surf *src_surf,<br>
> +           unsigned src_level, unsigned src_layer,<br>
> +           const struct blorp_surf *dst_surf,<br>
> +           unsigned dst_level, unsigned dst_layer,<br>
> +           uint32_t src_x, uint32_t src_y,<br>
> +           uint32_t dst_x, uint32_t dst_y,<br>
> +           uint32_t src_width, uint32_t src_height);<br>
> +<br>
> +void<br>
>  blorp_fast_clear(struct blorp_batch *batch,<br>
>                   const struct blorp_surf *surf,<br>
>                   uint32_t level, uint32_t layer, enum isl_format format,<br>
> diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c<br>
> index 3ab39a3..42a502c 100644<br>
> --- a/src/intel/blorp/blorp_blit.c<br>
> +++ b/src/intel/blorp/blorp_blit.c<br>
> @@ -1685,3 +1685,136 @@ blorp_blit(struct blorp_batch *batch,<br>
>                   dst_x0, dst_y0, dst_x1, dst_y1,<br>
>                   mirror_x, mirror_y);<br>
>  }<br>
> +<br>
> +static enum isl_format<br>
> +get_copy_format_for_bpb(<wbr>unsigned bpb)<br>
> +{<br>
> +   /* The choice of UNORM and UINT formats is very intentional here.  Most of<br>
> +    * the time, we want to use a UINT format to avoid any rounding error in<br>
> +    * the blit.  For stencil blits, R8_UINT is required by the hardware.<br>
> +    * (It's the only format allowed in conjunction with W-tiling.)  Also we<br>
> +    * intentionally use the 4-channel formats whenever we can.  This is so<br>
> +    * that, when we do a RGB <-> RGBX copy, the two formats will line up even<br>
> +    * though one of them is 3/4 the size of the other.  The choice of UNORM<br>
> +    * vs. UINT is also very intentional because Haswell doesn't handle 8 or<br>
> +    * 16-bit RGB UINT formats at all so we have to use UNORM there.<br>
> +    * Fortunately, the only time we should ever use two different formats in<br>
> +    * the table below is for RGB -> RGBA blits and so we will never have any<br>
> +    * UNORM/UINT mismatch.<br>
> +    */<br>
> +   switch (bpb) {<br>
> +   case 8:  return ISL_FORMAT_R8_UINT;<br>
> +   case 16: return ISL_FORMAT_R8G8_UINT;<br>
> +   case 24: return ISL_FORMAT_R8G8B8_UNORM;<br>
> +   case 32: return ISL_FORMAT_R8G8B8A8_UNORM;<br>
> +   case 48: return ISL_FORMAT_R16G16B16_UNORM;<br>
> +   case 64: return ISL_FORMAT_R16G16B16A16_UNORM;<br>
> +   case 96: return ISL_FORMAT_R32G32B32_UINT;<br>
> +   case 128:return ISL_FORMAT_R32G32B32A32_UINT;<br>
> +   default:<br>
> +      unreachable("Unknown format bpb");<br>
> +   }<br>
> +}<br>
> +<br>
> +static void<br>
> +surf_convert_to_uncompressed(<wbr>const struct isl_device *isl_dev,<br>
> +                             struct brw_blorp_surface_info *info,<br>
> +                             uint32_t *x, uint32_t *y,<br>
> +                             uint32_t *width, uint32_t *height)<br>
> +{<br>
> +   const struct isl_format_layout *fmtl =<br>
> +      isl_format_get_layout(info-><wbr>surf.format);<br>
> +<br>
> +   assert(fmtl->bw > 1 || fmtl->bh > 1);<br>
> +<br>
> +   /* This is a compressed surface.  We need to convert it to a single<br>
> +    * slice (becase compressed layouts don't perfectly match uncompressed<br>
> +    * ones with the same bpb) and divide x, y, width, and height by the<br>
> +    * block size.<br>
> +    */<br>
> +   surf_convert_to_single_slice(<wbr>isl_dev, info);<br>
> +<br>
> +   if (width || height) {<br>
> +      assert(*width % fmtl->bw == 0 ||<br>
> +             *x + *width == info->surf.logical_level0_px.<wbr>width);<br>
> +      assert(*height % fmtl->bh == 0 ||<br>
> +             *y + *height == info->surf.logical_level0_px.<wbr>height);<br>
> +      *width = DIV_ROUND_UP(*width, fmtl->bw);<br>
> +      *height = DIV_ROUND_UP(*height, fmtl->bh);<br>
> +   }<br>
> +<br>
> +   assert(*x % fmtl->bw == 0);<br>
> +   assert(*y % fmtl->bh == 0);<br>
> +   *x /= fmtl->bw;<br>
> +   *y /= fmtl->bh;<br>
> +<br>
> +   info->surf.logical_level0_px.<wbr>width =<br>
> +      DIV_ROUND_UP(info->surf.<wbr>logical_level0_px.width, fmtl->bw);<br>
> +   info->surf.logical_level0_px.<wbr>height =<br>
> +      DIV_ROUND_UP(info->surf.<wbr>logical_level0_px.height, fmtl->bh);<br>
> +<br>
> +   assert(info->surf.phys_level0_<wbr>sa.width % fmtl->bw == 0);<br>
> +   assert(info->surf.phys_level0_<wbr>sa.height % fmtl->bh == 0);<br>
> +   info->surf.phys_level0_sa.<wbr>width /= fmtl->bw;<br>
> +   info->surf.phys_level0_sa.<wbr>height /= fmtl->bh;<br>
> +<br>
> +   assert(info->tile_x_sa % fmtl->bw == 0);<br>
> +   assert(info->tile_y_sa % fmtl->bh == 0);<br>
> +   info->tile_x_sa /= fmtl->bw;<br>
> +   info->tile_y_sa /= fmtl->bh;<br>
> +<br>
> +   /* It's now an uncompressed surface so we need an uncompressed format */<br>
> +   info->surf.format = get_copy_format_for_bpb(fmtl-><wbr>bpb);<br>
> +}<br>
> +<br>
> +void<br>
> +blorp_copy(struct blorp_batch *batch,<br>
> +           const struct blorp_surf *src_surf,<br>
> +           unsigned src_level, unsigned src_layer,<br>
> +           const struct blorp_surf *dst_surf,<br>
> +           unsigned dst_level, unsigned dst_layer,<br>
> +           uint32_t src_x, uint32_t src_y,<br>
> +           uint32_t dst_x, uint32_t dst_y,<br>
> +           uint32_t src_width, uint32_t src_height)<br>
> +{<br>
> +   struct blorp_params params;<br>
> +   blorp_params_init(&params);<br>
> +<br>
> +   brw_blorp_surface_info_init(<wbr>batch->blorp, &params.src, src_surf, src_level,<br>
> +                               src_layer, ISL_FORMAT_UNSUPPORTED, false);<br>
> +   brw_blorp_surface_info_init(<wbr>batch->blorp, &params.dst, dst_surf, dst_level,<br>
> +                               dst_layer, ISL_FORMAT_UNSUPPORTED, true);<br>
> +<br>
> +   struct brw_blorp_blit_prog_key wm_prog_key;<br>
> +   memset(&wm_prog_key, 0, sizeof(wm_prog_key));<br>
> +<br>
> +   const struct isl_format_layout *src_fmtl =<br>
> +      isl_format_get_layout(params.<wbr>src.surf.format);<br>
> +   const struct isl_format_layout *dst_fmtl =<br>
> +      isl_format_get_layout(params.<wbr>dst.surf.format);<br>
> +<br>
> +   params.src.view.format = get_copy_format_for_bpb(src_<wbr>fmtl->bpb);<br>
> +   if (src_fmtl->bw > 1 || src_fmtl->bh > 1) {<br>
> +      surf_convert_to_uncompressed(<wbr>batch->blorp->isl_dev, &params.src,<br>
> +                                   &src_x, &src_y, &src_width, &src_height);<br>
> +      wm_prog_key.need_dst_offset = true;<br>
> +   }<br>
> +<br>
> +   params.dst.view.format = get_copy_format_for_bpb(dst_<wbr>fmtl->bpb);<br>
> +   if (dst_fmtl->bw > 1 || dst_fmtl->bh > 1) {<br>
> +      surf_convert_to_uncompressed(<wbr>batch->blorp->isl_dev, &params.dst,<br>
> +                                   &dst_x, &dst_y, NULL, NULL);<br>
> +      wm_prog_key.need_dst_offset = true;<br>
> +   }<br>
<br>
</div></div>When this function is later used to replace meta in vkCopyImage and the like,<br>
I suspect that copying non-zero mip levels on D16 and S8 textures can fail.<br>
These textures have a non-4x4 alignment on SKL and, like compressed textures,<br>
need surf_convert_to_single_slice()<wbr>.<br></blockquote><div><br></div><div>I don't think that's an issue.  Depth and stencil are still valid multi-LOD textures.  You don't need 4x4, you just need an alignment that we can validly express so 4x8 (stencil), for instance, is fine.  The problem with compressed is that, when you fake it as R32U32G32A32_UINT, you can end up with halign/valign that can't actually be expressed.  On SKL, I think we can actually express them all so we may not need the stomp at all.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
One idea is to call surf_convert_to_single_slice() when ever a copy occurs<br>
with an image's subresource that isn't the 1st mip level on the 1st array layer<br>
/depth slice and the alignment differs from what would be used the copy format.<br>
Thoughts?<span class="HOEnZb"><font color="#888888"><br></font></span></blockquote><div><br></div><div>That seems a bit harsh.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888">
- Nanley<br>
</font></span><span class="im HOEnZb"><br>
> +<br>
> +   /* Once both surfaces are stompped to uncompressed as needed, the<br>
> +    * destination size is the same as the source size.<br>
> +    */<br>
> +   uint32_t dst_width = src_width;<br>
> +   uint32_t dst_height = src_height;<br>
> +<br>
> +   do_blorp_blit(batch, &params, &wm_prog_key,<br>
> +                 src_x, src_y, src_x + src_width, src_y + src_height,<br>
> +                 dst_x, dst_y, dst_x + dst_width, dst_y + dst_height,<br>
> +                 false, false);<br>
> +}<br>
> --<br>
> 2.5.0.400.gff86faf<br>
><br>
</span><div class="HOEnZb"><div class="h5">> ______________________________<wbr>_________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">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>
</div></div></blockquote></div><br></div></div>