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

Topi Pohjolainen topi.pohjolainen at gmail.com
Mon Feb 27 07:27:52 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)).

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 | 23 +++++++++++++++--
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h |  5 ++++
 3 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 3db2857..1cca9a5 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -380,6 +380,43 @@ brw_hiz_all_slices_at_each_lod_offset(
    return level_y * pitch + level_x / halign * 4096;
 }
 
+uint32_t
+gen6_get_hiz_total_height(const struct isl_extent4d *phys_level0_sa,
+                          enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+                          unsigned last_level)
+{
+   /* 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 valign = 32;
+   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 b339f99..c20a3d4 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c
@@ -1900,9 +1900,28 @@ intel_hiz_miptree_buf_create(struct brw_context *brw,
       return NULL;
    }
 
+   const uint32_t format = translate_tex_format(brw, mt->format, false);
+   const unsigned cpp = isl_format_get_layout(format)->bpb / 8;
+   const unsigned halign = 128 / 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 = gen6_get_hiz_total_height(
+      &phys_level0_sa, dim, usage, mt->last_level);
+   const unsigned total_w = brw_get_mipmap_total_width(
+      phys_level0_sa.width, mt->last_level + 1, halign);
+
    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;
+   buf->aux_base.pitch = total_w * cpp;
+   buf->aux_base.size = total_h * buf->aux_base.pitch;
+
+   assert(buf->aux_base.pitch == buf->mt->pitch);
+   assert(buf->aux_base.size == buf->mt->total_height * 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
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index ae146d8..2a3438a 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -996,6 +996,11 @@ brw_hiz_all_slices_at_each_lod_offset(
    enum isl_surf_dim dim, unsigned num_levels,
    enum isl_format format, unsigned level);
 
+uint32_t
+gen6_get_hiz_total_height(const struct isl_extent4d *phys_level0_sa, 
+                          enum isl_surf_dim dim, isl_surf_usage_flags_t usage,
+                          unsigned last_level);
+
 bool
 brw_miptree_layout(struct brw_context *brw,
                    struct intel_mipmap_tree *mt,
-- 
2.9.3



More information about the mesa-dev mailing list