isl: Don't align phys_level0_sa by block dimension
authorNanley Chery <nanley.g.chery@intel.com>
Mon, 20 May 2019 21:50:23 +0000 (14:50 -0700)
committerNanley Chery <nanleychery@gmail.com>
Thu, 27 Jun 2019 23:38:38 +0000 (23:38 +0000)
Aligning phys_level0_sa by the compression block dimension prior to
mipmap layout causes the layout of compressed surfaces to differ from
the sampler's expectations in certain cases. The hardware docs agree:

From the BDW PRM, Vol. 5, Compressed Mipmap Layout,

   The compressed mipmaps are stored in a similar fashion to
   uncompressed mipmaps [...]

   The following exceptions apply to the layout of compressed (vs.
   uncompressed) mipmaps:
      * [...]
      * The dimensions of the mip maps are first determined by applying
the sizing algorithm presented in Non-Power-of-Two Mipmaps
above. Then, if necessary, they are padded out to compression
block boundaries.

The last bullet indicates that alignment should not be done for
calculating a miplevel's dimensions, but rather for determining miplevel
placement/padding. Comply with this text by removing the extra
alignment.

Fixes some fbo-generatemipmap-formats piglit failures on all tested
platforms (SNB-KBL).

v2:
- Note fixed platforms.
- Update some consumers via a helper function.

Cc: <mesa-stable@lists.freedesktop.org>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/isl/isl.c
src/intel/isl/isl.h

index 43ad8561c7e796a7812d0a8190a04c3d7be456fe..6e027277993437005a3cea35b01a6217c5bd5a9d 100644 (file)
@@ -717,7 +717,7 @@ isl_surf_choose_dim_layout(const struct isl_device *dev,
 
 /**
  * Calculate the physical extent of the surface's first level, in units of
- * surface samples. The result is aligned to the format's compression block.
+ * surface samples.
  */
 static void
 isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
@@ -746,8 +746,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
       case ISL_DIM_LAYOUT_GEN4_2D:
       case ISL_DIM_LAYOUT_GEN6_STENCIL_HIZ:
          *phys_level0_sa = (struct isl_extent4d) {
-            .w = isl_align_npot(info->width, fmtl->bw),
-            .h = fmtl->bh,
+            .w = info->width,
+            .h = 1,
             .d = 1,
             .a = info->array_len,
          };
@@ -771,8 +771,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
          assert(info->samples == 1);
 
          *phys_level0_sa = (struct isl_extent4d) {
-            .w = isl_align_npot(info->width, fmtl->bw),
-            .h = isl_align_npot(info->height, fmtl->bh),
+            .w = info->width,
+            .h = info->height,
             .d = 1,
             .a = info->array_len,
          };
@@ -807,9 +807,6 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
          isl_msaa_interleaved_scale_px_to_sa(info->samples,
                                              &phys_level0_sa->w,
                                              &phys_level0_sa->h);
-
-         phys_level0_sa->w = isl_align(phys_level0_sa->w, fmtl->bw);
-         phys_level0_sa->h = isl_align(phys_level0_sa->h, fmtl->bh);
          break;
       }
       break;
@@ -832,8 +829,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
          assert(ISL_DEV_GEN(dev) >= 9);
 
          *phys_level0_sa = (struct isl_extent4d) {
-            .w = isl_align_npot(info->width, fmtl->bw),
-            .h = isl_align_npot(info->height, fmtl->bh),
+            .w = info->width,
+            .h = info->height,
             .d = 1,
             .a = info->depth,
          };
