i965: Add helper functions to calculate the slice pitch of an array or 3D miptree.
authorFrancisco Jerez <currojerez@riseup.net>
Wed, 22 Apr 2015 18:32:49 +0000 (21:32 +0300)
committerFrancisco Jerez <currojerez@riseup.net>
Mon, 27 Apr 2015 14:28:28 +0000 (17:28 +0300)
src/mesa/drivers/dri/i965/brw_tex_layout.c
src/mesa/drivers/dri/i965/intel_mipmap_tree.h

index 440ba6c2ca47b745c6b050904b11fc7bba32a40c..d1ac3ed53b1aae937e4e3eac8e84718cd89de914 100644 (file)
@@ -263,6 +263,66 @@ brw_miptree_layout_2d(struct intel_mipmap_tree *mt)
    }
 }
 
+unsigned
+brw_miptree_get_horizontal_slice_pitch(const struct brw_context *brw,
+                                       const struct intel_mipmap_tree *mt,
+                                       unsigned level)
+{
+   assert(brw->gen < 9);
+
+   if (mt->target == GL_TEXTURE_3D ||
+       (brw->gen == 4 && mt->target == GL_TEXTURE_CUBE_MAP)) {
+      return ALIGN(minify(mt->physical_width0, level), mt->align_w);
+   } else {
+      return 0;
+   }
+}
+
+unsigned
+brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
+                                     const struct intel_mipmap_tree *mt,
+                                     unsigned level)
+{
+   if (brw->gen >= 9) {
+      /* ALL_SLICES_AT_EACH_LOD isn't supported on Gen8+ but this code will
+       * effectively end up with a packed qpitch anyway whenever
+       * mt->first_level == mt->last_level.
+       */
+      assert(mt->array_layout != ALL_SLICES_AT_EACH_LOD);
+
+      /* On Gen9 we can pick whatever qpitch we like as long as it's aligned
+       * to the vertical alignment so we don't need to add any extra rows.
+       */
+      unsigned qpitch = mt->total_height;
+
+      /* If the surface might be used as a stencil buffer or HiZ buffer then
+       * it needs to be a multiple of 8.
+       */
+      const GLenum base_format = _mesa_get_format_base_format(mt->format);
+      if (_mesa_is_depth_or_stencil_format(base_format))
+         qpitch = ALIGN(qpitch, 8);
+
+      /* 3D textures need to be aligned to the tile height. At this point we
+       * don't know which tiling will be used so let's just align it to 32
+       */
+      if (mt->target == GL_TEXTURE_3D)
+         qpitch = ALIGN(qpitch, 32);
+
+      return qpitch;
+
+   } else if (mt->target == GL_TEXTURE_3D ||
+              (brw->gen == 4 && mt->target == GL_TEXTURE_CUBE_MAP) ||
+              mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
+      return ALIGN(minify(mt->physical_height0, level), mt->align_h);
+
+   } else {
+      const unsigned h0 = ALIGN(mt->physical_height0, mt->align_h);
+      const unsigned h1 = ALIGN(minify(mt->physical_height0, 1), mt->align_h);
+
+      return h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->align_h;
+   }
+}
+
 static void
 align_cube(struct intel_mipmap_tree *mt)
 {
@@ -318,47 +378,13 @@ brw_miptree_layout_texture_array(struct brw_context *brw,
        * this case it's always 64). The vertical alignment is ignored.
        */
       mt->qpitch = mt->total_width;
-   } else if (brw->gen >= 9) {
-      GLenum base_format;
-
-      /* ALL_SLICES_AT_EACH_LOD isn't supported on Gen8+ but this code will
-       * effectively end up with a packed qpitch anyway whenever
-       * mt->first_level == mt->last_level.
-       */
-      assert(mt->array_layout != ALL_SLICES_AT_EACH_LOD);
-
-      /* On Gen9 we can pick whatever qpitch we like as long as it's aligned
-       * to the vertical alignment so we don't need to add any extra rows.
-       */
-      mt->qpitch = mt->total_height;
-
-      /* If the surface might be used as a stencil buffer or HiZ buffer then
-       * it needs to be a multiple of 8.
-       */
-      base_format = _mesa_get_format_base_format(mt->format);
-      if (_mesa_is_depth_or_stencil_format(base_format))
-         mt->qpitch = ALIGN(mt->qpitch, 8);
-
-      /* 3D textures need to be aligned to the tile height. At this point we
-       * don't know which tiling will be used so let's just align it to 32
-       */
-      if (mt->target == GL_TEXTURE_3D)
-         mt->qpitch = ALIGN(mt->qpitch, 32);
-
-      /* Unlike previous generations the qpitch is now a multiple of the
-       * compressed block size so physical_qpitch matches mt->qpitch.
-       */
-      physical_qpitch = mt->qpitch;
    } else {
-      int h0 = ALIGN(mt->physical_height0, mt->align_h);
-      int h1 = ALIGN(minify(mt->physical_height0, 1), mt->align_h);
-
-      if (mt->array_layout == ALL_SLICES_AT_EACH_LOD)
-         mt->qpitch = h0;
-      else
-         mt->qpitch = (h0 + h1 + (brw->gen >= 7 ? 12 : 11) * mt->align_h);
-
-      physical_qpitch = mt->compressed ? mt->qpitch / 4 : mt->qpitch;
+      mt->qpitch = brw_miptree_get_vertical_slice_pitch(brw, mt, 0);
+      /* Unlike previous generations the qpitch is a multiple of the
+       * compressed block size on Gen9 so physical_qpitch matches mt->qpitch.
+       */
+      physical_qpitch = (mt->compressed && brw->gen < 9 ? mt->qpitch / 4 :
+                         mt->qpitch);
    }
 
    for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
index 77b029452b45100e11c1b013d3034ec15698ff91..8b42e4adb79af7aa336ef4102ed53cb00aabde6a 100644 (file)
@@ -735,6 +735,24 @@ intel_miptree_updownsample(struct brw_context *brw,
                            struct intel_mipmap_tree *src,
                            struct intel_mipmap_tree *dst);
 
+/**
+ * Horizontal distance from one slice to the next in the two-dimensional
+ * miptree layout.
+ */
+unsigned
+brw_miptree_get_horizontal_slice_pitch(const struct brw_context *brw,
+                                       const struct intel_mipmap_tree *mt,
+                                       unsigned level);
+
+/**
+ * Vertical distance from one slice to the next in the two-dimensional miptree
+ * layout.
+ */
+unsigned
+brw_miptree_get_vertical_slice_pitch(const struct brw_context *brw,
+                                     const struct intel_mipmap_tree *mt,
+                                     unsigned level);
+
 void brw_miptree_layout(struct brw_context *brw, struct intel_mipmap_tree *mt);
 
 void *intel_miptree_map_raw(struct brw_context *brw,