xref: /aosp_15_r20/external/mesa3d/src/intel/isl/isl_genX_helpers.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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