@@ -842,8 +839,8 @@ isl_calc_phys_level0_extent_sa(const struct isl_device *dev,
       case ISL_DIM_LAYOUT_GEN4_3D:
          assert(ISL_DEV_GEN(dev) < 9);
          *phys_level0_sa = (struct isl_extent4d) {
-            .w = isl_align(info->width, fmtl->bw),
-            .h = isl_align(info->height, fmtl->bh),
+            .w = info->width,
+            .h = info->height,
             .d = info->depth,
             .a = 1,
          };
@@ -968,13 +965,10 @@ isl_calc_phys_slice0_extent_sa_gen4_2d(
       const struct isl_extent4d *phys_level0_sa,
       struct isl_extent2d *phys_slice0_sa)
 {
-   const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
-
    assert(phys_level0_sa->depth == 1);
 
    if (info->levels == 1) {
-      /* Do not pad the surface to the image alignment. Instead, pad it only
-       * to the pixel format's block alignment.
+      /* Do not pad the surface to the image alignment.
        *
        * For tiled surfaces, using a reduced alignment here avoids wasting CPU
        * cycles on the below mipmap layout caluclations. Reducing the
@@ -989,8 +983,8 @@ isl_calc_phys_slice0_extent_sa_gen4_2d(
        * VkBufferImageCopy::bufferRowLength.
        */
       *phys_slice0_sa = (struct isl_extent2d) {
-         .w = isl_align_npot(phys_level0_sa->w, fmtl->bw),
-         .h = isl_align_npot(phys_level0_sa->h, fmtl->bh),
+         .w = phys_level0_sa->w,
+         .h = phys_level0_sa->h,
       };
       return;
    }
@@ -1055,9 +1049,9 @@ isl_calc_phys_total_extent_el_gen4_2d(
                                            array_pitch_span,
                                            &phys_slice0_sa);
    *total_extent_el = (struct isl_extent2d) {
-      .w = isl_assert_div(phys_slice0_sa.w, fmtl->bw),
+      .w = isl_align_div_npot(phys_slice0_sa.w, fmtl->bw),
       .h = *array_pitch_el_rows * (phys_level0_sa->array_len - 1) +
-           isl_assert_div(phys_slice0_sa.h, fmtl->bh),
+           isl_align_div_npot(phys_slice0_sa.h, fmtl->bh),
    };
 }
 
@@ -1201,7 +1195,7 @@ isl_calc_phys_total_extent_el_gen9_1d(
 {
    MAYBE_UNUSED const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
 
-   assert(phys_level0_sa->height / fmtl->bh == 1);
+   assert(phys_level0_sa->height == 1);
    assert(phys_level0_sa->depth == 1);
    assert(info->samples == 1);
    assert(image_align_sa->w >= fmtl->bw);
@@ -1480,8 +1474,6 @@ isl_surf_init_s(const struct isl_device *dev,
    struct isl_extent4d phys_level0_sa;
    isl_calc_phys_level0_extent_sa(dev, info, dim_layout, tiling, msaa_layout,
                                   &phys_level0_sa);
-   assert(phys_level0_sa.w % fmtl->bw == 0);
-   assert(phys_level0_sa.h % fmtl->bh == 0);
 
    enum isl_array_pitch_span array_pitch_span =
       isl_choose_array_pitch_span(dev, info, dim_layout, &phys_level0_sa);
index 162301e4bf66123efc16e252987e945a45e69862..9fbc88ec83ed38159cf3529babf8c5c4672a2db0 100644 (file)
@@ -1176,7 +1176,7 @@ struct isl_surf {
 
    /**
     * Physical extent of the surface's base level, in units of physical
-    * surface samples and aligned to the format's compression block.
+    * surface samples.
     *
     * Consider isl_dim_layout as an operator that transforms a logical surface
     * layout to a physical surface layout. Then
@@ -1907,13 +1907,9 @@ isl_surf_get_phys_level0_el(const struct isl_surf *surf)
 {
    const struct isl_format_layout *fmtl = isl_format_get_layout(surf->format);
 
-   assert(surf->phys_level0_sa.w % fmtl->bw == 0);
-   assert(surf->phys_level0_sa.h % fmtl->bh == 0);
-   assert(surf->phys_level0_sa.d % fmtl->bd == 0);
-
-   return isl_extent4d(surf->phys_level0_sa.w / fmtl->bw,
-                       surf->phys_level0_sa.h / fmtl->bh,
-                       surf->phys_level0_sa.d / fmtl->bd,
+   return isl_extent4d(DIV_ROUND_UP(surf->phys_level0_sa.w, fmtl->bw),
+                       DIV_ROUND_UP(surf->phys_level0_sa.h, fmtl->bh),
+                       DIV_ROUND_UP(surf->phys_level0_sa.d, fmtl->bd),
                        surf->phys_level0_sa.a);
 }