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