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