<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 13, 2015 at 11:37 PM, Ben Widawsky <span dir="ltr"><<a href="mailto:benjamin.widawsky@intel.com" target="_blank">benjamin.widawsky@intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This patch will use a new calculation to determine if a surface can be blitted<br>
from or to. Previously, the "total_height" member was used. Total_height in the<br>
case of 2d, 3d, and cube map arrays is the height of each slice/layer/face.<br>
Since the GL map APIS only ever deal with a slice at a time however, the<br>
determining factor is really the height of one slice.<br>
<br>
This patch also has a side effect of not needing to set potentially large<br>
texture objects to the CPU domain, which implies we do not need to clflush the<br>
entire objects. (See references below for a kernel patch to achieve the same<br>
thing)<br>
<br>
With both the Y-tiled surfaces, and the removal of excessive clflushes, this<br>
improves the terrain benchmark on Cherryview (data collected by Jordan)<br>
<br>
Difference at 95.0% confidence<br>
17.9236 +/- 0.252116 153.005% +/- 2.1522% (Student's t, pooled s = 0.205889)<br>
<br>
With the performance governor, and HI-Z raw stall optimization, the improvement<br>
is even more stark on Braswell.<br>
<br>
Jordan was extremely helpful in creating this patch. Consider him co-author.<br>
<br>
References: <a href="http://patchwork.freedesktop.org/patch/38909/" target="_blank">http://patchwork.freedesktop.org/patch/38909/</a><br>
Cc: Jordan Justen <<a href="mailto:jordan.l.justen@intel.com" target="_blank">jordan.l.justen@intel.com</a>><br>
Signed-off-by: Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>><br>
---<br>
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 71 +++++++++++++++++++++------<br>
 1 file changed, 56 insertions(+), 15 deletions(-)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c<br>
index 639309b..1319f1e 100644<br>
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c<br>
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c<br>
@@ -86,6 +86,27 @@ compute_msaa_layout(struct brw_context *brw, mesa_format format, GLenum target)<br>
    }<br>
 }<br>
<br>
+static uint32_t<br>
+compute_real_blit_height(struct intel_mipmap_tree *mt)<br>
+{<br>
+   switch (mt->target) {<br>
+   case GL_TEXTURE_CUBE_MAP:<br>
+   case GL_TEXTURE_1D_ARRAY:<br>
+   case GL_TEXTURE_2D_ARRAY:<br>
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:<br>
+   case GL_TEXTURE_CUBE_MAP_ARRAY:<br>
+      assert(mt->logical_depth0);<br>
+      return mt->qpitch;<br>
+   case GL_TEXTURE_3D:<br>
+      /* FIXME 3d textures don't have a qpitch. I think it's simply the tiled<br>
+       * aligned mt->physical_height0. Since 3D textures aren't used often, just<br>
+       * print the perf debug from the caller and bail<br>
+       */<br>
+       /* fallthrough */<br>
+   default:<br>
+      return mt->total_height;<br>
+   }<br>
+}<br>
<br>
 /**<br>
  * For single-sampled render targets ("non-MSRT"), the MCS buffer is a<br>
@@ -416,6 +437,17 @@ intel_miptree_create_layout(struct brw_context *brw,<br>
    return mt;<br>
 }<br>
<br>
+static bool<br>
+miptree_exceeds_blit_height(struct intel_mipmap_tree *mt)<br>
+{<br>
+   /* FIXME: Add 3d texture support */<br>
+   if (mt->target == GL_TEXTURE_3D && mt->total_height >= 32768) {<br>
+      return true;<br>
+   }<br>
+<br>
+   return compute_real_blit_height(mt) >= 32768;<br></blockquote><div><br></div><div>I don't think this is quite correct.  Let's say we have 2D array texture with a qpitch of 32767.  Then slice 1 (the second slice) will start at 32767.  Since we have to align to a tile, the vertical offset we use for the blit will be 32768 - tile_height.  Then the Y2 coordinat will be (2 * 32767) - (32768 - tile_height) which is greater than 32767.  If we just give ourselves an extra tile_height of padding here, it should solve this problem.  Probably want to throw the above in as a comment as well.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+}<br>
+<br>
 /**<br>
  * \brief Helper function for intel_miptree_create().<br>
  */<br>
