i965/gen9: Plugin the code for selecting YF/YS tiling on skl+
authorAnuj Phogat <anuj.phogat@gmail.com>
Wed, 15 Apr 2015 05:06:49 +0000 (22:06 -0700)
committerAnuj Phogat <anuj.phogat@gmail.com>
Mon, 29 Jun 2015 20:13:41 +0000 (13:13 -0700)
Buffers with Yf/Ys tiling end up using meta upload / download
paths or the blitter for cases where they used tiled_memcpy paths
in case of Y tiling. This has exposed some bugs in meta path. To
avoid any piglit regressions on SKL this patch keeps the Yf/Ys
tiling disabled at the moment.

V3: Make brw_miptree_choose_tr_mode() actually choose TRMODE. (Ben)
    Few cosmetic changes.
V4: Get rid of brw_miptree_choose_tr_mode().
    Take care of all tile resource modes {Yf, Ys, none} for all
    generations at one place.

Signed-off-by: Anuj Phogat <anuj.phogat@gmail.com>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net>
src/mesa/drivers/dri/i965/brw_tex_layout.c

index e35cb645c24efa7b4bdb73dda36c1374e8037d16..45bbf7e7d0fc319e5f7cbb927557061c0cd92d22 100644 (file)
@@ -810,27 +810,89 @@ brw_miptree_layout(struct brw_context *brw,
                    enum intel_miptree_tiling_mode requested,
                    uint32_t layout_flags)
 {
-   mt->tr_mode = INTEL_MIPTREE_TRMODE_NONE;
+   const unsigned bpp = mt->cpp * 8;
+   /* Enable YF/YS tiling only for color surfaces because depth and
+    * stencil surfaces are not supported in blitter using fast copy
+    * blit and meta PBO upload, download paths. No other paths
+    * currently support Yf/Ys tiled surfaces.
+    * FINISHME:  Remove this restriction once we have a tiled_memcpy()
+    * path to do depth/stencil data upload/download to Yf/Ys tiled
+    * surfaces.
+    */
+   const bool is_tr_mode_yf_ys_allowed =
+      brw->gen >= 9 &&
+      !(layout_flags & MIPTREE_LAYOUT_FOR_BO) &&
+      !mt->compressed &&
+      _mesa_is_format_color_format(mt->format) &&
+      (requested == INTEL_MIPTREE_TILING_Y ||
+       requested == INTEL_MIPTREE_TILING_ANY) &&
+      (bpp && is_power_of_two(bpp)) &&
+      /* FIXME: To avoid piglit regressions keep the Yf/Ys tiling
+       * disabled at the moment.
+       */
+      false;
 
-   intel_miptree_set_alignment(brw, mt, layout_flags);
-   intel_miptree_set_total_width_height(brw, mt);
+   /* Lower index (Yf) is the higher priority mode */
+   const uint32_t tr_mode[3] = {INTEL_MIPTREE_TRMODE_YF,
+                                INTEL_MIPTREE_TRMODE_YS,
+                                INTEL_MIPTREE_TRMODE_NONE};
+   int i = is_tr_mode_yf_ys_allowed ? 0 : ARRAY_SIZE(tr_mode) - 1;
 
-   if (!mt->total_width || !mt->total_height) {
-      intel_miptree_release(&mt);
-      return;
-   }
+   while (i < ARRAY_SIZE(tr_mode)) {
+      if (brw->gen < 9)
+         assert(tr_mode[i] == INTEL_MIPTREE_TRMODE_NONE);
+      else
+         assert(tr_mode[i] == INTEL_MIPTREE_TRMODE_YF ||
+                tr_mode[i] == INTEL_MIPTREE_TRMODE_YS ||
+                tr_mode[i] == INTEL_MIPTREE_TRMODE_NONE);
 
-   /* On Gen9+ the alignment values are expressed in multiples of the block
-    * size
-    */
-   if (brw->gen >= 9) {
-      unsigned int i, j;
-      _mesa_get_format_block_size(mt->format, &i, &j);
-      mt->align_w /= i;
-      mt->align_h /= j;
-   }
+      mt->tr_mode = tr_mode[i];
+      intel_miptree_set_alignment(brw, mt, layout_flags);
+      intel_miptree_set_total_width_height(brw, mt);
+
+      if (!mt->total_width || !mt->total_height) {
+         intel_miptree_release(&mt);
+         break;
+      }
+
+      /* On Gen9+ the alignment values are expressed in multiples of the
+       * block size.
+       */
+      if (brw->gen >= 9) {
+         unsigned int i, j;
+         _mesa_get_format_block_size(mt->format, &i, &j);
+         mt->align_w /= i;
+         mt->align_h /= j;
+      }
+
+      /* If there is already a BO, we cannot effect tiling modes */
+      if (layout_flags & MIPTREE_LAYOUT_FOR_BO)
+         break;
 
-   if ((layout_flags & MIPTREE_LAYOUT_FOR_BO) == 0)
       mt->tiling = brw_miptree_choose_tiling(brw, requested, mt);
+      if (is_tr_mode_yf_ys_allowed) {
+         unsigned int level = 0;
+
+         if (mt->tiling == I915_TILING_Y ||
+             mt->tiling == (I915_TILING_Y | I915_TILING_X) ||
+             mt->tr_mode == INTEL_MIPTREE_TRMODE_NONE) {
+            /* FIXME: Don't allow YS tiling at the moment. Using 64KB tiling
+             * for small textures might result in to memory wastage. Revisit
+             * this condition when we have more information about the specific
+             * cases where using YS over YF will be useful.
+             */
+            if (mt->tr_mode != INTEL_MIPTREE_TRMODE_YS)
+               break;
+         }
+         /* Failed to use selected tr_mode. Free up the memory allocated
+          * for miptree levels in intel_miptree_total_width_height().
+          */
+         for (level = mt->first_level; level <= mt->last_level; level++) {
+            free(mt->level[level].slice);
+            mt->level[level].slice = NULL;
+         }
+      }
+      i++;
+   }
 }