[Mesa-dev] [PATCH 20/20] i965/blorp: Translate w-tiling into linear instead of into Y-tiling

Topi Pohjolainen topi.pohjolainen at intel.com
Fri Apr 11 00:29:00 PDT 2014


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp.cpp      | 10 ++--
 src/mesa/drivers/dri/i965/brw_blorp_blit.cpp | 90 +++++++---------------------
 src/mesa/drivers/dri/i965/gen6_blorp.cpp     | 10 +---
 src/mesa/drivers/dri/i965/gen7_blorp.cpp     | 10 +---
 4 files changed, 31 insertions(+), 89 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.cpp b/src/mesa/drivers/dri/i965/brw_blorp.cpp
index 82e30d4..99b1069 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp.cpp
@@ -88,14 +88,14 @@ brw_blorp_surface_info::set(struct brw_context *brw,
 
    switch (mt->format) {
    case MESA_FORMAT_S_UINT8:
-      /* The miptree is a W-tiled stencil buffer.  Surface states can't be set
-       * up for W tiling, so we'll need to use Y tiling and have the WM
-       * program swizzle the coordinates, and offset to correct level/layer.
+      /* The miptree is a W-tiled stencil buffer. Surface states can't be set
+       * up for W tiling, and hence the surface is configured as linear and
+       * the program swizzles and offsets the coordinates.
        */
       this->map_stencil_as_y_tiled = true;
       this->brw_surfaceformat = BRW_SURFACEFORMAT_R8_UNORM;
-      this->width = mt->physical_width0;
-      this->height = mt->total_height;
+      this->width = mt->region->pitch;
+      this->height = ALIGN(mt->total_height, 64);
       break;
    case MESA_FORMAT_Z24_UNORM_X8_UINT:
       /* It would make sense to use BRW_SURFACEFORMAT_R24_UNORM_X8_TYPELESS
diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
index c69fac4..d5ab1e1 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
+++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
@@ -835,7 +835,10 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
        key->rt_layout != key->dst_layout) {
       encode_msaa(key->rt_samples, key->rt_layout);
       /* Now (X, Y, S) = detile(rt_tiling, offset) */
-      translate_tiling(rt_tiled_w, key->dst_tiled_w);
+      if (rt_tiled_w != key->dst_tiled_w) {
+         emit_linear_to_w_tiling(t1, t2, dst_stride, X, Y, Xp, Yp);
+         SWAP_XY_AND_XPYP();
+      }
       /* Now (X, Y, S) = detile(dst_tiling, offset) */
       decode_msaa(key->dst_samples, key->dst_layout);
    }
@@ -895,7 +898,10 @@ brw_blorp_blit_program::compile(struct brw_context *brw,
           !key->bilinear_filter) {
          encode_msaa(key->src_samples, key->src_layout);
          /* Now (X, Y, S) = detile(src_tiling, offset) */
-         translate_tiling(key->src_tiled_w, tex_tiled_w);
+         if (tex_tiled_w != key->src_tiled_w) {
+            emit_w_tiling_to_linear(t1, t2, src_stride, X, Y, Xp, Yp);
+            SWAP_XY_AND_XPYP();
+         }
          /* Now (X, Y, S) = detile(tex_tiling, offset) */
          if (!key->src_tiled_w)
             decode_msaa(key->tex_samples, key->tex_layout);
@@ -2224,75 +2230,23 @@ brw_blorp_blit_params::brw_blorp_blit_params(struct brw_context *brw,
 
    if (dst.map_stencil_as_y_tiled) {
       /* We must modify the rectangle we send through the rendering pipeline
-       * (and the size and x/y offset of the destination surface), to account
-       * for the fact that we are mapping it as Y-tiled when it is in fact
-       * W-tiled.
-       *
-       * Both Y tiling and W tiling can be understood as organizations of
-       * 32-byte sub-tiles; within each 32-byte sub-tile, the layout of pixels
-       * is different, but the layout of the 32-byte sub-tiles within the 4k
-       * tile is the same (8 sub-tiles across by 16 sub-tiles down, in
-       * column-major order).  In Y tiling, the sub-tiles are 16 bytes wide
-       * and 2 rows high; in W tiling, they are 8 bytes wide and 4 rows high.
-       *
-       * Therefore, to account for the layout differences within the 32-byte
-       * sub-tiles, we must expand the rectangle so the X coordinates of its
-       * edges are multiples of 8 (the W sub-tile width), and its Y
-       * coordinates of its edges are multiples of 4 (the W sub-tile height).
-       * Then we need to scale the X and Y coordinates of the rectangle to
-       * account for the differences in aspect ratio between the Y and W
-       * sub-tiles.  We need to modify the layer width and height similarly.
-       *
-       * A correction needs to be applied when MSAA is in use: since
-       * INTEL_MSAA_LAYOUT_IMS uses an interleaving pattern whose height is 4,
-       * we need to align the Y coordinates to multiples of 8, so that when
-       * they are divided by two they are still multiples of 4.
-       *
-       * Note: Since the x/y offset of the surface will be applied using the
-       * SURFACE_STATE command packet, it will be invisible to the swizzling
-       * code in the shader; therefore it needs to be in a multiple of the
-       * 32-byte sub-tile size.  Fortunately it is, since the sub-tile is 8
-       * pixels wide and 4 pixels high (when viewed as a W-tiled stencil
-       * buffer), and the miplevel alignment used for stencil buffers is 8
-       * pixels horizontally and either 4 or 8 pixels vertically (see
-       * intel_horizontal_texture_alignment_unit() and
-       * intel_vertical_texture_alignment_unit()).
-       *
-       * Note: Also, since the SURFACE_STATE command packet can only apply
-       * offsets that are multiples of 4 pixels horizontally and 2 pixels
-       * vertically, it is important that the offsets will be multiples of
-       * these sizes after they are converted into Y-tiled coordinates.
-       * Fortunately they will be, since we know from above that the offsets
-       * are a multiple of the 32-byte sub-tile size, and in Y-tiled
-       * coordinates the sub-tile is 16 pixels wide and 2 pixels high.
-       *
-       * TODO: what if this makes the coordinates (or the texture size) too
-       * large?
+       * to account for the fact that we are mapping it as linear when it is
+       * in fact W-tiled. In W-tiling 8x8 blocks are in column major order and
+       * hence full width is needed but the height can be restricted by
+       * examining the offset in the furthest included corner x1 - 1, y1 - 1.
        */
-      const unsigned x_align = 8, y_align = dst.num_samples != 0 ? 8 : 4;
-      x0 = ROUND_DOWN_TO(x0, x_align) * 2;
-      y0 = ROUND_DOWN_TO(y0, y_align) / 2;
-      x1 = ALIGN(x1, x_align) * 2;
-      y1 = ALIGN(y1, y_align) / 2;
-      dst.width = ALIGN(dst.width, x_align) * 2;
-      dst.height = ALIGN(dst.height, y_align) / 2;
+      static const unsigned make_exclusive = 1;
+      const unsigned stride = dst_mt->region->pitch;
+      const intptr_t min_off = intel_offset_S8(stride, x0, y0,
+                                               brw->has_swizzling);
+      const intptr_t max_off = intel_offset_S8(stride, x1 - 1, y1 - 1,
+                                               brw->has_swizzling);
+      y0 = ROUND_DOWN_TO(min_off, stride) / stride;
+      y1 = ALIGN(max_off, stride) / stride + make_exclusive;
+      x1 = dst_mt->region->pitch;
+      x0 = 0;
       wm_prog_key.use_kill = true;
    }
-
-   if (src.map_stencil_as_y_tiled) {
-      /* We must modify the size and x/y offset of the source surface to
-       * account for the fact that we are mapping it as Y-tiled when it is in
-       * fact W tiled.
-       *
-       * See the comments above concerning x/y offset alignment for the
-       * destination surface.
-       *
-       * TODO: what if this makes the texture size too large?
-       */
-      const unsigned x_align = 8, y_align = src.num_samples != 0 ? 8 : 4;
-      src.width = ALIGN(src.width, x_align) * 2;
-      src.height = ALIGN(src.height, y_align) / 2;
-   }
 }
 
 uint32_t
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
index 4b6430b..3551a20 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -391,15 +391,9 @@ gen6_blorp_emit_surface_state(struct brw_context *brw,
               (width - 1) << BRW_SURFACE_WIDTH_SHIFT |
               (height - 1) << BRW_SURFACE_HEIGHT_SHIFT);
 
-   uint32_t tiling = surface->map_stencil_as_y_tiled
-      ? BRW_SURFACE_TILED | BRW_SURFACE_TILED_Y
-      : brw_get_surface_tiling_bits(region->tiling);
-   uint32_t pitch_bytes = region->pitch;
-   if (surface->map_stencil_as_y_tiled)
-      pitch_bytes *= 2;
-   surf[3] = (tiling |
+   surf[3] = (brw_get_surface_tiling_bits(region->tiling) |
               0 << BRW_SURFACE_DEPTH_SHIFT |
-              (pitch_bytes - 1) << BRW_SURFACE_PITCH_SHIFT);
+              SET_FIELD(region->pitch - 1, BRW_SURFACE_PITCH));
 
    surf[4] = surface->map_stencil_as_y_tiled ?
       0 : brw_get_surface_num_multisamples(surface->num_samples);
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index ab76bee..93fd970 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -153,16 +153,13 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
    uint32_t tile_x = 0, tile_y = 0;
    const uint8_t mocs = GEN7_MOCS_L3;
 
-   uint32_t tiling = surface->map_stencil_as_y_tiled
-      ? I915_TILING_Y : region->tiling;
-
    uint32_t *surf = (uint32_t *)
       brw_state_batch(brw, AUB_TRACE_SURFACE_STATE, 8 * 4, 32, &wm_surf_offset);
    memset(surf, 0, 8 * 4);
 
    surf[0] = BRW_SURFACE_2D << BRW_SURFACE_TYPE_SHIFT |
              surface->brw_surfaceformat << BRW_SURFACE_FORMAT_SHIFT |
-             gen7_surface_tiling_mode(tiling);
+             gen7_surface_tiling_mode(region->tiling);
 
    if (surface->mt->align_h == 4)
       surf[0] |= GEN7_SURFACE_VALIGN_4;
@@ -193,10 +190,7 @@ gen7_blorp_emit_surface_state(struct brw_context *brw,
    surf[2] = SET_FIELD(width - 1, GEN7_SURFACE_WIDTH) |
              SET_FIELD(height - 1, GEN7_SURFACE_HEIGHT);
 
-   uint32_t pitch_bytes = region->pitch;
-   if (surface->map_stencil_as_y_tiled)
-      pitch_bytes *= 2;
-   surf[3] = pitch_bytes - 1;
+   surf[3] = region->pitch - 1;
 
    if (surface->map_stencil_as_y_tiled)
       surf[4] = 0;
-- 
1.8.3.1



More information about the mesa-dev mailing list