<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>