[Mesa-dev] [PATCH 6/6] i965: Allow Y-tiled allocations for large surfaces

Ben Widawsky benjamin.widawsky at intel.com
Mon Mar 9 21:43:36 PDT 2015


This patch will use a new calculation to determine if a surface can be blitted
from or to. Previously, the "total_height" member was used. Total_height in the
case of 2d, 3d, and cube map arrays is the height of each slice/layer/face.
Since the GL map APIS only ever deal with a slice at a time however, the
determining factor is really the height of one slice.

This patch also has a side effect of not needing to set potentially large
texture objects to the CPU domain, which implies we do not need to clflush the
entire objects. (See references below for a kernel patch to achieve the same
thing)

With both the Y-tiled surfaces, and the removal of excessive clflushes, this
improves the terrain benchmark on Cherryview (data collected by Jordan)

Jordan was extremely helpful in creating this patch. Consider him co-author.

v2: Remove assertion which didn't belong. This assert was only meant for the
patch which renamed gtt mappings to really mean GTT mappings. This should fix
around 150 piglit failures
Some reworks to centralize blitability determination (Jason, Jordan)

v3: Rebased with some non-trivial conflicts on Anuj's blitter fixes.

References: http://patchwork.freedesktop.org/patch/38909/
Cc: Jordan Justen <jordan.l.justen at intel.com>
Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
---
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 55 +++++++++++++++------------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 21 ++++++++++
 2 files changed, 52 insertions(+), 24 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 16bd151..ee8fae4 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -86,7 +86,6 @@ compute_msaa_layout(struct brw_context *brw, mesa_format format, GLenum target)
    }
 }
 
-
 /**
  * For single-sampled render targets ("non-MSRT"), the MCS buffer is a
  * scaled-down bitfield representation of the color buffer which is capable of
@@ -437,6 +436,12 @@ intel_miptree_create_layout(struct brw_context *brw,
    return mt;
 }
 
+static bool
+miptree_exceeds_blit_height(struct intel_mipmap_tree *mt)
+{
+   return intel_miptree_blit_height(mt) >= intel_blit_tile_height(mt->tiling);
+}
+
 /**
  * \brief Helper function for intel_miptree_create().
  */
@@ -502,10 +507,22 @@ intel_miptree_choose_tiling(struct brw_context *brw,
       return I915_TILING_NONE;
 
    if (ALIGN(minimum_pitch, 512) >= INTEL_MAX_BLIT_PITCH ||
-       mt->total_width >= INTEL_MAX_BLIT_PITCH ||
-       mt->total_height >= INTEL_MAX_BLIT_ROWS) {
-      perf_debug("%dx%d miptree too large to blit, falling back to untiled",
-                 mt->total_width, mt->total_height);
+       miptree_exceeds_blit_height(mt)) {
+      if (mt->format == GL_TEXTURE_3D) {
+         perf_debug("Unsupported large 3D texture blit. "
+                    "Falling back to untiled.\n");
+      } else {
+         /* qpitch should always be greater than or equal to the tile aligned
+          * maximum of lod0 height.  That is sufficient to determine if we can
+          * blit, but the most optimal value is potentially less.
+          */
+         if (mt->physical_height0 < INTEL_MAX_BLIT_ROWS) {
+            perf_debug("Potentially skipped a blittable buffers %d\n",
+                  mt->physical_height0);
+         }
+         perf_debug("%dx%d miptree too large to blit, falling back to untiled",
+                    mt->total_width, mt->total_height);
+      }
       return I915_TILING_NONE;
    }
 
@@ -647,12 +664,18 @@ intel_miptree_create(struct brw_context *brw,
                                       BO_ALLOC_FOR_RENDER : 0));
    mt->pitch = pitch;
 
+   uint32_t size =
+      mt->tiling ? ALIGN(intel_miptree_blit_height(mt) * mt->pitch,
+                         intel_blit_tile_height(mt->tiling)) :
+      mt->bo->size;
+   assert(size <= mt->bo->size);
+
    /* If the BO is too large to fit in the aperture, we need to use the
     * BLT engine to support it.  Prior to Sandybridge, the BLT paths can't
     * handle Y-tiling, so we need to fall back to X.
     */
    if (brw->gen < 6 &&
-       mt->bo->size >= brw->max_gtt_map_object_size &&
+       size >= brw->max_gtt_map_object_size &&
        mt->tiling == I915_TILING_Y &&
        requested_tiling == INTEL_MIPTREE_TILING_ANY) {
       perf_debug("%dx%d miptree larger than aperture; falling back to X-tiled\n",
@@ -2290,23 +2313,7 @@ intel_miptree_release_map(struct intel_mipmap_tree *mt,
    *map = NULL;
 }
 
-static bool
-can_blit_slice(struct intel_mipmap_tree *mt,
-               unsigned int level, unsigned int slice)
-{
-   uint32_t image_x;
-   uint32_t image_y;
-   intel_miptree_get_image_offset(mt, level, slice, &image_x, &image_y);
-   if (image_x >= INTEL_MAX_BLIT_PITCH || image_y >= INTEL_MAX_BLIT_ROWS)
-      return false;
-
    /* See intel_miptree_blit() for details on the 32k pitch limit. */
-   if (mt->pitch >= INTEL_MAX_BLIT_PITCH)
-      return false;
-
-   return true;
-}
-
 static bool
 use_intel_mipree_map_blit(struct brw_context *brw,
                           struct intel_mipmap_tree *mt,
@@ -2323,12 +2330,12 @@ use_intel_mipree_map_blit(struct brw_context *brw,
        (mt->tiling == I915_TILING_X ||
         /* Prior to Sandybridge, the blitter can't handle Y tiling */
         (brw->gen >= 6 && mt->tiling == I915_TILING_Y)) &&
-       can_blit_slice(mt, level, slice))
+       !miptree_exceeds_blit_height(mt))
       return true;
 
    if (mt->tiling != I915_TILING_NONE &&
        mt->bo->size >= brw->max_gtt_map_object_size) {
-      assert(can_blit_slice(mt, level, slice));
+      assert(!miptree_exceeds_blit_height(mt));
       return true;
    }
 
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index ee9cf1e..ce8bccc 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -576,6 +576,27 @@ void intel_miptree_release(struct intel_mipmap_tree **mt);
  */
 bool intel_miptree_match_image(struct intel_mipmap_tree *mt,
                                     struct gl_texture_image *image);
+static inline uint32_t
+intel_miptree_blit_height(struct intel_mipmap_tree *mt)
+{
+   switch (mt->target) {
+   case GL_TEXTURE_CUBE_MAP:
+   case GL_TEXTURE_1D_ARRAY:
+   case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_TEXTURE_CUBE_MAP_ARRAY:
+      assert(mt->logical_depth0);
+      return mt->qpitch;
+   case GL_TEXTURE_3D:
+      /* FIXME 3d textures don't have a qpitch. I think it's simply the tiled
+       * aligned mt->physical_height0. Since 3D textures aren't used often, just
+       * print the perf debug from the caller and bail
+       */
+      /* fallthrough */
+   default:
+      return mt->total_height;
+   }
+}
 
 void
 intel_miptree_get_image_offset(const struct intel_mipmap_tree *mt,
-- 
2.3.1



More information about the mesa-dev mailing list