[Mesa-dev] [v3 18/19] i965/gen6: Use back-to-back layout for stencil surfaces

Topi Pohjolainen topi.pohjolainen at gmail.com
Mon May 15 12:08:08 UTC 2017


Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_blorp.c         | 21 +++++++++++++----
 src/mesa/drivers/dri/i965/gen6_depth_state.c  | 26 +++++++-------------
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 34 ++++++++++++++++++++++++++-
 3 files changed, 58 insertions(+), 23 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c
index b69cb4f..7c2f7b5 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.c
+++ b/src/mesa/drivers/dri/i965/brw_blorp.c
@@ -161,7 +161,6 @@ blorp_surf_for_miptree(struct brw_context *brw,
          intel_miptree_check_level_layer(mt, *level, start_layer + i);
    }
 
-   intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]);
    surf->surf = &tmp_surfs[0];
    surf->addr = (struct blorp_address) {
       .buffer = mt->bo,
@@ -171,8 +170,9 @@ blorp_surf_for_miptree(struct brw_context *brw,
       .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0,
    };
 
-   if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8 &&
-       mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
+   if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8) {
+      assert(mt->array_layout == GEN6_BACK_TO_BACK);
+
       /* Sandy bridge stencil and HiZ use this ALL_SLICES_AT_EACH_LOD hack in
        * order to allow for layered rendering.  The hack makes each LOD of the
        * stencil or HiZ buffer a single tightly packed array surface at some
@@ -183,10 +183,21 @@ blorp_surf_for_miptree(struct brw_context *brw,
        *
        * See also gen6_depth_stencil_state.c
        */
-      uint32_t offset;
-      apply_gen6_stencil_hiz_offset(&tmp_surfs[0], mt, *level, &offset);
+      uint32_t x_offset_sa, y_offset_sa;
+      gen6_back_to_back_offset(&mt->surf, *level, 0,
+                               &x_offset_sa, &y_offset_sa);
+      assert(x_offset_sa == 0);
+
+      /* Pitch represents two rows interleaved. */
+      const uint32_t offset = y_offset_sa * mt->surf.row_pitch / 2;
+
       surf->addr.offset += offset;
+
+      tmp_surfs[0] = gen6_back_to_back_minify(&mt->surf, *level);
+
       *level = 0;
+   } else {
+      intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]);
    }
 
    struct isl_surf *aux_surf = &tmp_surfs[1];
diff --git a/src/mesa/drivers/dri/i965/gen6_depth_state.c b/src/mesa/drivers/dri/i965/gen6_depth_state.c
index 0ff2407..36d92f0 100644
--- a/src/mesa/drivers/dri/i965/gen6_depth_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_depth_state.c
@@ -188,27 +188,19 @@ gen6_emit_depth_stencil_hiz(struct brw_context *brw,
 
       /* Emit stencil buffer. */
       if (separate_stencil) {
-         uint32_t offset = 0;
-
-         if (stencil_mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
-            assert(stencil_mt->format == MESA_FORMAT_S_UINT8);
+         assert(stencil_mt->surf.size > 0);
 
-            /* Note: we can't compute the stencil offset using
-             * intel_region_get_aligned_offset(), because stencil_region
-             * claims that the region is untiled even though it's W tiled.
-             */
-            offset = stencil_mt->level[lod].level_y * stencil_mt->pitch +
-                     stencil_mt->level[lod].level_x * 64;
-         }
+         uint32_t x_offset_sa, y_offset_sa;
+         gen6_back_to_back_offset(&stencil_mt->surf, lod, 0,
+                                  &x_offset_sa, &y_offset_sa);
+         assert(x_offset_sa == 0);
+         
+         /* Pitch represents two rows interleaved. */
+         const uint32_t offset = y_offset_sa * stencil_mt->surf.row_pitch / 2;
 
 	 BEGIN_BATCH(3);
 	 OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2));
-         /* The stencil buffer has quirky pitch requirements.  From Vol 2a,
-          * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch":
-          *    The pitch must be set to 2x the value computed based on width, as
-          *    the stencil buffer is stored with two rows interleaved.
-          */
-	 OUT_BATCH(2 * stencil_mt->pitch - 1);
+	 OUT_BATCH(stencil_mt->surf.row_pitch - 1);
 	 OUT_RELOC(stencil_mt->bo,
 		   I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER,
 		   offset);
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index df5a954..4721d22 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -602,6 +602,24 @@ intel_lower_compressed_format(struct brw_context *brw, mesa_format format)
    }
 }
 
+static void
+gen6_stencil_override(struct isl_surf *surf, unsigned levels)
+{
+   surf->levels = levels;
+
+   const struct isl_extent3d image_align_sa =
+      isl_surf_get_image_alignment_sa(surf);
+   const uint32_t total_h = gen6_back_to_back_total_height(
+                                &surf->phys_level0_sa, &image_align_sa,
+                                surf->dim, surf->tiling, surf->levels);
+
+   /* Pitch represents two rows interleaved. */
+   surf->size = total_h * surf->row_pitch / 2;
+
+   /* There is no such thing with back-to-back layout. */
+   surf->array_pitch_el_rows = 0;
+}
+
 static struct intel_mipmap_tree *
 make_surface(struct brw_context *brw, GLenum target, mesa_format format,
              unsigned first_level, unsigned last_level,
@@ -630,6 +648,8 @@ make_surface(struct brw_context *brw, GLenum target, mesa_format format,
        num_samples, width0, height0, depth0,
        first_level, last_level, mt);
 
+   const bool is_gen6_stencil = brw->gen == 6 &&
+                                format == MESA_FORMAT_S_UINT8;
 
    struct isl_surf_init_info init_info = {
       .dim = get_isl_surf_dim(target),
@@ -637,7 +657,7 @@ make_surface(struct brw_context *brw, GLenum target, mesa_format format,
       .width = width0,
       .height = height0,
       .depth = target == GL_TEXTURE_3D ? depth0 : 1,
-      .levels = last_level + 1,
+      .levels = is_gen6_stencil ? 1 : last_level + 1,
       .array_len = target == GL_TEXTURE_3D ? 1 : depth0,
       .samples = MAX2(num_samples, 1),
       .usage = isl_usage_flags, 
@@ -647,6 +667,11 @@ make_surface(struct brw_context *brw, GLenum target, mesa_format format,
    if (!isl_surf_init_s(&brw->isl_dev, &mt->surf, &init_info))
       goto fail;
 
+   if (is_gen6_stencil) {
+      mt->array_layout = GEN6_BACK_TO_BACK;
+      gen6_stencil_override(&mt->surf, last_level + 1);
+   }
+
    assert(mt->surf.size % mt->surf.row_pitch == 0);
 
    unsigned pitch = mt->surf.row_pitch;
@@ -686,6 +711,13 @@ miptree_create(struct brw_context *brw,
                GLuint num_samples,
                uint32_t layout_flags)
 {
+   if (brw->gen == 6 && format == MESA_FORMAT_S_UINT8)
+      return make_surface(brw, target, format, first_level, last_level,
+                          width0, height0, depth0, num_samples, ISL_TILING_W,
+                          ISL_SURF_USAGE_STENCIL_BIT |
+                          ISL_SURF_USAGE_TEXTURE_BIT,
+                          BO_ALLOC_FOR_RENDER);
+
    struct intel_mipmap_tree *mt;
    mesa_format tex_format = format;
    mesa_format etc_format = MESA_FORMAT_NONE;
-- 
2.9.3



More information about the mesa-dev mailing list