1 /*
2 * Copyright 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #ifndef ISL_SURFACE_STATE_H
25 #define ISL_SURFACE_STATE_H
26
27 #include <stdint.h>
28
29 /**
30 * @file isl_surface_state.h
31 *
32 * ============================= GENXML CODE =============================
33 * [This file is compiled once per generation.]
34 * =======================================================================
35 *
36 * Helpers for encoding SURFACE_STATE and XY_BLOCK_COPY_BLT commands.
37 */
38
39 UNUSED static const uint8_t
isl_encode_halign(uint8_t halign)40 isl_encode_halign(uint8_t halign)
41 {
42 switch (halign) {
43 #if GFX_VERx10 >= 125
44 case 16: return HALIGN_16;
45 case 32: return HALIGN_32;
46 case 64: return HALIGN_64;
47 case 128: return HALIGN_128;
48 #elif GFX_VER >= 8
49 case 4: return HALIGN_4;
50 case 8: return HALIGN_8;
51 case 16: return HALIGN_16;
52 #elif GFX_VER >= 7
53 case 4: return HALIGN_4;
54 case 8: return HALIGN_8;
55 #endif
56 default: unreachable("Invalid halign");
57 }
58 }
59
60 UNUSED static const uint8_t
isl_encode_valign(uint8_t valign)61 isl_encode_valign(uint8_t valign)
62 {
63 switch (valign) {
64 #if GFX_VER >= 8
65 case 4: return VALIGN_4;
66 case 8: return VALIGN_8;
67 case 16: return VALIGN_16;
68 #elif GFX_VER >= 6
69 case 2: return VALIGN_2;
70 case 4: return VALIGN_4;
71 #endif
72 default: unreachable("Invalid valign");
73 }
74 }
75
76 /**
77 * Get the horizontal and vertical alignment in the units expected by the
78 * hardware. Note that this does NOT give you the actual hardware enum values
79 * but an index into the isl_encode_[hv]align arrays above.
80 */
81 UNUSED static struct isl_extent3d
isl_get_image_alignment(const struct isl_surf * surf)82 isl_get_image_alignment(const struct isl_surf *surf)
83 {
84 if (GFX_VERx10 >= 125) {
85 if (isl_tiling_is_64(surf->tiling)) {
86 /* The hardware ignores the alignment values. Anyway, the surface's
87 * true alignment is likely outside the enum range of HALIGN* and
88 * VALIGN*.
89 */
90 return isl_extent3d(128, 4, 1);
91 } else if (isl_format_get_layout(surf->format)->bpb % 3 == 0) {
92 /* On XeHP, RENDER_SURFACE_STATE.SurfaceHorizontalAlignment is in
93 * units of elements for 24, 48, and 96 bpb formats.
94 */
95 return isl_surf_get_image_alignment_el(surf);
96 } else {
97 /* On XeHP, RENDER_SURFACE_STATE.SurfaceHorizontalAlignment is in
98 * units of bytes for formats that are powers of two.
99 */
100 const uint32_t bs = isl_format_get_layout(surf->format)->bpb / 8;
101 return isl_extent3d(surf->image_alignment_el.w * bs,
102 surf->image_alignment_el.h,
103 surf->image_alignment_el.d);
104 }
105 } else if (GFX_VER >= 9) {
106 if (isl_tiling_is_std_y(surf->tiling) ||
107 surf->dim_layout == ISL_DIM_LAYOUT_GFX9_1D) {
108 /* The hardware ignores the alignment values. Anyway, the surface's
109 * true alignment is likely outside the enum range of HALIGN* and
110 * VALIGN*.
111 */
112 return isl_extent3d(4, 4, 1);
113 } else {
114 /* In Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in units
115 * of surface elements (not pixels nor samples). For compressed formats,
116 * a "surface element" is defined as a compression block. For example,
117 * if SurfaceVerticalAlignment is VALIGN_4 and SurfaceFormat is an ETC2
118 * format (ETC2 has a block height of 4), then the vertical alignment is
119 * 4 compression blocks or, equivalently, 16 pixels.
120 */
121 return isl_surf_get_image_alignment_el(surf);
122 }
123 } else {
124 /* Pre-Skylake, RENDER_SUFFACE_STATE.SurfaceVerticalAlignment is in
125 * units of surface samples. For example, if SurfaceVerticalAlignment
126 * is VALIGN_4 and the surface is singlesampled, then for any surface
127 * format (compressed or not) the vertical alignment is
128 * 4 pixels.
129 */
130 return isl_surf_get_image_alignment_sa(surf);
131 }
132 }
133
134 UNUSED static uint32_t
isl_get_qpitch(const struct isl_surf * surf)135 isl_get_qpitch(const struct isl_surf *surf)
136 {
137 switch (surf->dim_layout) {
138 default:
139 unreachable("Bad isl_surf_dim");
140 case ISL_DIM_LAYOUT_GFX4_2D:
141 if (GFX_VER >= 9) {
142 if (surf->dim == ISL_SURF_DIM_3D && surf->tiling == ISL_TILING_W) {
143 /* This is rather annoying and completely undocumented. It
144 * appears that the hardware has a bug (or undocumented feature)
145 * regarding stencil buffers most likely related to the way
146 * W-tiling is handled as modified Y-tiling. If you bind a 3-D
147 * stencil buffer normally, and use texelFetch on it, the z or
148 * array index will get implicitly multiplied by 2 for no obvious
149 * reason. The fix appears to be to divide qpitch by 2 for
150 * W-tiled surfaces.
151 */
152 return isl_surf_get_array_pitch_el_rows(surf) / 2;
153 } else {
154 return isl_surf_get_array_pitch_el_rows(surf);
155 }
156 } else {
157 /* From the Broadwell PRM for RENDER_SURFACE_STATE.QPitch
158 *
159 * "This field must be set to an integer multiple of the Surface
160 * Vertical Alignment. For compressed textures (BC*, FXT1,
161 * ETC*, and EAC* Surface Formats), this field is in units of
162 * rows in the uncompressed surface, and must be set to an
163 * integer multiple of the vertical alignment parameter "j"
164 * defined in the Common Surface Formats section."
165 */
166 return isl_surf_get_array_pitch_sa_rows(surf);
167 }
168 case ISL_DIM_LAYOUT_GFX9_1D:
169 /* QPitch is usually expressed as rows of surface elements (where
170 * a surface element is an compression block or a single surface
171 * sample). Skylake 1D is an outlier.
172 *
173 * From the Skylake BSpec >> Memory Views >> Common Surface
174 * Formats >> Surface Layout and Tiling >> 1D Surfaces:
175 *
176 * Surface QPitch specifies the distance in pixels between array
177 * slices.
178 */
179 return isl_surf_get_array_pitch_el(surf);
180 case ISL_DIM_LAYOUT_GFX4_3D:
181 /* QPitch doesn't make sense for ISL_DIM_LAYOUT_GFX4_3D since it uses a
182 * different pitch at each LOD. Also, the QPitch field is ignored for
183 * these surfaces. From the Broadwell PRM documentation for QPitch:
184 *
185 * This field specifies the distance in rows between array slices. It
186 * is used only in the following cases:
187 * - Surface Array is enabled OR
188 * - Number of Mulitsamples is not NUMSAMPLES_1 and Multisampled
189 * Surface Storage Format set to MSFMT_MSS OR
190 * - Surface Type is SURFTYPE_CUBE
191 *
192 * None of the three conditions above can possibly apply to a 3D surface
193 * so it is safe to just set QPitch to 0.
194 */
195 return 0;
196 }
197 }
198
199 #if GFX_VER >= 20
200
201 /*
202 * Returns compression format encoding for Unified Lossless Compression
203 */
204 UNUSED static uint8_t
isl_get_render_compression_format(enum isl_format format)205 isl_get_render_compression_format(enum isl_format format)
206 {
207 /* Bspec 63919 (r60413):
208 *
209 * Table "[Enumeration] UNIFIED_COMPRESSION_FORMAT"
210 *
211 * These ISL formats have explicitly defined CMF values in the spec.
212 */
213 switch(format) {
214 case ISL_FORMAT_R8_UNORM:
215 case ISL_FORMAT_R8_UINT:
216 case ISL_FORMAT_R8_SNORM:
217 case ISL_FORMAT_R8_SINT:
218 case ISL_FORMAT_A8_UNORM:
219 case ISL_FORMAT_R24_UNORM_X8_TYPELESS:
220 return CMF_R8;
221 case ISL_FORMAT_R8G8_UNORM:
222 case ISL_FORMAT_R8G8_UINT:
223 case ISL_FORMAT_R8G8_SNORM:
224 case ISL_FORMAT_R8G8_SINT:
225 case ISL_FORMAT_B5G6R5_UNORM:
226 case ISL_FORMAT_B5G6R5_UNORM_SRGB:
227 case ISL_FORMAT_B5G5R5A1_UNORM:
228 case ISL_FORMAT_B5G5R5A1_UNORM_SRGB:
229 case ISL_FORMAT_B4G4R4A4_UNORM:
230 case ISL_FORMAT_B4G4R4A4_UNORM_SRGB:
231 case ISL_FORMAT_B5G5R5X1_UNORM:
232 case ISL_FORMAT_B5G5R5X1_UNORM_SRGB:
233 case ISL_FORMAT_A1B5G5R5_UNORM:
234 case ISL_FORMAT_A4B4G4R4_UNORM:
235 return CMF_R8_G8;
236 case ISL_FORMAT_R8G8B8A8_UNORM:
237 case ISL_FORMAT_R8G8B8A8_UINT:
238 case ISL_FORMAT_R8G8B8A8_SNORM:
239 case ISL_FORMAT_R8G8B8A8_SINT:
240 case ISL_FORMAT_R8G8B8A8_UNORM_SRGB:
241 case ISL_FORMAT_B8G8R8A8_UNORM_SRGB:
242 case ISL_FORMAT_B8G8R8A8_UNORM:
243 case ISL_FORMAT_B8G8R8X8_UNORM:
244 return CMF_R8_G8_B8_A8;
245 case ISL_FORMAT_R10G10B10A2_UNORM:
246 case ISL_FORMAT_R10G10B10A2_UNORM_SRGB:
247 case ISL_FORMAT_R10G10B10_FLOAT_A2_UNORM:
248 case ISL_FORMAT_R10G10B10A2_UINT:
249 case ISL_FORMAT_B10G10R10A2_UNORM:
250 case ISL_FORMAT_B10G10R10X2_UNORM:
251 case ISL_FORMAT_B10G10R10A2_UNORM_SRGB:
252 return CMF_R10_G10_B10_A2;
253 case ISL_FORMAT_R11G11B10_FLOAT:
254 return CMF_R11_G11_B10;
255 case ISL_FORMAT_R16_UNORM:
256 case ISL_FORMAT_R16_UINT:
257 case ISL_FORMAT_R16_SNORM:
258 case ISL_FORMAT_R16_SINT:
259 case ISL_FORMAT_R16_FLOAT:
260 return CMF_R16;
261 case ISL_FORMAT_R16G16_UNORM:
262 case ISL_FORMAT_R16G16_UINT:
263 case ISL_FORMAT_R16G16_SNORM:
264 case ISL_FORMAT_R16G16_SINT:
265 case ISL_FORMAT_R16G16_FLOAT:
266 return CMF_R16_G16;
267 case ISL_FORMAT_R16G16B16A16_UNORM:
268 case ISL_FORMAT_R16G16B16A16_UINT:
269 case ISL_FORMAT_R16G16B16A16_SNORM:
270 case ISL_FORMAT_R16G16B16A16_SINT:
271 case ISL_FORMAT_R16G16B16A16_FLOAT:
272 case ISL_FORMAT_R16G16B16X16_FLOAT:
273 return CMF_R16_G16_B16_A16;
274 case ISL_FORMAT_R32_UNORM:
275 case ISL_FORMAT_R32_UINT:
276 case ISL_FORMAT_R32_SNORM:
277 case ISL_FORMAT_R32_SINT:
278 case ISL_FORMAT_R32_FLOAT:
279 return CMF_R32;
280 case ISL_FORMAT_R32G32_UNORM:
281 case ISL_FORMAT_R32G32_UINT:
282 case ISL_FORMAT_R32G32_SNORM:
283 case ISL_FORMAT_R32G32_SINT:
284 case ISL_FORMAT_R32G32_FLOAT:
285 return CMF_R32_G32;
286 case ISL_FORMAT_R32G32B32A32_UNORM:
287 case ISL_FORMAT_R32G32B32A32_UINT:
288 case ISL_FORMAT_R32G32B32A32_SNORM:
289 case ISL_FORMAT_R32G32B32A32_SINT:
290 case ISL_FORMAT_R32G32B32A32_FLOAT:
291 case ISL_FORMAT_R32G32B32X32_FLOAT:
292 return CMF_R32_G32_B32_A32;
293 case ISL_FORMAT_EAC_R11:
294 case ISL_FORMAT_EAC_RG11:
295 case ISL_FORMAT_EAC_SIGNED_R11:
296 case ISL_FORMAT_EAC_SIGNED_RG11:
297 case ISL_FORMAT_ETC1_RGB8:
298 case ISL_FORMAT_ETC2_RGB8:
299 case ISL_FORMAT_ETC2_SRGB8:
300 case ISL_FORMAT_ETC2_RGB8_PTA:
301 case ISL_FORMAT_ETC2_SRGB8_PTA:
302 case ISL_FORMAT_ETC2_EAC_RGBA8:
303 case ISL_FORMAT_ETC2_EAC_SRGB8_A8:
304 case ISL_FORMAT_BC1_UNORM:
305 case ISL_FORMAT_BC2_UNORM:
306 case ISL_FORMAT_BC3_UNORM:
307 case ISL_FORMAT_BC4_UNORM:
308 case ISL_FORMAT_BC5_UNORM:
309 case ISL_FORMAT_BC1_UNORM_SRGB:
310 case ISL_FORMAT_BC2_UNORM_SRGB:
311 case ISL_FORMAT_BC3_UNORM_SRGB:
312 case ISL_FORMAT_BC4_SNORM:
313 case ISL_FORMAT_BC5_SNORM:
314 case ISL_FORMAT_BC6H_SF16:
315 case ISL_FORMAT_BC7_UNORM:
316 case ISL_FORMAT_BC7_UNORM_SRGB:
317 case ISL_FORMAT_BC6H_UF16:
318 return CMF_ML8;
319 /* These formats are not in the CMF table in the Bspec 63919 (r60413).
320 * We choose CMF values for them by their number of channels x channel bit
321 * size.
322 */
323 case ISL_FORMAT_L8A8_UNORM_SRGB:
324 return CMF_R8_G8;
325 case ISL_FORMAT_L8_UNORM_SRGB:
326 return CMF_R8;
327 case ISL_FORMAT_R9G9B9E5_SHAREDEXP:
328 return CMF_R11_G11_B10;
329 default:
330 unreachable("Unsupported render compression format!");
331 return 0;
332 }
333 }
334
335 #elif GFX_VERx10 >= 125
336
337 /*
338 * Returns compression format encoding for Unified Lossless Compression
339 */
340 UNUSED static uint8_t
isl_get_render_compression_format(enum isl_format format)341 isl_get_render_compression_format(enum isl_format format)
342 {
343 /* From the Bspec, Enumeration_RenderCompressionFormat section (53726): */
344 switch(format) {
345 case ISL_FORMAT_R32G32B32A32_FLOAT:
346 case ISL_FORMAT_R32G32B32X32_FLOAT:
347 case ISL_FORMAT_R32G32B32A32_SINT:
348 return 0x0;
349 case ISL_FORMAT_R32G32B32A32_UINT:
350 return 0x1;
351 case ISL_FORMAT_R32G32_FLOAT:
352 case ISL_FORMAT_R32G32_SINT:
353 return 0x2;
354 case ISL_FORMAT_R32G32_UINT:
355 return 0x3;
356 case ISL_FORMAT_R16G16B16A16_UNORM:
357 case ISL_FORMAT_R16G16B16X16_UNORM:
358 case ISL_FORMAT_R16G16B16A16_UINT:
359 return 0x4;
360 case ISL_FORMAT_R16G16B16A16_SNORM:
361 case ISL_FORMAT_R16G16B16A16_SINT:
362 case ISL_FORMAT_R16G16B16A16_FLOAT:
363 case ISL_FORMAT_R16G16B16X16_FLOAT:
364 return 0x5;
365 case ISL_FORMAT_R16G16_UNORM:
366 case ISL_FORMAT_R16G16_UINT:
367 return 0x6;
368 case ISL_FORMAT_R16G16_SNORM:
369 case ISL_FORMAT_R16G16_SINT:
370 case ISL_FORMAT_R16G16_FLOAT:
371 return 0x7;
372 case ISL_FORMAT_B8G8R8A8_UNORM:
373 case ISL_FORMAT_B8G8R8X8_UNORM:
374 case ISL_FORMAT_B8G8R8A8_UNORM_SRGB:
375 case ISL_FORMAT_B8G8R8X8_UNORM_SRGB:
376 case ISL_FORMAT_R8G8B8A8_UNORM:
377 case ISL_FORMAT_R8G8B8X8_UNORM:
378 case ISL_FORMAT_R8G8B8A8_UNORM_SRGB:
379 case ISL_FORMAT_R8G8B8X8_UNORM_SRGB:
380 case ISL_FORMAT_R8G8B8A8_UINT:
381 return 0x8;
382 case ISL_FORMAT_R8G8B8A8_SNORM:
383 case ISL_FORMAT_R8G8B8A8_SINT:
384 return 0x9;
385 case ISL_FORMAT_B5G6R5_UNORM:
386 case ISL_FORMAT_B5G6R5_UNORM_SRGB:
387 case ISL_FORMAT_B5G5R5A1_UNORM:
388 case ISL_FORMAT_B5G5R5A1_UNORM_SRGB:
389 case ISL_FORMAT_B4G4R4A4_UNORM:
390 case ISL_FORMAT_B4G4R4A4_UNORM_SRGB:
391 case ISL_FORMAT_B5G5R5X1_UNORM:
392 case ISL_FORMAT_B5G5R5X1_UNORM_SRGB:
393 case ISL_FORMAT_A1B5G5R5_UNORM:
394 case ISL_FORMAT_A4B4G4R4_UNORM:
395 case ISL_FORMAT_R8G8_UNORM:
396 case ISL_FORMAT_R8G8_UINT:
397 return 0xA;
398 case ISL_FORMAT_R8G8_SNORM:
399 case ISL_FORMAT_R8G8_SINT:
400 return 0xB;
401 case ISL_FORMAT_R10G10B10A2_UNORM:
402 case ISL_FORMAT_R10G10B10A2_UNORM_SRGB:
403 case ISL_FORMAT_R10G10B10_FLOAT_A2_UNORM:
404 case ISL_FORMAT_R10G10B10A2_UINT:
405 case ISL_FORMAT_B10G10R10A2_UNORM:
406 case ISL_FORMAT_B10G10R10X2_UNORM:
407 case ISL_FORMAT_B10G10R10A2_UNORM_SRGB:
408 return 0xC;
409 case ISL_FORMAT_R11G11B10_FLOAT:
410 return 0xD;
411 case ISL_FORMAT_R32_SINT:
412 case ISL_FORMAT_R32_FLOAT:
413 return 0x10;
414 case ISL_FORMAT_R32_UINT:
415 case ISL_FORMAT_R24_UNORM_X8_TYPELESS:
416 return 0x11;
417 case ISL_FORMAT_R16_UNORM:
418 case ISL_FORMAT_R16_UINT:
419 return 0x14;
420 case ISL_FORMAT_R16_SNORM:
421 case ISL_FORMAT_R16_SINT:
422 case ISL_FORMAT_R16_FLOAT:
423 return 0x15;
424 case ISL_FORMAT_R8_UNORM:
425 case ISL_FORMAT_R8_UINT:
426 case ISL_FORMAT_A8_UNORM:
427 return 0x18;
428 case ISL_FORMAT_R8_SNORM:
429 case ISL_FORMAT_R8_SINT:
430 return 0x19;
431 default:
432 unreachable("Unsupported render compression format!");
433 return 0;
434 }
435 }
436
437 #endif /* #if GFX_VERx10 >= 125 */
438
439 #endif
440