- if (target == GL_TEXTURE_1D_ARRAY)
- assert(height0 == 1);
-
- mt->target = target;
- mt->format = format;
- mt->first_level = first_level;
- mt->last_level = last_level;
- mt->logical_width0 = width0;
- mt->logical_height0 = height0;
- mt->logical_depth0 = depth0;
- mt->aux_disable = (layout_flags & MIPTREE_LAYOUT_DISABLE_AUX) != 0 ?
- INTEL_AUX_DISABLE_ALL : INTEL_AUX_DISABLE_NONE;
- mt->aux_disable |= INTEL_AUX_DISABLE_CCS;
- mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0;
- mt->aux_state = NULL;
- mt->cpp = _mesa_get_format_bytes(format);
- mt->num_samples = num_samples;
- mt->compressed = _mesa_is_format_compressed(format);
- mt->msaa_layout = INTEL_MSAA_LAYOUT_NONE;
- mt->refcount = 1;
-
- if (brw->gen == 6 && format == MESA_FORMAT_S_UINT8)
- layout_flags |= MIPTREE_LAYOUT_GEN6_HIZ_STENCIL;
-
- int depth_multiply = 1;
- if (num_samples > 1) {
- /* Adjust width/height/depth for MSAA */
- mt->msaa_layout = compute_msaa_layout(brw, format, mt->aux_disable);
- if (mt->msaa_layout == INTEL_MSAA_LAYOUT_IMS) {
- /* From the Ivybridge PRM, Volume 1, Part 1, page 108:
- * "If the surface is multisampled and it is a depth or stencil
- * surface or Multisampled Surface StorageFormat in SURFACE_STATE is
- * MSFMT_DEPTH_STENCIL, WL and HL must be adjusted as follows before
- * proceeding:
- *
- * +----------------------------------------------------------------+
- * | Num Multisamples | W_l = | H_l = |
- * +----------------------------------------------------------------+
- * | 2 | ceiling(W_l / 2) * 4 | H_l (no adjustment) |
- * | 4 | ceiling(W_l / 2) * 4 | ceiling(H_l / 2) * 4 |
- * | 8 | ceiling(W_l / 2) * 8 | ceiling(H_l / 2) * 4 |
- * | 16 | ceiling(W_l / 2) * 8 | ceiling(H_l / 2) * 8 |
- * +----------------------------------------------------------------+
- * "
- *
- * Note that MSFMT_DEPTH_STENCIL just means the IMS (interleaved)
- * format rather than UMS/CMS (array slices). The Sandybridge PRM,
- * Volume 1, Part 1, Page 111 has the same formula for 4x MSAA.
- *
- * Another more complicated explanation for these adjustments comes
- * from the Sandybridge PRM, volume 4, part 1, page 31:
- *
- * "Any of the other messages (sample*, LOD, load4) used with a
- * (4x) multisampled surface will in-effect sample a surface with
- * double the height and width as that indicated in the surface
- * state. Each pixel position on the original-sized surface is
- * replaced with a 2x2 of samples with the following arrangement:
- *
- * sample 0 sample 2
- * sample 1 sample 3"
- *
- * Thus, when sampling from a multisampled texture, it behaves as
- * though the layout in memory for (x,y,sample) is:
- *
- * (0,0,0) (0,0,2) (1,0,0) (1,0,2)
- * (0,0,1) (0,0,3) (1,0,1) (1,0,3)
- *
- * (0,1,0) (0,1,2) (1,1,0) (1,1,2)
- * (0,1,1) (0,1,3) (1,1,1) (1,1,3)
- *
- * However, the actual layout of multisampled data in memory is:
- *
- * (0,0,0) (1,0,0) (0,0,1) (1,0,1)
- * (0,1,0) (1,1,0) (0,1,1) (1,1,1)
- *
- * (0,0,2) (1,0,2) (0,0,3) (1,0,3)
- * (0,1,2) (1,1,2) (0,1,3) (1,1,3)
- *
- * This pattern repeats for each 2x2 pixel block.
- *
- * As a result, when calculating the size of our 4-sample buffer for
- * an odd width or height, we have to align before scaling up because
- * sample 3 is in that bottom right 2x2 block.
- */
- switch (num_samples) {
- case 2:
- assert(brw->gen >= 8);
- width0 = ALIGN(width0, 2) * 2;
- height0 = ALIGN(height0, 2);
- break;
- case 4:
- width0 = ALIGN(width0, 2) * 2;
- height0 = ALIGN(height0, 2) * 2;
- break;
- case 8:
- width0 = ALIGN(width0, 2) * 4;
- height0 = ALIGN(height0, 2) * 2;
- break;
- case 16:
- width0 = ALIGN(width0, 2) * 4;
- height0 = ALIGN(height0, 2) * 4;
- break;
- default:
- /* num_samples should already have been quantized to 0, 1, 2, 4, 8
- * or 16.
- */
- unreachable("not reached");
- }
- } else {
- /* Non-interleaved */
- depth_multiply = num_samples;
- depth0 *= depth_multiply;
- }
- }
-
- if (!create_mapping_table(target, first_level, last_level, depth0,
- mt->level)) {
- free(mt);
- return NULL;
- }
-
- /* Set array_layout to ALL_SLICES_AT_EACH_LOD when array_spacing_lod0 can
- * be used. array_spacing_lod0 is only used for non-IMS MSAA surfaces on
- * Gen 7 and 8. On Gen 8 and 9 this layout is not available but it is still
- * used on Gen8 to make it pick a qpitch value which doesn't include space
- * for the mipmaps. On Gen9 this is not necessary because it will
- * automatically pick a packed qpitch value whenever mt->first_level ==
- * mt->last_level.
- * TODO: can we use it elsewhere?
- * TODO: also disable this on Gen8 and pick the qpitch value like Gen9
- */
- if (brw->gen >= 9) {
- mt->array_layout = ALL_LOD_IN_EACH_SLICE;
- } else {
- switch (mt->msaa_layout) {
- case INTEL_MSAA_LAYOUT_NONE:
- case INTEL_MSAA_LAYOUT_IMS:
- mt->array_layout = ALL_LOD_IN_EACH_SLICE;
- break;
- case INTEL_MSAA_LAYOUT_UMS:
- case INTEL_MSAA_LAYOUT_CMS:
- mt->array_layout = ALL_SLICES_AT_EACH_LOD;
- break;
- }
- }
-
- if (target == GL_TEXTURE_CUBE_MAP)
- assert(depth0 == 6 * depth_multiply);
-
- mt->physical_width0 = width0;
- mt->physical_height0 = height0;
- mt->physical_depth0 = depth0;