@@ -473,10 +505,22 @@ intel_miptree_choose_tiling(struct brw_context *brw,<br>
    if (minimum_pitch < 64)<br>
       return I915_TILING_NONE;<br>
<br>
-   if (ALIGN(minimum_pitch, 512) >= 32768 ||<br>
-       mt->total_width >= 32768 || mt->total_height >= 32768) {<br>
-      perf_debug("%dx%d miptree too large to blit, falling back to untiled",<br>
-                 mt->total_width, mt->total_height);<br>
+   if (ALIGN(minimum_pitch, 512) >= 32768 || miptree_exceeds_blit_height(mt)) {<br>
+      if (mt->format == GL_TEXTURE_3D) {<br>
+         perf_debug("Unsupported large 3D texture blit. "<br>
+                    "Falling back to untiled.\n");<br>
+      } else {<br>
+         /* qpitch should always be greater than or equal to the tile aligned<br>
+          * maximum of lod0 height.  That is sufficient to determine if we can<br>
+          * blit, but the most optimal value is potentially less.<br>
+          */<br>
+         if (mt->physical_height0 < 32768) {<br>
+            perf_debug("Potentially skipped a blittable buffers %d\n",<br>
+                  mt->physical_height0);<br>
+         }<br>
+         perf_debug("%dx%d miptree too large to blit, falling back to untiled",<br>
+                    mt->total_width, mt->total_height);<br>
+      }<br>
       return I915_TILING_NONE;<br>
    }<br>
<br>
@@ -620,11 +664,14 @@ intel_miptree_create(struct brw_context *brw,<br>
                                       BO_ALLOC_FOR_RENDER : 0));<br>
    mt->pitch = pitch;<br>
<br>
+   uint32_t size = ALIGN(compute_real_blit_height(mt) * mt->pitch, 512);<br>
+   assert(size <= mt->bo->size);<br>
+<br>
    /* If the BO is too large to fit in the aperture, we need to use the<br>
     * BLT engine to support it.  The BLT paths can't currently handle Y-tiling,<br>
     * so we need to fall back to X.<br>
     */<br>
-   if (y_or_x && mt->bo->size >= brw->max_gtt_map_object_size) {<br>
+   if (y_or_x && size >= brw->max_gtt_map_object_size) {<br></blockquote><div><br></div><div>We run into the same issue I pointed out above here too.  Maybe we want to roll the padding into the compute_real_blit_height function and call it compute_real_max_blit_height or something?<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
       perf_debug("%dx%d miptree larger than aperture; falling back to X-tiled\n",<br>
                  mt->total_width, mt->total_height);<br>
<br>
@@ -1748,6 +1795,8 @@ intel_miptree_map_gtt(struct brw_context *brw,<br>
    intptr_t x = map->x;<br>
    intptr_t y = map->y;<br>
<br>
+   assert(mt->bo->size < brw->max_gtt_map_object_size);<br>
+<br>
    /* For compressed formats, the stride is the number of bytes per<br>
     * row of blocks.  intel_miptree_get_image_offset() already does<br>
     * the divide.<br>
@@ -2247,16 +2296,8 @@ static bool<br>
 can_blit_slice(struct intel_mipmap_tree *mt,<br>
                unsigned int level, unsigned int slice)<br>
 {<br>
-   uint32_t image_x;<br>
-   uint32_t image_y;<br>
-   intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);<br>
-   if (image_x >= 32768 || image_y >= 32768)<br>
-      return false;<br>
-<br>
-   if (mt->pitch >= 32768)<br>
-      return false;<br>
-<br>
-   return true;<br>
+   return compute_real_blit_height(mt) < 32768 &&<br>
+          mt->pitch < 32768;<br>
 }<br>
<br>
 /**<br>
<span><font color="#888888">--<br>
2.2.1<br>
<br>
_______________________________________________<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="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>