1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2015 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci *  Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci *  copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci *  to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci *  and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci *  Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci *  The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci *  paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci *  Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci *  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci *  IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "isl_gfx7.h"
25bf215546Sopenharmony_ci#include "isl_priv.h"
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_cistatic bool
28bf215546Sopenharmony_cigfx7_format_needs_valign2(const struct isl_device *dev,
29bf215546Sopenharmony_ci                          enum isl_format format)
30bf215546Sopenharmony_ci{
31bf215546Sopenharmony_ci   assert(ISL_GFX_VER(dev) == 7);
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci   /* From the Ivybridge PRM (2012-05-31), Volume 4, Part 1, Section 2.12.1,
34bf215546Sopenharmony_ci    * RENDER_SURFACE_STATE Surface Vertical Alignment:
35bf215546Sopenharmony_ci    *
36bf215546Sopenharmony_ci    *    - Value of 1 [VALIGN_4] is not supported for format YCRCB_NORMAL
37bf215546Sopenharmony_ci    *      (0x182), YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY
38bf215546Sopenharmony_ci    *      (0x190)
39bf215546Sopenharmony_ci    *
40bf215546Sopenharmony_ci    *    - VALIGN_4 is not supported for surface format R32G32B32_FLOAT.
41bf215546Sopenharmony_ci    *
42bf215546Sopenharmony_ci    * The R32G32B32_FLOAT restriction is dropped on Haswell.
43bf215546Sopenharmony_ci    */
44bf215546Sopenharmony_ci   return isl_format_is_yuv(format) ||
45bf215546Sopenharmony_ci          (format == ISL_FORMAT_R32G32B32_FLOAT && !ISL_DEV_IS_HASWELL(dev));
46bf215546Sopenharmony_ci}
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_cibool
49bf215546Sopenharmony_ciisl_gfx7_choose_msaa_layout(const struct isl_device *dev,
50bf215546Sopenharmony_ci                            const struct isl_surf_init_info *info,
51bf215546Sopenharmony_ci                            enum isl_tiling tiling,
52bf215546Sopenharmony_ci                            enum isl_msaa_layout *msaa_layout)
53bf215546Sopenharmony_ci{
54bf215546Sopenharmony_ci   bool require_array = false;
55bf215546Sopenharmony_ci   bool require_interleaved = false;
56bf215546Sopenharmony_ci
57bf215546Sopenharmony_ci   assert(ISL_GFX_VER(dev) == 7);
58bf215546Sopenharmony_ci   assert(info->samples >= 1);
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci   if (info->samples == 1) {
61bf215546Sopenharmony_ci      *msaa_layout = ISL_MSAA_LAYOUT_NONE;
62bf215546Sopenharmony_ci      return true;
63bf215546Sopenharmony_ci   }
64bf215546Sopenharmony_ci
65bf215546Sopenharmony_ci   if (!isl_format_supports_multisampling(dev->info, info->format))
66bf215546Sopenharmony_ci      return false;
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   /* From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
69bf215546Sopenharmony_ci    * Multisamples:
70bf215546Sopenharmony_ci    *
71bf215546Sopenharmony_ci    *    - If this field is any value other than MULTISAMPLECOUNT_1, the
72bf215546Sopenharmony_ci    *      Surface Type must be SURFTYPE_2D.
73bf215546Sopenharmony_ci    *
74bf215546Sopenharmony_ci    *    - If this field is any value other than MULTISAMPLECOUNT_1, Surface
75bf215546Sopenharmony_ci    *      Min LOD, Mip Count / LOD, and Resource Min LOD must be set to zero
76bf215546Sopenharmony_ci    */
77bf215546Sopenharmony_ci   if (info->dim != ISL_SURF_DIM_2D)
78bf215546Sopenharmony_ci      return false;
79bf215546Sopenharmony_ci   if (info->levels > 1)
80bf215546Sopenharmony_ci      return false;
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci   /* The Ivyrbridge PRM insists twice that signed integer formats cannot be
83bf215546Sopenharmony_ci    * multisampled.
84bf215546Sopenharmony_ci    *
85bf215546Sopenharmony_ci    * From the Ivybridge PRM, Volume 4 Part 1 p73, SURFACE_STATE, Number of
86bf215546Sopenharmony_ci    * Multisamples:
87bf215546Sopenharmony_ci    *
88bf215546Sopenharmony_ci    *    - This field must be set to MULTISAMPLECOUNT_1 for SINT MSRTs when
89bf215546Sopenharmony_ci    *      all RT channels are not written.
90bf215546Sopenharmony_ci    *
91bf215546Sopenharmony_ci    * And errata from the Ivybridge PRM, Volume 4 Part 1 p77,
92bf215546Sopenharmony_ci    * RENDER_SURFACE_STATE, MCS Enable:
93bf215546Sopenharmony_ci    *
94bf215546Sopenharmony_ci    *   This field must be set to 0 [MULTISAMPLECOUNT_1] for all SINT MSRTs
95bf215546Sopenharmony_ci    *   when all RT channels are not written.
96bf215546Sopenharmony_ci    *
97bf215546Sopenharmony_ci    * Note that the above SINT restrictions apply only to *MSRTs* (that is,
98bf215546Sopenharmony_ci    * *multisampled* render targets). The restrictions seem to permit an MCS
99bf215546Sopenharmony_ci    * if the render target is singlesampled.
100bf215546Sopenharmony_ci    *
101bf215546Sopenharmony_ci    * Moreover, empirically it looks that hardware can render multisampled
102bf215546Sopenharmony_ci    * surfaces with RGBA8I, RGBA16I and RGBA32I.
103bf215546Sopenharmony_ci    */
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   /* Multisampling requires vertical alignment of four. */
106bf215546Sopenharmony_ci   if (info->samples > 1 && gfx7_format_needs_valign2(dev, info->format))
107bf215546Sopenharmony_ci      return false;
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   /* More obvious restrictions */
110bf215546Sopenharmony_ci   if (isl_surf_usage_is_display(info->usage))
111bf215546Sopenharmony_ci      return false;
112bf215546Sopenharmony_ci   if (tiling == ISL_TILING_LINEAR)
113bf215546Sopenharmony_ci      return false;
114bf215546Sopenharmony_ci
115bf215546Sopenharmony_ci   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
116bf215546Sopenharmony_ci    * Surface Storage Format:
117bf215546Sopenharmony_ci    *
118bf215546Sopenharmony_ci    *    +---------------------+----------------------------------------------------------------+
119bf215546Sopenharmony_ci    *    | MSFMT_MSS           | Multsampled surface was/is rendered as a render target         |
120bf215546Sopenharmony_ci    *    | MSFMT_DEPTH_STENCIL | Multisampled surface was rendered as a depth or stencil buffer |
121bf215546Sopenharmony_ci    *    +---------------------+----------------------------------------------------------------+
122bf215546Sopenharmony_ci    *
123bf215546Sopenharmony_ci    * In the table above, MSFMT_MSS refers to ISL_MSAA_LAYOUT_ARRAY, and
124bf215546Sopenharmony_ci    * MSFMT_DEPTH_STENCIL refers to ISL_MSAA_LAYOUT_INTERLEAVED.
125bf215546Sopenharmony_ci    */
126bf215546Sopenharmony_ci   if (isl_surf_usage_is_depth_or_stencil(info->usage) ||
127bf215546Sopenharmony_ci       (info->usage & ISL_SURF_USAGE_HIZ_BIT))
128bf215546Sopenharmony_ci      require_interleaved = true;
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_ci   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
131bf215546Sopenharmony_ci    * Surface Storage Format:
132bf215546Sopenharmony_ci    *
133bf215546Sopenharmony_ci    *    If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8, Width
134bf215546Sopenharmony_ci    *    is >= 8192 (meaning the actual surface width is >= 8193 pixels), this
135bf215546Sopenharmony_ci    *    field must be set to MSFMT_MSS.
136bf215546Sopenharmony_ci    */
137bf215546Sopenharmony_ci   if (info->samples == 8 && info->width > 8192)
138bf215546Sopenharmony_ci      require_array = true;
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_ci   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
141bf215546Sopenharmony_ci    * Surface Storage Format:
142bf215546Sopenharmony_ci    *
143bf215546Sopenharmony_ci    *    If the surface’s Number of Multisamples is MULTISAMPLECOUNT_8,
144bf215546Sopenharmony_ci    *    ((Depth+1) * (Height+1)) is > 4,194,304, OR if the surface’s Number
145bf215546Sopenharmony_ci    *    of Multisamples is MULTISAMPLECOUNT_4, ((Depth+1) * (Height+1)) is
146bf215546Sopenharmony_ci    *    > 8,388,608, this field must be set to MSFMT_DEPTH_STENCIL.
147bf215546Sopenharmony_ci    */
148bf215546Sopenharmony_ci   if ((info->samples == 8 && info->height > 4194304u) ||
149bf215546Sopenharmony_ci       (info->samples == 4 && info->height > 8388608u))
150bf215546Sopenharmony_ci      require_interleaved = true;
151bf215546Sopenharmony_ci
152bf215546Sopenharmony_ci   /* From the Ivybridge PRM, Volume 4 Part 1 p72, SURFACE_STATE, Multisampled
153bf215546Sopenharmony_ci    * Surface Storage Format:
154bf215546Sopenharmony_ci    *
155bf215546Sopenharmony_ci    *    This field must be set to MSFMT_DEPTH_STENCIL if Surface Format is
156bf215546Sopenharmony_ci    *    one of the following: I24X8_UNORM, L24X8_UNORM, A24X8_UNORM, or
157bf215546Sopenharmony_ci    *    R24_UNORM_X8_TYPELESS.
158bf215546Sopenharmony_ci    */
159bf215546Sopenharmony_ci   if (info->format == ISL_FORMAT_I24X8_UNORM ||
160bf215546Sopenharmony_ci       info->format == ISL_FORMAT_L24X8_UNORM ||
161bf215546Sopenharmony_ci       info->format == ISL_FORMAT_A24X8_UNORM ||
162bf215546Sopenharmony_ci       info->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS)
163bf215546Sopenharmony_ci      require_interleaved = true;
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   if (require_array && require_interleaved)
166bf215546Sopenharmony_ci      return false;
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ci   if (require_interleaved) {
169bf215546Sopenharmony_ci      *msaa_layout = ISL_MSAA_LAYOUT_INTERLEAVED;
170bf215546Sopenharmony_ci      return true;
171bf215546Sopenharmony_ci   }
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci   /* Default to the array layout because it permits multisample
174bf215546Sopenharmony_ci    * compression.
175bf215546Sopenharmony_ci    */
176bf215546Sopenharmony_ci   *msaa_layout = ISL_MSAA_LAYOUT_ARRAY;
177bf215546Sopenharmony_ci   return true;
178bf215546Sopenharmony_ci}
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_ci/**
181bf215546Sopenharmony_ci * @brief Filter out tiling flags that are incompatible with the surface.
182bf215546Sopenharmony_ci *
183bf215546Sopenharmony_ci * The resultant outgoing @a flags is a subset of the incoming @a flags. The
184bf215546Sopenharmony_ci * outgoing flags may be empty (0x0) if the incoming flags were too
185bf215546Sopenharmony_ci * restrictive.
186bf215546Sopenharmony_ci *
187bf215546Sopenharmony_ci * For example, if the surface will be used for a display
188bf215546Sopenharmony_ci * (ISL_SURF_USAGE_DISPLAY_BIT), then this function filters out all tiling
189bf215546Sopenharmony_ci * flags except ISL_TILING_X_BIT and ISL_TILING_LINEAR_BIT.
190bf215546Sopenharmony_ci */
191bf215546Sopenharmony_civoid
192bf215546Sopenharmony_ciisl_gfx6_filter_tiling(const struct isl_device *dev,
193bf215546Sopenharmony_ci                       const struct isl_surf_init_info *restrict info,
194bf215546Sopenharmony_ci                       isl_tiling_flags_t *flags)
195bf215546Sopenharmony_ci{
196bf215546Sopenharmony_ci   /* IVB+ requires separate stencil */
197bf215546Sopenharmony_ci   assert(ISL_DEV_USE_SEPARATE_STENCIL(dev));
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   /* Clear flags unsupported on this hardware */
200bf215546Sopenharmony_ci   assert(ISL_GFX_VERX10(dev) < 125);
201bf215546Sopenharmony_ci   if (ISL_GFX_VER(dev) >= 12) {
202bf215546Sopenharmony_ci      *flags &= ISL_TILING_LINEAR_BIT |
203bf215546Sopenharmony_ci                ISL_TILING_X_BIT |
204bf215546Sopenharmony_ci                ISL_TILING_ANY_Y_MASK;
205bf215546Sopenharmony_ci   } else if (ISL_GFX_VER(dev) >= 9) {
206bf215546Sopenharmony_ci      *flags &= ISL_TILING_LINEAR_BIT |
207bf215546Sopenharmony_ci                ISL_TILING_X_BIT |
208bf215546Sopenharmony_ci                ISL_TILING_W_BIT |
209bf215546Sopenharmony_ci                ISL_TILING_ANY_Y_MASK;
210bf215546Sopenharmony_ci   } else {
211bf215546Sopenharmony_ci      *flags &= ISL_TILING_LINEAR_BIT |
212bf215546Sopenharmony_ci                ISL_TILING_X_BIT |
213bf215546Sopenharmony_ci                ISL_TILING_W_BIT |
214bf215546Sopenharmony_ci                ISL_TILING_Y0_BIT;
215bf215546Sopenharmony_ci   }
216bf215546Sopenharmony_ci
217bf215546Sopenharmony_ci   /* And... clear the Yf and Ys bits anyway because Anvil doesn't support
218bf215546Sopenharmony_ci    * them yet.
219bf215546Sopenharmony_ci    */
220bf215546Sopenharmony_ci   *flags &= ~ISL_TILING_Yf_BIT; /* FINISHME[SKL]: Support Yf */
221bf215546Sopenharmony_ci   *flags &= ~ISL_TILING_Ys_BIT; /* FINISHME[SKL]: Support Ys */
222bf215546Sopenharmony_ci
223bf215546Sopenharmony_ci   if (isl_surf_usage_is_depth(info->usage)) {
224bf215546Sopenharmony_ci      /* Depth requires Y. */
225bf215546Sopenharmony_ci      *flags &= ISL_TILING_ANY_Y_MASK;
226bf215546Sopenharmony_ci   }
227bf215546Sopenharmony_ci
228bf215546Sopenharmony_ci   if (isl_surf_usage_is_stencil(info->usage)) {
229bf215546Sopenharmony_ci      if (ISL_GFX_VER(dev) >= 12) {
230bf215546Sopenharmony_ci         /* Stencil requires Y. */
231bf215546Sopenharmony_ci         *flags &= ISL_TILING_ANY_Y_MASK;
232bf215546Sopenharmony_ci      } else {
233bf215546Sopenharmony_ci         /* Stencil requires W. */
234bf215546Sopenharmony_ci         *flags &= ISL_TILING_W_BIT;
235bf215546Sopenharmony_ci      }
236bf215546Sopenharmony_ci   } else {
237bf215546Sopenharmony_ci      *flags &= ~ISL_TILING_W_BIT;
238bf215546Sopenharmony_ci   }
239bf215546Sopenharmony_ci
240bf215546Sopenharmony_ci   /* MCS buffers are always Y-tiled */
241bf215546Sopenharmony_ci   if (isl_format_get_layout(info->format)->txc == ISL_TXC_MCS)
242bf215546Sopenharmony_ci      *flags &= ISL_TILING_Y0_BIT;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci   if (info->usage & ISL_SURF_USAGE_DISPLAY_BIT) {
245bf215546Sopenharmony_ci      if (ISL_GFX_VER(dev) >= 12) {
246bf215546Sopenharmony_ci         *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT |
247bf215546Sopenharmony_ci                    ISL_TILING_Y0_BIT);
248bf215546Sopenharmony_ci      } else if (ISL_GFX_VER(dev) >= 9) {
249bf215546Sopenharmony_ci         /* Note we let Yf even though it was cleared above. This is just for
250bf215546Sopenharmony_ci          * completeness.
251bf215546Sopenharmony_ci          */
252bf215546Sopenharmony_ci         *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT |
253bf215546Sopenharmony_ci                    ISL_TILING_Y0_BIT | ISL_TILING_Yf_BIT);
254bf215546Sopenharmony_ci      } else {
255bf215546Sopenharmony_ci         /* Before Skylake, the display engine does not accept Y */
256bf215546Sopenharmony_ci         *flags &= (ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT);
257bf215546Sopenharmony_ci      }
258bf215546Sopenharmony_ci   }
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci   if (info->samples > 1) {
261bf215546Sopenharmony_ci      /* From the Sandybridge PRM, Volume 4 Part 1, SURFACE_STATE Tiled
262bf215546Sopenharmony_ci       * Surface:
263bf215546Sopenharmony_ci       *
264bf215546Sopenharmony_ci       *   For multisample render targets, this field must be 1 (true). MSRTs
265bf215546Sopenharmony_ci       *   can only be tiled.
266bf215546Sopenharmony_ci       *
267bf215546Sopenharmony_ci       * From the Broadwell PRM >> Volume2d: Command Structures >>
268bf215546Sopenharmony_ci       * RENDER_SURFACE_STATE Tile Mode:
269bf215546Sopenharmony_ci       *
270bf215546Sopenharmony_ci       *   If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
271bf215546Sopenharmony_ci       *   must be YMAJOR.
272bf215546Sopenharmony_ci       *
273bf215546Sopenharmony_ci       * As usual, though, stencil is special and requires W-tiling.
274bf215546Sopenharmony_ci       */
275bf215546Sopenharmony_ci      *flags &= (ISL_TILING_ANY_Y_MASK | ISL_TILING_W_BIT);
276bf215546Sopenharmony_ci   }
277bf215546Sopenharmony_ci
278bf215546Sopenharmony_ci   /* workaround */
279bf215546Sopenharmony_ci   if (ISL_GFX_VER(dev) == 7 &&
280bf215546Sopenharmony_ci       gfx7_format_needs_valign2(dev, info->format) &&
281bf215546Sopenharmony_ci       (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) &&
282bf215546Sopenharmony_ci       info->samples == 1) {
283bf215546Sopenharmony_ci      /* Y tiling is illegal. From the Ivybridge PRM, Vol4 Part1 2.12.2.1,
284bf215546Sopenharmony_ci       * SURFACE_STATE Surface Vertical Alignment:
285bf215546Sopenharmony_ci       *
286bf215546Sopenharmony_ci       *     This field must be set to VALIGN_4 for all tiled Y Render Target
287bf215546Sopenharmony_ci       *     surfaces.
288bf215546Sopenharmony_ci       */
289bf215546Sopenharmony_ci      *flags &= ~ISL_TILING_Y0_BIT;
290bf215546Sopenharmony_ci   }
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci   /* From the Sandybridge PRM, Volume 1, Part 2, page 32:
293bf215546Sopenharmony_ci    *
294bf215546Sopenharmony_ci    *    "NOTE: 128BPE Format Color Buffer ( render target ) MUST be either
295bf215546Sopenharmony_ci    *     TileX or Linear."
296bf215546Sopenharmony_ci    *
297bf215546Sopenharmony_ci    * This is necessary all the way back to 965, but is permitted on Gfx7+.
298bf215546Sopenharmony_ci    */
299bf215546Sopenharmony_ci   if (ISL_GFX_VER(dev) < 7 && isl_format_get_layout(info->format)->bpb >= 128)
300bf215546Sopenharmony_ci      *flags &= ~ISL_TILING_Y0_BIT;
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   /* From the BDW and SKL PRMs, Volume 2d,
303bf215546Sopenharmony_ci    * RENDER_SURFACE_STATE::Width - Programming Notes:
304bf215546Sopenharmony_ci    *
305bf215546Sopenharmony_ci    *   A known issue exists if a primitive is rendered to the first 2 rows and
306bf215546Sopenharmony_ci    *   last 2 columns of a 16K width surface. If any geometry is drawn inside
307bf215546Sopenharmony_ci    *   this square it will be copied to column X=2 and X=3 (arrangement on Y
308bf215546Sopenharmony_ci    *   position will stay the same). If any geometry exceeds the boundaries of
309bf215546Sopenharmony_ci    *   this 2x2 region it will be drawn normally. The issue also only occurs
310bf215546Sopenharmony_ci    *   if the surface has TileMode != Linear.
311bf215546Sopenharmony_ci    *
312bf215546Sopenharmony_ci    * [Internal documentation notes that this issue isn't present on SKL GT4.]
313bf215546Sopenharmony_ci    * To prevent this rendering corruption, only allow linear tiling for
314bf215546Sopenharmony_ci    * surfaces with widths greater than 16K-2 pixels.
315bf215546Sopenharmony_ci    *
316bf215546Sopenharmony_ci    * TODO: Is this an issue for multisampled surfaces as well?
317bf215546Sopenharmony_ci    */
318bf215546Sopenharmony_ci   if (info->width > 16382 && info->samples == 1 &&
319bf215546Sopenharmony_ci       info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT &&
320bf215546Sopenharmony_ci       (ISL_GFX_VER(dev) == 8 ||
321bf215546Sopenharmony_ci        (dev->info->platform == INTEL_PLATFORM_SKL && dev->info->gt != 4))) {
322bf215546Sopenharmony_ci          *flags &= ISL_TILING_LINEAR_BIT;
323bf215546Sopenharmony_ci   }
324bf215546Sopenharmony_ci}
325bf215546Sopenharmony_ci
326bf215546Sopenharmony_civoid
327bf215546Sopenharmony_ciisl_gfx7_choose_image_alignment_el(const struct isl_device *dev,
328bf215546Sopenharmony_ci                                   const struct isl_surf_init_info *restrict info,
329bf215546Sopenharmony_ci                                   enum isl_tiling tiling,
330bf215546Sopenharmony_ci                                   enum isl_dim_layout dim_layout,
331bf215546Sopenharmony_ci                                   enum isl_msaa_layout msaa_layout,
332bf215546Sopenharmony_ci                                   struct isl_extent3d *image_align_el)
333bf215546Sopenharmony_ci{
334bf215546Sopenharmony_ci   assert(ISL_GFX_VER(dev) == 7);
335bf215546Sopenharmony_ci
336bf215546Sopenharmony_ci   /* Handled by isl_choose_image_alignment_el */
337bf215546Sopenharmony_ci   assert(info->format != ISL_FORMAT_HIZ);
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ci   /* IVB+ does not support combined depthstencil. */
340bf215546Sopenharmony_ci   assert(!isl_surf_usage_is_depth_and_stencil(info->usage));
341bf215546Sopenharmony_ci
342bf215546Sopenharmony_ci   /* From the Ivy Bridge PRM, Vol. 2, Part 2, Section 6.18.4.4,
343bf215546Sopenharmony_ci    * "Alignment unit size", the alignment parameters are summarized in the
344bf215546Sopenharmony_ci    * following table:
345bf215546Sopenharmony_ci    *
346bf215546Sopenharmony_ci    *     Surface Defined By | Surface Format  | Align Width | Align Height
347bf215546Sopenharmony_ci    *    --------------------+-----------------+-------------+--------------
348bf215546Sopenharmony_ci    *       DEPTH_BUFFER     |   D16_UNORM     |      8      |      4
349bf215546Sopenharmony_ci    *                        |     other       |      4      |      4
350bf215546Sopenharmony_ci    *    --------------------+-----------------+-------------+--------------
351bf215546Sopenharmony_ci    *       STENCIL_BUFFER   |      N/A        |      8      |      8
352bf215546Sopenharmony_ci    *    --------------------+-----------------+-------------+--------------
353bf215546Sopenharmony_ci    *       SURFACE_STATE    | BC*, ETC*, EAC* |      4      |      4
354bf215546Sopenharmony_ci    *                        |      FXT1       |      8      |      4
355bf215546Sopenharmony_ci    *                        |   all others    |   HALIGN    |   VALIGN
356bf215546Sopenharmony_ci    *    -------------------------------------------------------------------
357bf215546Sopenharmony_ci    */
358bf215546Sopenharmony_ci   if (isl_surf_usage_is_depth(info->usage)) {
359bf215546Sopenharmony_ci      *image_align_el = info->format == ISL_FORMAT_R16_UNORM ?
360bf215546Sopenharmony_ci                        isl_extent3d(8, 4, 1) : isl_extent3d(4, 4, 1);
361bf215546Sopenharmony_ci      return;
362bf215546Sopenharmony_ci   } else if (isl_surf_usage_is_stencil(info->usage)) {
363bf215546Sopenharmony_ci      *image_align_el = isl_extent3d(8, 8, 1);
364bf215546Sopenharmony_ci      return;
365bf215546Sopenharmony_ci   } else if (isl_format_is_compressed(info->format)) {
366bf215546Sopenharmony_ci      /* Compressed formats all have alignment equal to block size. */
367bf215546Sopenharmony_ci      *image_align_el = isl_extent3d(1, 1, 1);
368bf215546Sopenharmony_ci      return;
369bf215546Sopenharmony_ci   }
370bf215546Sopenharmony_ci
371bf215546Sopenharmony_ci   /* Everything after this point is in the "set by Surface Horizontal or
372bf215546Sopenharmony_ci    * Vertical Alignment" case.  Now it's just a matter of applying
373bf215546Sopenharmony_ci    * restrictions.
374bf215546Sopenharmony_ci    */
375bf215546Sopenharmony_ci
376bf215546Sopenharmony_ci   /* There are no restrictions on halign beyond what's given in the table
377bf215546Sopenharmony_ci    * above.  We set it to the minimum value of 4 because that uses the least
378bf215546Sopenharmony_ci    * memory.
379bf215546Sopenharmony_ci    */
380bf215546Sopenharmony_ci   const uint32_t halign = 4;
381bf215546Sopenharmony_ci
382bf215546Sopenharmony_ci   bool require_valign4 = false;
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ci   /* From the Ivybridge PRM, Volume 4, Part 1, Section 2.12.1:
385bf215546Sopenharmony_ci    * RENDER_SURFACE_STATE Surface Vertical Alignment:
386bf215546Sopenharmony_ci    *
387bf215546Sopenharmony_ci    *    * This field is intended to be set to VALIGN_4 if the surface was
388bf215546Sopenharmony_ci    *      rendered as a depth buffer,
389bf215546Sopenharmony_ci    *
390bf215546Sopenharmony_ci    *    * for a multisampled (4x) render target, or for a multisampled (8x)
391bf215546Sopenharmony_ci    *      render target, since these surfaces support only alignment of 4.
392bf215546Sopenharmony_ci    *
393bf215546Sopenharmony_ci    *    * This field must be set to VALIGN_4 for all tiled Y Render Target
394bf215546Sopenharmony_ci    *      surfaces
395bf215546Sopenharmony_ci    *
396bf215546Sopenharmony_ci    *    * Value of 1 is not supported for format YCRCB_NORMAL (0x182),
397bf215546Sopenharmony_ci    *      YCRCB_SWAPUVY (0x183), YCRCB_SWAPUV (0x18f), YCRCB_SWAPY (0x190)
398bf215546Sopenharmony_ci    *
399bf215546Sopenharmony_ci    *    * If Number of Multisamples is not MULTISAMPLECOUNT_1, this field
400bf215546Sopenharmony_ci    *      must be set to VALIGN_4."
401bf215546Sopenharmony_ci    *
402bf215546Sopenharmony_ci    * The first restriction is already handled by the table above and the
403bf215546Sopenharmony_ci    * second restriction is redundant with the fifth.
404bf215546Sopenharmony_ci    */
405bf215546Sopenharmony_ci   if (info->samples > 1)
406bf215546Sopenharmony_ci      require_valign4 = true;
407bf215546Sopenharmony_ci
408bf215546Sopenharmony_ci   if (tiling == ISL_TILING_Y0 &&
409bf215546Sopenharmony_ci       (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT))
410bf215546Sopenharmony_ci      require_valign4 = true;
411bf215546Sopenharmony_ci
412bf215546Sopenharmony_ci   assert(!(require_valign4 && gfx7_format_needs_valign2(dev, info->format)));
413bf215546Sopenharmony_ci
414bf215546Sopenharmony_ci   /* We default to VALIGN_2 because it uses the least memory. */
415bf215546Sopenharmony_ci   const uint32_t valign = require_valign4 ? 4 : 2;
416bf215546Sopenharmony_ci
417bf215546Sopenharmony_ci   *image_align_el = isl_extent3d(halign, valign, 1);
418bf215546Sopenharmony_ci}
419