<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Mar 5, 2018 at 11:39 AM, 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 Tue, Jan 09, 2018 at 11:16:59PM -0800, Scott D Phillips wrote:<br>
> Rename the (un)map_gtt functions to (un)map_map (map by<br>
> returning a map) and add new functions (un)map_tiled_memcpy that<br>
> return a shadow buffer populated with the intel_tiled_memcpy<br>
> functions.<br>
<br>
</span>Could you mention some of the rationale?<br>
<div><div class="h5"><br>
> ---<br>
>  src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c | 95 ++++++++++++++++++++++++---<br>
>  1 file changed, 86 insertions(+), 9 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c<br>
> index ead0c359c0..7a90dafa1e 100644<br>
> --- a/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c<br>
> +++ b/src/mesa/drivers/dri/i965/<wbr>intel_mipmap_tree.c<br>
> @@ -31,6 +31,7 @@<br>
>  #include "intel_image.h"<br>
>  #include "intel_mipmap_tree.h"<br>
>  #include "intel_tex.h"<br>
> +#include "intel_tiled_memcpy.h"<br>
>  #include "intel_blit.h"<br>
>  #include "intel_fbo.h"<br>
><br>
> @@ -3031,10 +3032,10 @@ intel_miptree_unmap_raw(struct intel_mipmap_tree *mt)<br>
>  }<br>
><br>
>  static void<br>
> -intel_miptree_map_gtt(struct brw_context *brw,<br>
> -                   struct intel_mipmap_tree *mt,<br>
> -                   struct intel_miptree_map *map,<br>
> -                   unsigned int level, unsigned int slice)<br>
> +intel_miptree_map_map(struct brw_context *brw,<br>
> +                      struct intel_mipmap_tree *mt,<br>
> +                      struct intel_miptree_map *map,<br>
> +                      unsigned int level, unsigned int slice)<br>
>  {<br>
>     unsigned int bw, bh;<br>
>     void *base;<br>
> @@ -3052,7 +3053,7 @@ intel_miptree_map_gtt(struct brw_context *brw,<br>
>     y /= bh;<br>
>     x /= bw;<br>
><br>
> -   base = intel_miptree_map_raw(brw, mt, map->mode);<br>
> +   base = intel_miptree_map_raw(brw, mt, map->mode | MAP_RAW);<br>
><br>
>     if (base == NULL)<br>
>        map->ptr = NULL;<br>
> @@ -3078,11 +3079,80 @@ intel_miptree_map_gtt(struct brw_context *brw,<br>
>  }<br>
><br>
>  static void<br>
> -intel_miptree_unmap_gtt(<wbr>struct intel_mipmap_tree *mt)<br>
> +intel_miptree_unmap_map(<wbr>struct intel_mipmap_tree *mt)<br>
>  {<br>
>     intel_miptree_unmap_raw(mt);<br>
>  }<br>
><br>
> +/* Compute extent parameters for use with tiled_memcpy functions.<br>
> + * xs are in units of bytes and ys are in units of strides. */<br>
> +static inline void<br>
> +tile_extents(struct intel_mipmap_tree *mt, struct intel_miptree_map *map,<br>
> +             unsigned int level, unsigned int slice, unsigned int *x1,<br>
> +             unsigned int *x2, unsigned int *y1, unsigned int *y2)<br>
<br>
</div></div>It would be nice to give these variables units:<br>
x1_B, y1_el, etc.<br>
<span class=""><br>
> +{<br>
> +   unsigned int block_width, block_height, block_bytes;<br>
> +   unsigned int x0_el, y0_el;<br>
> +<br>
> +   _mesa_get_format_block_size(<wbr>mt->format, &block_width, &block_height);<br>
> +   block_bytes = _mesa_get_format_bytes(mt-><wbr>format);<br>
<br>
</span>block_bytes == mt->cpp (in theory anyways)<br>
<span class=""><br>
> +<br>
> +   assert(map->x % block_width == 0);<br>
> +   assert(map->y % block_height == 0);<br>
> +<br>
> +   intel_miptree_get_image_<wbr>offset(mt, level, slice, &x0_el, &y0_el);<br>
> +   *x1 = (map->x / block_width + x0_el) * block_bytes;<br>
> +   *y1 = map->y / block_height + y0_el;<br>
> +   *x2 = *x1 + DIV_ROUND_UP(map->w, block_width) * block_bytes;<br>
> +   *y2 = *y1 + DIV_ROUND_UP(map->h, block_height);<br>
> +}<br>
> +<br>
> +static void<br>
> +intel_miptree_map_tiled_<wbr>memcpy(struct brw_context *brw,<br>
> +                               struct intel_mipmap_tree *mt,<br>
> +                               struct intel_miptree_map *map,<br>
> +                               unsigned int level, unsigned int slice)<br>
> +{<br>
> +   unsigned int x1, x2, y1, y2;<br>
> +   tile_extents(mt, map, level, slice, &x1, &x2, &y1, &y2);<br>
> +   map->stride = _mesa_format_row_stride(mt-><wbr>format, map->w);<br>
> +   map->buffer = map->ptr = malloc(map->stride * (y2 - y1));<br>
<br>
</span>Using _mesa_align_malloc should improve memory accesses for our 128bit formats.<br>
<br>
We should probably also assert(map->ptr) or throw a GL_OUT_OF_MEMORY<br>
error if the alloc fails.<br>
<div><div class="h5"><br>
> +<br>
> +   if (!(map->mode & GL_MAP_INVALIDATE_RANGE_BIT)) {<br>
> +      char *src = intel_miptree_map_raw(brw, mt, map->mode | MAP_RAW);<br>
> +      src += mt->offset;<br>
> +<br>
> +      tiled_to_linear(x1, x2, y1, y2, map->ptr, src, map->stride,<br>
> +                      mt->surf.row_pitch, brw->has_swizzling, mt->surf.tiling,<br>
> +                      memcpy);<br>
> +<br>
> +      intel_miptree_unmap_raw(mt);<br>
> +   }<br>
> +}<br>
> +<br>
> +static void<br>
> +intel_miptree_unmap_tiled_<wbr>memcpy(struct brw_context *brw,<br>
> +                                 struct intel_mipmap_tree *mt,<br>
> +                                 struct intel_miptree_map *map,<br>
> +                                 unsigned int level,<br>
> +                                 unsigned int slice)<br>
> +{<br>
> +   if (map->mode & GL_MAP_WRITE_BIT) {<br>
> +      unsigned int x1, x2, y1, y2;<br>
> +      tile_extents(mt, map, level, slice, &x1, &x2, &y1, &y2);<br>
> +<br>
> +      char *dst = intel_miptree_map_raw(brw, mt, map->mode | MAP_RAW);<br>
> +      dst += mt->offset;<br>
> +<br>
> +      linear_to_tiled(x1, x2, y1, y2, dst, map->ptr, mt->surf.row_pitch,<br>
> +                      map->stride, brw->has_swizzling, mt->surf.tiling, memcpy);<br>
> +<br>
> +      intel_miptree_unmap_raw(mt);<br>
> +   }<br>
> +   free(map->buffer);<br>
> +   map->buffer = map->ptr = NULL;<br>
> +}<br>
> +<br>
>  static void<br>
>  intel_miptree_map_blit(struct brw_context *brw,<br>
>                      struct intel_mipmap_tree *mt,<br>
> @@ -3640,8 +3710,10 @@ intel_miptree_map(struct brw_context *brw,<br>
>                (mt->surf.row_pitch % 16 == 0)) {<br>
>        intel_miptree_map_movntdqa(<wbr>brw, mt, map, level, slice);<br>
>  #endif<br>
> +   } else if (mt->surf.tiling != ISL_TILING_LINEAR) {<br>
<br>
</div></div>What happens to clients who try to map a tiled surface with the MAP_RAW<br>
flag set? It looks like they expect a tiled buffer but get a linear one<br>
instead.<br>
<br>
Also, in a number of places where tiling memcpy is used, the following<br>
restriction is present (though the comment varies):<br>
<br>
   /* linear_to_tiled() assumes that if the object is swizzled, it is using<br>
    * I915_BIT6_SWIZZLE_9_10 for X and I915_BIT6_SWIZZLE_9 for Y.  This is only<br>
    * true on gen5 and above.<br>
    *<br>
    * The killer on top is that some gen4 have an L-shaped swizzle mode, where<br>
    * parts of the memory aren't swizzled at all. Userspace just can't handle<br>
    * that.<br>
    */<br>
   if (devinfo->gen < 5 && brw->has_swizzling)<br>
      return false;<span class=""><br></span></blockquote><div><br></div><div>Yikes.  I didn't realize  that gen4 still had crazy swizzling.  I'm a bit surprised this didn't come up in testing.<br><br></div><div>--Jason<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> +      intel_miptree_map_tiled_<wbr>memcpy(brw, mt, map, level, slice);<br>
>     } else {<br>
> -      intel_miptree_map_gtt(brw, mt, map, level, slice);<br>
> +      intel_miptree_map_map(brw, mt, map, level, slice);<br>
>     }<br>
><br>
>     *out_ptr = map->ptr;<br>
> @@ -3677,11 +3749,16 @@ intel_miptree_unmap(struct brw_context *brw,<br>
>     } else if (map->linear_mt) {<br>
>        intel_miptree_unmap_blit(brw, mt, map, level, slice);<br>
>  #if defined(USE_SSE41)<br>
> -   } else if (map->buffer && cpu_has_sse4_1) {<br>
> +   } else if (!(map->mode & GL_MAP_WRITE_BIT) &&<br>
> +              !mt->compressed && cpu_has_sse4_1 &&<br>
> +              (mt->surf.row_pitch % 16 == 0) &&<br>
> +              map->buffer) {<br>
<br>
</span>This hunk looks unrelated. Should this be a separate patch?<br>
<span class="HOEnZb"><font color="#888888"><br>
-Nanley<br>
</font></span><span class="im HOEnZb">>        intel_miptree_unmap_movntdqa(<wbr>brw, mt, map, level, slice);<br>
>  #endif<br>
> +   } else if (mt->surf.tiling != ISL_TILING_LINEAR) {<br>
> +      intel_miptree_unmap_tiled_<wbr>memcpy(brw, mt, map, level, slice);<br>
>     } else {<br>
> -      intel_miptree_unmap_gtt(mt);<br>
> +      intel_miptree_unmap_map(mt);<br>
>     }<br>
><br>
>     intel_miptree_release_map(mt, level, slice);<br>
> --<br>
> 2.14.3<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>
______________________________<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>