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