<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 5, 2015 at 7:36 PM, Ben Widawsky <span dir="ltr"><<a href="mailto:ben@bwidawsk.net" target="_blank">ben@bwidawsk.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, Jan 14, 2015 at 10:34:52AM -0800, Jason Ekstrand wrote:<br>
> On Tue, Jan 13, 2015 at 11:37 PM, Ben Widawsky <<a href="mailto:benjamin.widawsky@intel.com">benjamin.widawsky@intel.com</a>><br>
> wrote:<br>
><br>
> > This patch will use a new calculation to determine if a surface can be<br>
> > blitted<br>
> > from or to. Previously, the "total_height" member was used. Total_height<br>
> > 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<br>
> > the<br>
> > entire objects. (See references below for a kernel patch to achieve the<br>
> > same<br>
> > thing)<br>
> ><br>
> > With both the Y-tiled surfaces, and the removal of excessive clflushes,<br>
> > 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 =<br>
> > 0.205889)<br>
> ><br>
> > With the performance governor, and HI-Z raw stall optimization, the<br>
> > improvement<br>
> > is even more stark on Braswell.<br>
> ><br>
> > Jordan was extremely helpful in creating this patch. Consider him<br>
> > 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">jordan.l.justen@intel.com</a>><br>
> > Signed-off-by: Ben Widawsky <<a href="mailto:ben@bwidawsk.net">ben@bwidawsk.net</a>><br>
> > ---<br>
> >  src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 71<br>
> > +++++++++++++++++++++------<br>
> >  1 file changed, 56 insertions(+), 15 deletions(-)<br>
> ><br>
> > diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c<br>
> > 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,<br>
> > 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<br>
> > tiled<br>
> > +       * aligned mt->physical_height0. Since 3D textures aren't used<br>
> > 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>
> ><br>
><br>
> I don't think this is quite correct.  Let's say we have 2D array texture<br>
> with a qpitch of 32767.  Then slice 1 (the second slice) will start at<br>
> 32767.  Since we have to align to a tile, the vertical offset we use for<br>
> the blit will be 32768 - tile_height.  Then the Y2 coordinat will be (2 *<br>
> 32767) - (32768 - tile_height) which is greater than 32767.  If we just<br>
> give ourselves an extra tile_height of padding here, it should solve this<br>
> problem.  Probably want to throw the above in as a comment as well.<br>
><br>
<br>
</div></div>I tried really hard to prove you wrong (ie. that getting to such a number was<br>
impossible), but I failed (fwiw, you need a height of 21812 to hit it). At some<br>
point I began thinking qpitch was specifically designed to keep slices tile<br>
aligned, but without stride in the formula, that can't be right.<br>
<br>
Just to avoid excess patch versions, you okay with:<br>
compute_real_blit_height(mt) >= (32768 - tile_height(mt->tiling))<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>Yeah, that should be sufficient.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
<br>
><br>
> > +}<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<br>
> > untiled",<br>
> > -                 mt->total_width, mt->total_height);<br>
> > +   if (ALIGN(minimum_pitch, 512) >= 32768 ||<br>
> > 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<br>
> > aligned<br>
> > +          * maximum of lod0 height.  That is sufficient to determine if<br>
> > 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<br>
> > 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<br>
> > 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>
> ><br>
><br>
> We run into the same issue I pointed out above here too.  Maybe we want to<br>
> roll the padding into the compute_real_blit_height function and call it<br>
> compute_real_max_blit_height or something?<br>
><br>
<br>
</div></div>Okay, that sounds good to me, thanks for spotting that.<br>
<div class="HOEnZb"><div class="h5"><br>
><br>
> >        perf_debug("%dx%d miptree larger than aperture; falling back to<br>
> > 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>
> > --<br>
> > 2.2.1<br>
> ><br>
> > _______________________________________________<br>
> > mesa-dev mailing list<br>
> > <a href="mailto:mesa-dev@lists.freedesktop.org">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>
> ><br>
<br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">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>
<br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Ben Widawsky, Intel Open Source Technology Center<br>
</font></span></blockquote></div><br></div></div>