i965: Fix 3D texture layout by more literally copying from the spec.
authorEric Anholt <eric@anholt.net>
Tue, 8 Oct 2013 07:19:23 +0000 (00:19 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 9 Oct 2013 18:28:19 +0000 (11:28 -0700)
Fixes 3 texelFetch tests in piglit all.tests on ivb, and cubemap npot on gm45.

v2: Don't forget the gen4 DL=6 cubemap behavior.

Cc: "9.1 9.2" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Chad Versace <chad.versace@linux.intel.com> (v1)
src/mesa/drivers/dri/i965/brw_tex_layout.c

index e9128a38244cabc98c742059e67e4c60d401ef45..d912862e50bf2a9781bd772ede04f8350bf7028b 100644 (file)
@@ -240,69 +240,34 @@ static void
 brw_miptree_layout_texture_3d(struct brw_context *brw,
                               struct intel_mipmap_tree *mt)
 {
-   unsigned width  = mt->physical_width0;
-   unsigned height = mt->physical_height0;
-   unsigned depth = mt->physical_depth0;
-   unsigned pack_x_pitch, pack_x_nr;
-   unsigned pack_y_pitch;
+   unsigned yscale = mt->compressed ? 4 : 1;
 
+   mt->total_width = 0;
    mt->total_height = 0;
 
-   if (mt->compressed) {
-       mt->total_width = ALIGN(width, mt->align_w);
-       pack_y_pitch = (height + 3) / 4;
-   } else {
-      mt->total_width = mt->physical_width0;
-      pack_y_pitch = ALIGN(mt->physical_height0, mt->align_h);
-   }
-
-   pack_x_pitch = width;
-   pack_x_nr = 1;
-
+   unsigned ysum = 0;
    for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
-      int x = 0;
-      int y = 0;
-
-      intel_miptree_set_level_info(mt, level,
-                                   0, mt->total_height,
-                                   width, height, depth);
-
-      for (int q = 0; q < depth; /* empty */) {
-         for (int j = 0; j < pack_x_nr && q < depth; j++, q++) {
-            intel_miptree_set_image_offset(mt, level, q, x, y);
-            x += pack_x_pitch;
-         }
-         if (x > mt->total_width)
-            mt->total_width = x;
-
-         x = 0;
-         y += pack_y_pitch;
-      }
+      unsigned WL = MAX2(mt->physical_width0 >> level, 1);
+      unsigned HL = MAX2(mt->physical_height0 >> level, 1);
+      unsigned DL = MAX2(mt->physical_depth0 >> level, 1);
+      unsigned wL = ALIGN(WL, mt->align_w);
+      unsigned hL = ALIGN(HL, mt->align_h);
 
-      mt->total_height += y;
-      width  = minify(width, 1);
-      height = minify(height, 1);
-      if (mt->target == GL_TEXTURE_3D)
-         depth = minify(depth, 1);
+      if (mt->target == GL_TEXTURE_CUBE_MAP)
+         DL = 6;
 
-      if (mt->compressed) {
-         pack_y_pitch = (height + 3) / 4;
+      intel_miptree_set_level_info(mt, level, 0, 0, WL, HL, DL);
 
-         if (pack_x_pitch > ALIGN(width, mt->align_w)) {
-            pack_x_pitch = ALIGN(width, mt->align_w);
-            pack_x_nr <<= 1;
-         }
-      } else {
-         pack_x_nr <<= 1;
-         if (pack_x_pitch > 4) {
-            pack_x_pitch >>= 1;
-         }
-
-         if (pack_y_pitch > 2) {
-            pack_y_pitch >>= 1;
-            pack_y_pitch = ALIGN(pack_y_pitch, mt->align_h);
-         }
+      for (unsigned q = 0; q < DL; q++) {
+         unsigned x = (q % (1 << level)) * wL;
+         unsigned y = ysum + (q >> level) * hL;
+
+         intel_miptree_set_image_offset(mt, level, q, x, y / yscale);
+         mt->total_width = MAX2(mt->total_width, x + wL);
+         mt->total_height = MAX2(mt->total_height, (y + hL) / yscale);
       }
+
+      ysum += ALIGN(DL, 1 << level) / (1 << level) * hL;
    }
 
    align_cube(mt);