[Mesa-dev] [v2 09/39] i965/gen6/hiz: Add direct buffer size resolver

Topi Pohjolainen topi.pohjolainen at gmail.com
Wed May 3 09:22:22 UTC 2017


The apparent hack adding unconditionally two lines into cube
maps is taken directly from align_cube().

v2: Apply the cube map hack also for non-mipmapped. But apply
    it only for cube-map, not for cube-map-array to keep things
    as they were (use mt->target == GL_TEXTURE_CUBE_MAP instead
    of _mesa_is_cube_map_texture(mt->target)).
v3: Take vertical alignment as argument allowing to be re-used
    for stencil. Also introduce all_slices_at_each_lod_aux_init()
    that hiz and stencil can both share.

Reviewed-by: Jason Ekstrand <jason at jlekstrand.net> (v1)
Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_tex_layout.c    | 37 +++++++++++++++++++++
 src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 47 ++++++++++++++++++++++-----
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |  6 ++++
 3 files changed, 82 insertions(+), 8 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 76d6ba0..b58a846 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -255,6 +255,43 @@ brw_hiz_all_slices_at_each_lod_offset(
    return level_y * pitch + level_x / halign * 4096;
 }
 
+uint32_t
+brw_all_slices_at_each_lod_total_height(
+   const struct isl_extent4d *phys_level0_sa,
+   enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+   unsigned last_level, unsigned valign)
+{
+   /* The 965's sampler lays cachelines out according to how accesses
+    * in the texture surfaces run, so they may be "vertical" through
+    * memory.  As a result, the docs say in Surface Padding Requirements:
+    * Sampling Engine Surfaces that two extra rows of padding are required.
+    */
+   const unsigned extra_padding = usage & ISL_SURF_USAGE_CUBE_BIT ? 2 : 0;
+   const unsigned second_level_y = all_slices_at_each_lod_y_offset(
+                                      phys_level0_sa, dim, valign, 1);
+
+   /* Second level would be just below first, and its start position is equal
+    * to the aligned size needed for the the first.
+    */
+   if (last_level == 0)
+      return second_level_y + extra_padding;
+
+   const unsigned last_level_y = all_slices_at_each_lod_y_offset(
+                                    phys_level0_sa, dim, valign, last_level);
+   const unsigned second_level_h =
+      phys_level0_sa->array_len *
+      ALIGN(minify(phys_level0_sa->height, 1), valign);
+   const unsigned last_level_h =
+      phys_level0_sa->array_len *
+      ALIGN(minify(phys_level0_sa->height, last_level), valign);
+
+   /* Choose the taller of the two: end of the second or end of the last. */
+   const unsigned total_h = MAX2(second_level_y + second_level_h,
+                                 last_level_y + last_level_h);
+
+   return ALIGN(total_h, valign) + extra_padding;
+}
+
 static void
 brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
 {
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
index 54ef1ba..d5267df 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -284,6 +284,38 @@ intel_depth_format_for_depthstencil_format(mesa_format format) {
    }
 }
 
+static void
+all_slices_at_each_lod_aux_init(struct brw_context *brw,
+                                const struct intel_mipmap_tree *mt,
+                                unsigned halign_bytes, unsigned valign,
+                                struct intel_miptree_aux_buffer *buf)
+{
+   const uint32_t format = translate_tex_format(brw, mt->format, false);
+   const unsigned cpp = isl_format_get_layout(format)->bpb / 8;
+   const unsigned halign = halign_bytes / cpp;
+   const enum isl_surf_dim dim = get_isl_surf_dim(mt->target);
+   const struct isl_extent4d phys_level0_sa = {
+     { mt->physical_width0 }, 
+     { mt->physical_height0 },              
+     { dim == ISL_SURF_DIM_3D ? mt->physical_depth0 : 1 },
+     { dim == ISL_SURF_DIM_3D ? 1 : mt->physical_depth0 } };
+   const isl_surf_usage_flags_t usage =
+      mt->target == GL_TEXTURE_CUBE_MAP ? ISL_SURF_USAGE_CUBE_BIT : 0;
+   const unsigned total_h = brw_all_slices_at_each_lod_total_height(
+      &phys_level0_sa, dim, usage, mt->last_level, valign);
+   const unsigned total_w = brw_get_mipmap_total_width(
+      phys_level0_sa.width, mt->last_level + 1, halign);
+
+   buf->pitch = total_w * cpp;
+   buf->size = total_h * buf->pitch;
+
+   /* On gen6 hiz is unconditionally laid out packing all slices
+    * at each level-of-detail (LOD). This means there is no valid qpitch
+    * setting. In fact, this is ignored when hardware is setup - there is no
+    * hardware qpitch setting of hiz on gen6.
+    */
+   buf->qpitch = 0;
+}
 
 /**
  * @param for_bo Indicates that the caller is
@@ -1810,16 +1842,15 @@ intel_hiz_miptree_buf_create(struct brw_context *brw,
       return NULL;
    }
 
+   const unsigned halign_bytes = 128;
+   const unsigned valign = 32;
+   all_slices_at_each_lod_aux_init(brw, mt, halign_bytes, valign,
+                                   &buf->aux_base);
+
    buf->aux_base.bo = buf->mt->bo;
-   buf->aux_base.size = buf->mt->total_height * buf->mt->pitch;
-   buf->aux_base.pitch = buf->mt->pitch;
 
-   /* On gen6 hiz is unconditionally laid out packing all slices
-    * at each level-of-detail (LOD). This means there is no valid qpitch
-    * setting. In fact, this is ignored when hardware is setup - there is no
-    * hardware qpitch setting of hiz on gen6.
-    */
-   buf->aux_base.qpitch = 0;
+   assert(buf->aux_base.pitch == buf->mt->pitch);
+   assert(buf->aux_base.size == buf->mt->total_height * buf->mt->pitch);
 
    return buf;
 }
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index 5707037..9495da0 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -986,6 +986,12 @@ brw_hiz_all_slices_at_each_lod_offset(
    enum isl_surf_dim dim, unsigned num_levels,
    enum isl_format format, unsigned level);
 
+uint32_t
+brw_all_slices_at_each_lod_total_height(
+   const struct isl_extent4d *phys_level0_sa, 
+   enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+   unsigned last_level, unsigned valign);
+
 bool
 brw_miptree_layout(struct brw_context *brw,
                    struct intel_mipmap_tree *mt,
-- 
2.9.3



More information about the mesa-dev mailing list