[Mesa-dev] [PATCH 13/27] i965/gen6: Calculate hiz offset on demand

Topi Pohjolainen topi.pohjolainen at gmail.com
Mon Jan 16 09:13:48 UTC 2017


This is kept on purpose in i965. It can be moved to ISL if it
is needed in vulkan.

Pointers to miptrees are given solely for verification purposes.
These will be dropped in following patches.

Signed-off-by: Topi Pohjolainen <topi.pohjolainen at intel.com>
---
 src/mesa/drivers/dri/i965/brw_tex_layout.c    | 44 +++++++++++++++++++++++++++
 src/mesa/drivers/dri/i965/gen6_depth_state.c  | 18 ++++++++---
 src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 11 +++++++
 3 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 80b341a..6f1c228 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -353,6 +353,50 @@ brw_stencil_all_slices_at_each_lod_offset(const struct isl_surf *surf,
    return level_y * two_rows_interleaved_pitch + level_x * 64;
 }
 
+uint32_t
+brw_get_mipmap_total_width(unsigned w0, unsigned num_levels, unsigned halign)
+{
+   /* If there is not level two, no adjustment is needed. */
+   if (num_levels < 2)
+      return ALIGN(w0, halign);
+
+   const uint32_t w1 = ALIGN(minify(w0, 1), halign);
+   const uint32_t w2 = minify(w0, 2);
+
+   /* Levels one and two sit side-by-side below level zero. Due to alignment
+    * of level one levels one and two may require more space than level zero.
+    */
+   return ALIGN(MAX2(w0, w1 + w2), halign);
+}
+
+uint32_t
+brw_hiz_all_slices_at_each_lod_offset(
+   const struct isl_extent4d *phys_level0_sa,
+   enum isl_surf_dim dim, unsigned num_levels,
+   enum isl_format format,
+   const struct intel_mipmap_tree *mt,
+   unsigned level)
+{
+   assert(mt->array_layout == ALL_SLICES_AT_EACH_LOD);
+
+   const uint32_t cpp = isl_format_get_layout(format)->bpb / 8;
+   const uint32_t halign = 128 / cpp;
+   const uint32_t valign = 32;
+   const uint32_t level_x = all_slices_at_each_lod_x_offset(
+                               phys_level0_sa->width, halign, level);
+   const uint32_t level_y = all_slices_at_each_lod_y_offset(
+                               phys_level0_sa, dim, valign, level);
+   const uint32_t pitch = brw_get_mipmap_total_width(
+                             phys_level0_sa->width, num_levels, halign) * cpp;
+
+   assert(level_x == mt->level[level].level_x);
+   assert(level_y == mt->level[level].level_y);
+   assert(pitch == mt->pitch);
+   assert(cpp == mt->cpp);
+
+   return level_y * pitch + level_x / halign * 4096;
+}
+
 static void
 brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
 {
diff --git a/src/mesa/drivers/dri/i965/gen6_depth_state.c b/src/mesa/drivers/dri/i965/gen6_depth_state.c
index 80cb890..05565de 100644
--- a/src/mesa/drivers/dri/i965/gen6_depth_state.c
+++ b/src/mesa/drivers/dri/i965/gen6_depth_state.c
@@ -165,10 +165,20 @@ gen6_emit_depth_stencil_hiz(struct brw_context *brw,
 
          assert(hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD);
 
-         const uint32_t offset = intel_miptree_get_aligned_offset(
-                                    hiz_mt,
-                                    hiz_mt->level[lod].level_x,
-                                    hiz_mt->level[lod].level_y);
+         struct isl_surf temp_surf;
+         intel_miptree_get_isl_surf(brw, mt, &temp_surf);
+
+         /* Main and hiz surfaces agree on the base level dimensions and
+          * format. Therefore one can calculate against the main surface.
+          */
+         const uint32_t offset = brw_hiz_all_slices_at_each_lod_offset(
+            &temp_surf.phys_level0_sa, temp_surf.dim, temp_surf.levels,
+            temp_surf.format, hiz_mt, lod);
+
+         assert(offset == intel_miptree_get_aligned_offset(
+                             hiz_mt,
+                             hiz_mt->level[lod].level_x,
+                             hiz_mt->level[lod].level_y));
 
 	 BEGIN_BATCH(3);
 	 OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2));
diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
index e51872f..11c61c2 100644
--- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
+++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h
@@ -984,10 +984,21 @@ brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
                                      unsigned level);
 
 uint32_t
+brw_get_mipmap_total_width(unsigned w0, unsigned num_levels, unsigned halign);
+
+uint32_t
 brw_stencil_all_slices_at_each_lod_offset(const struct isl_surf *surf,
                                           const struct intel_mipmap_tree *mt,
                                           uint32_t level);
 
+uint32_t
+brw_hiz_all_slices_at_each_lod_offset(
+   const struct isl_extent4d *phys_level0_sa, 
+   enum isl_surf_dim dim, unsigned num_levels,
+   enum isl_format format,
+   const struct intel_mipmap_tree *mt,
+   unsigned level);
+
 void
 brw_miptree_layout(struct brw_context *brw,
                    struct intel_mipmap_tree *mt,
-- 
2.5.5



More information about the mesa-dev mailing list