+static void
+brw_miptree_layout_texture_array(struct brw_context *brw,
+ struct intel_mipmap_tree *mt)
+{
+ int h0, h1;
+ unsigned height = mt->physical_height0;
+
+ h0 = ALIGN(mt->physical_height0, mt->align_h);
+ 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);
+
+ int physical_qpitch = mt->compressed ? mt->qpitch / 4 : mt->qpitch;
+
+ brw_miptree_layout_2d(mt);
+
+ for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
+ unsigned img_height;
+ img_height = ALIGN(height, mt->align_h);
+ if (mt->compressed)
+ img_height /= mt->align_h;
+
+ for (int q = 0; q < mt->physical_depth0; q++) {
+ if (mt->array_layout == ALL_SLICES_AT_EACH_LOD) {
+ intel_miptree_set_image_offset(mt, level, q, 0, q * img_height);
+ } else {
+ intel_miptree_set_image_offset(mt, level, q, 0, q * physical_qpitch);
+ }
+ }
+ height = minify(height, 1);
+ }
+ if (mt->array_layout == ALL_LOD_IN_EACH_SLICE)
+ mt->total_height = physical_qpitch * mt->physical_depth0;
+
+ align_cube(mt);
+}
+
+static void
+brw_miptree_layout_texture_3d(struct brw_context *brw,
+ struct intel_mipmap_tree *mt)
+{
+ unsigned yscale = mt->compressed ? 4 : 1;
+
+ mt->total_width = 0;
+ mt->total_height = 0;
+
+ unsigned ysum = 0;
+ for (unsigned level = mt->first_level; level <= mt->last_level; level++) {
+ 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);
+
+ if (mt->target == GL_TEXTURE_CUBE_MAP)
+ DL = 6;
+
+ intel_miptree_set_level_info(mt, level, 0, 0, DL);
+
+ 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);
+}
+