- const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
- uint32_t pitch_sa_rows = 0;
-
- switch (dim_layout) {
- case ISL_DIM_LAYOUT_GEN9_1D:
- /* Each row is an array slice */
- pitch_sa_rows = 1;
- break;
- case ISL_DIM_LAYOUT_GEN4_2D:
- switch (array_pitch_span) {
- case ISL_ARRAY_PITCH_SPAN_COMPACT:
- pitch_sa_rows = isl_align_npot(phys_slice0_sa->h, image_align_sa->h);
- break;
- case ISL_ARRAY_PITCH_SPAN_FULL: {
- /* The QPitch equation is found in the Broadwell PRM >> Volume 5:
- * Memory Views >> Common Surface Formats >> Surface Layout >> 2D
- * Surfaces >> Surface Arrays.
- */
- uint32_t H0_sa = phys_level0_sa->h;
- uint32_t H1_sa = isl_minify(H0_sa, 1);
-
- uint32_t h0_sa = isl_align_npot(H0_sa, image_align_sa->h);
- uint32_t h1_sa = isl_align_npot(H1_sa, image_align_sa->h);
-
- uint32_t m;
- if (ISL_DEV_GEN(dev) >= 7) {
- /* The QPitch equation changed slightly in Ivybridge. */
- m = 12;
- } else {
- m = 11;
- }
-
- pitch_sa_rows = h0_sa + h1_sa + (m * image_align_sa->h);
-
- if (ISL_DEV_GEN(dev) == 6 && info->samples > 1 &&
- (info->height % 4 == 1)) {
- /* [SNB] Errata from the Sandy Bridge PRM >> Volume 4 Part 1:
- * Graphics Core >> Section 7.18.3.7: Surface Arrays:
- *
- * [SNB] Errata: Sampler MSAA Qpitch will be 4 greater than
- * the value calculated in the equation above , for every
- * other odd Surface Height starting from 1 i.e. 1,5,9,13.
- *
- * XXX(chadv): Is the errata natural corollary of the physical
- * layout of interleaved samples?
- */
- pitch_sa_rows += 4;
- }
-
- pitch_sa_rows = isl_align_npot(pitch_sa_rows, fmtl->bh);
- } /* end case */
- break;
- }
- break;
- case ISL_DIM_LAYOUT_GEN4_3D:
- assert(array_pitch_span == ISL_ARRAY_PITCH_SPAN_COMPACT);
- pitch_sa_rows = isl_align_npot(phys_slice0_sa->h, image_align_sa->h);
- break;
- default:
- unreachable("bad isl_dim_layout");
- break;
- }
-
- assert(pitch_sa_rows % fmtl->bh == 0);
- uint32_t pitch_el_rows = pitch_sa_rows / fmtl->bh;
-
- if (ISL_DEV_GEN(dev) >= 9 && fmtl->txc == ISL_TXC_CCS) {
- /*
- * From the Sky Lake PRM Vol 7, "MCS Buffer for Render Target(s)" (p. 632):
- *
- * "Mip-mapped and arrayed surfaces are supported with MCS buffer
- * layout with these alignments in the RT space: Horizontal
- * Alignment = 128 and Vertical Alignment = 64."
- *
- * From the Sky Lake PRM Vol. 2d, "RENDER_SURFACE_STATE" (p. 435):
- *
- * "For non-multisampled render target's CCS auxiliary surface,
- * QPitch must be computed with Horizontal Alignment = 128 and
- * Surface Vertical Alignment = 256. These alignments are only for
- * CCS buffer and not for associated render target."
- *
- * The first restriction is already handled by isl_choose_image_alignment_el
- * but the second restriction, which is an extension of the first, only
- * applies to qpitch and must be applied here.
- */
- assert(fmtl->bh == 4);
- pitch_el_rows = isl_align(pitch_el_rows, 256 / 4);
- }
-
- if (ISL_DEV_GEN(dev) >= 9 &&
- info->dim == ISL_SURF_DIM_3D &&
- tile_info->tiling != ISL_TILING_LINEAR) {
- /* From the Skylake BSpec >> RENDER_SURFACE_STATE >> Surface QPitch:
- *
- * Tile Mode != Linear: This field must be set to an integer multiple
- * of the tile height
- */
- pitch_el_rows = isl_align(pitch_el_rows, tile_info->logical_extent_el.height);
- }
-
- return pitch_el_rows;
-}
-
-/**
- * Calculate the pitch of each surface row, in bytes.
- */
-static uint32_t
-isl_calc_linear_row_pitch(const struct isl_device *dev,
- const struct isl_surf_init_info *restrict info,
- const struct isl_extent2d *phys_slice0_sa)
-{
- const struct isl_format_layout *fmtl = isl_format_get_layout(info->format);
-
- uint32_t row_pitch = info->min_pitch;
-
- /* First, align the surface to a cache line boundary, as the PRM explains
- * below.
- *
- * From the Broadwell PRM >> Volume 5: Memory Views >> Common Surface
- * Formats >> Surface Padding Requirements >> Render Target and Media
- * Surfaces:
- *
- * The data port accesses data (pixels) outside of the surface if they
- * are contained in the same cache request as pixels that are within the
- * surface. These pixels will not be returned by the requesting message,
- * however if these pixels lie outside of defined pages in the GTT,
- * a GTT error will result when the cache request is processed. In order
- * to avoid these GTT errors, “padding” at the bottom of the surface is
- * sometimes necessary.
- *
- * From the Broadwell PRM >> Volume 5: Memory Views >> Common Surface
- * Formats >> Surface Padding Requirements >> Sampling Engine Surfaces:
- *
- * The sampling engine accesses texels outside of the surface if they
- * are contained in the same cache line as texels that are within the
- * surface. These texels will not participate in any calculation
- * performed by the sampling engine and will not affect the result of
- * any sampling engine operation, however if these texels lie outside of
- * defined pages in the GTT, a GTT error will result when the cache line
- * is accessed. In order to avoid these GTT errors, “padding” at the
- * bottom and right side of a sampling engine surface is sometimes
- * necessary.
- *
- * It is possible that a cache line will straddle a page boundary if the
- * base address or pitch is not aligned. All pages included in the cache
- * lines that are part of the surface must map to valid GTT entries to
- * avoid errors. To determine the necessary padding on the bottom and
- * right side of the surface, refer to the table in Alignment Unit Size
- * section for the i and j parameters for the surface format in use. The
- * surface must then be extended to the next multiple of the alignment
- * unit size in each dimension, and all texels contained in this
- * extended surface must have valid GTT entries.
- *
- * For example, suppose the surface size is 15 texels by 10 texels and
- * the alignment parameters are i=4 and j=2. In this case, the extended
- * surface would be 16 by 10. Note that these calculations are done in
- * texels, and must be converted to bytes based on the surface format
- * being used to determine whether additional pages need to be defined.
- */
- assert(phys_slice0_sa->w % fmtl->bw == 0);
- const uint32_t bs = fmtl->bpb / 8;
- row_pitch = MAX(row_pitch, bs * (phys_slice0_sa->w / fmtl->bw));