xref: /aosp_15_r20/external/mesa3d/src/amd/common/ac_formats.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  * Copyright 2024 Valve Corporation
4  *
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include "ac_gpu_info.h"
9 #include "ac_formats.h"
10 #include "ac_gpu_info.h"
11 
12 #include "sid.h"
13 
14 uint32_t
ac_translate_buffer_numformat(const struct util_format_description * desc,int first_non_void)15 ac_translate_buffer_numformat(const struct util_format_description *desc,
16                               int first_non_void)
17 {
18    if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
19       return V_008F0C_BUF_NUM_FORMAT_FLOAT;
20 
21    assert(first_non_void >= 0);
22 
23    switch (desc->channel[first_non_void].type) {
24    case UTIL_FORMAT_TYPE_SIGNED:
25    case UTIL_FORMAT_TYPE_FIXED:
26       if (desc->channel[first_non_void].size >= 32 || desc->channel[first_non_void].pure_integer)
27          return V_008F0C_BUF_NUM_FORMAT_SINT;
28       else if (desc->channel[first_non_void].normalized)
29          return V_008F0C_BUF_NUM_FORMAT_SNORM;
30       else
31          return V_008F0C_BUF_NUM_FORMAT_SSCALED;
32       break;
33    case UTIL_FORMAT_TYPE_UNSIGNED:
34       if (desc->channel[first_non_void].size >= 32 || desc->channel[first_non_void].pure_integer)
35          return V_008F0C_BUF_NUM_FORMAT_UINT;
36       else if (desc->channel[first_non_void].normalized)
37          return V_008F0C_BUF_NUM_FORMAT_UNORM;
38       else
39          return V_008F0C_BUF_NUM_FORMAT_USCALED;
40       break;
41    case UTIL_FORMAT_TYPE_FLOAT:
42    default:
43       return V_008F0C_BUF_NUM_FORMAT_FLOAT;
44    }
45 }
46 
47 uint32_t
ac_translate_buffer_dataformat(const struct util_format_description * desc,int first_non_void)48 ac_translate_buffer_dataformat(const struct util_format_description *desc,
49                                int first_non_void)
50 {
51    int i;
52 
53    if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
54       return V_008F0C_BUF_DATA_FORMAT_10_11_11;
55 
56    assert(first_non_void >= 0);
57 
58    if (desc->nr_channels == 4 && desc->channel[0].size == 10 && desc->channel[1].size == 10 &&
59        desc->channel[2].size == 10 && desc->channel[3].size == 2)
60       return V_008F0C_BUF_DATA_FORMAT_2_10_10_10;
61 
62    /* See whether the components are of the same size. */
63    for (i = 0; i < desc->nr_channels; i++) {
64       if (desc->channel[first_non_void].size != desc->channel[i].size)
65          return V_008F0C_BUF_DATA_FORMAT_INVALID;
66    }
67 
68    switch (desc->channel[first_non_void].size) {
69    case 8:
70       switch (desc->nr_channels) {
71       case 1:
72       case 3: /* 3 loads */
73          return V_008F0C_BUF_DATA_FORMAT_8;
74       case 2:
75          return V_008F0C_BUF_DATA_FORMAT_8_8;
76       case 4:
77          return V_008F0C_BUF_DATA_FORMAT_8_8_8_8;
78       }
79       break;
80    case 16:
81       switch (desc->nr_channels) {
82       case 1:
83       case 3: /* 3 loads */
84          return V_008F0C_BUF_DATA_FORMAT_16;
85       case 2:
86          return V_008F0C_BUF_DATA_FORMAT_16_16;
87       case 4:
88          return V_008F0C_BUF_DATA_FORMAT_16_16_16_16;
89       }
90       break;
91    case 32:
92       switch (desc->nr_channels) {
93       case 1:
94          return V_008F0C_BUF_DATA_FORMAT_32;
95       case 2:
96          return V_008F0C_BUF_DATA_FORMAT_32_32;
97       case 3:
98          return V_008F0C_BUF_DATA_FORMAT_32_32_32;
99       case 4:
100          return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
101       }
102       break;
103    case 64:
104       /* Legacy double formats. */
105       switch (desc->nr_channels) {
106       case 1: /* 1 load */
107          return V_008F0C_BUF_DATA_FORMAT_32_32;
108       case 2: /* 1 load */
109          return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
110       case 3: /* 3 loads */
111          return V_008F0C_BUF_DATA_FORMAT_32_32;
112       case 4: /* 2 loads */
113          return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
114       }
115       break;
116    }
117 
118    return V_008F0C_BUF_DATA_FORMAT_INVALID;
119 }
120 
121 uint32_t
ac_translate_tex_numformat(const struct util_format_description * desc,int first_non_void)122 ac_translate_tex_numformat(const struct util_format_description *desc,
123                            int first_non_void)
124 {
125    uint32_t num_format;
126 
127    switch (desc->format) {
128    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
129       num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
130       break;
131    default:
132       if (first_non_void < 0) {
133          if (util_format_is_compressed(desc->format)) {
134             switch (desc->format) {
135             case PIPE_FORMAT_DXT1_SRGB:
136             case PIPE_FORMAT_DXT1_SRGBA:
137             case PIPE_FORMAT_DXT3_SRGBA:
138             case PIPE_FORMAT_DXT5_SRGBA:
139             case PIPE_FORMAT_BPTC_SRGBA:
140             case PIPE_FORMAT_ETC2_SRGB8:
141             case PIPE_FORMAT_ETC2_SRGB8A1:
142             case PIPE_FORMAT_ETC2_SRGBA8:
143                num_format = V_008F14_IMG_NUM_FORMAT_SRGB;
144                break;
145             case PIPE_FORMAT_RGTC1_SNORM:
146             case PIPE_FORMAT_LATC1_SNORM:
147             case PIPE_FORMAT_RGTC2_SNORM:
148             case PIPE_FORMAT_LATC2_SNORM:
149             case PIPE_FORMAT_ETC2_R11_SNORM:
150             case PIPE_FORMAT_ETC2_RG11_SNORM:
151             /* implies float, so use SNORM/UNORM to determine
152                whether data is signed or not */
153             case PIPE_FORMAT_BPTC_RGB_FLOAT:
154                num_format = V_008F14_IMG_NUM_FORMAT_SNORM;
155                break;
156             default:
157                num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
158                break;
159             }
160          } else if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
161             num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
162          } else {
163             num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
164          }
165       } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
166          num_format = V_008F14_IMG_NUM_FORMAT_SRGB;
167       } else {
168          switch (desc->channel[first_non_void].type) {
169          case UTIL_FORMAT_TYPE_FLOAT:
170             num_format = V_008F14_IMG_NUM_FORMAT_FLOAT;
171             break;
172          case UTIL_FORMAT_TYPE_SIGNED:
173             if (desc->channel[first_non_void].normalized)
174                num_format = V_008F14_IMG_NUM_FORMAT_SNORM;
175             else if (desc->channel[first_non_void].pure_integer)
176                num_format = V_008F14_IMG_NUM_FORMAT_SINT;
177             else
178                num_format = V_008F14_IMG_NUM_FORMAT_SSCALED;
179             break;
180          case UTIL_FORMAT_TYPE_UNSIGNED:
181             if (desc->channel[first_non_void].normalized)
182                num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
183             else if (desc->channel[first_non_void].pure_integer)
184                num_format = V_008F14_IMG_NUM_FORMAT_UINT;
185             else
186                num_format = V_008F14_IMG_NUM_FORMAT_USCALED;
187             break;
188          default:
189             num_format = V_008F14_IMG_NUM_FORMAT_UNORM;
190             break;
191          }
192       }
193    }
194 
195    return num_format;
196 }
197 
198 uint32_t
ac_translate_tex_dataformat(const struct radeon_info * info,const struct util_format_description * desc,int first_non_void)199 ac_translate_tex_dataformat(const struct radeon_info *info,
200                             const struct util_format_description *desc,
201                             int first_non_void)
202 {
203    bool uniform = true;
204    int i;
205 
206    /* Colorspace (return non-RGB formats directly). */
207    switch (desc->colorspace) {
208    /* Depth stencil formats */
209    case UTIL_FORMAT_COLORSPACE_ZS:
210       switch (desc->format) {
211       case PIPE_FORMAT_Z16_UNORM:
212          return V_008F14_IMG_DATA_FORMAT_16;
213       case PIPE_FORMAT_X24S8_UINT:
214       case PIPE_FORMAT_S8X24_UINT:
215          /*
216           * Implemented as an 8_8_8_8 data format to fix texture
217           * gathers in stencil sampling. This affects at least
218           * GL45-CTS.texture_cube_map_array.sampling on GFX8.
219           */
220          if (info->gfx_level <= GFX8)
221             return V_008F14_IMG_DATA_FORMAT_8_8_8_8;
222 
223          if (desc->format == PIPE_FORMAT_X24S8_UINT)
224             return V_008F14_IMG_DATA_FORMAT_8_24;
225          else
226             return V_008F14_IMG_DATA_FORMAT_24_8;
227       case PIPE_FORMAT_Z24X8_UNORM:
228       case PIPE_FORMAT_Z24_UNORM_S8_UINT:
229          return V_008F14_IMG_DATA_FORMAT_8_24;
230       case PIPE_FORMAT_X8Z24_UNORM:
231       case PIPE_FORMAT_S8_UINT_Z24_UNORM:
232          return V_008F14_IMG_DATA_FORMAT_24_8;
233       case PIPE_FORMAT_S8_UINT:
234          return V_008F14_IMG_DATA_FORMAT_8;
235       case PIPE_FORMAT_Z32_FLOAT:
236          return V_008F14_IMG_DATA_FORMAT_32;
237       case PIPE_FORMAT_X32_S8X24_UINT:
238       case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
239          return V_008F14_IMG_DATA_FORMAT_X24_8_32;
240       default:
241          return ~0;
242       }
243 
244    case UTIL_FORMAT_COLORSPACE_YUV:
245       return ~0; /* TODO */
246 
247    default:
248       break;
249    }
250 
251    if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
252       switch (desc->format) {
253       case PIPE_FORMAT_RGTC1_SNORM:
254       case PIPE_FORMAT_LATC1_SNORM:
255       case PIPE_FORMAT_RGTC1_UNORM:
256       case PIPE_FORMAT_LATC1_UNORM:
257          return V_008F14_IMG_DATA_FORMAT_BC4;
258       case PIPE_FORMAT_RGTC2_SNORM:
259       case PIPE_FORMAT_LATC2_SNORM:
260       case PIPE_FORMAT_RGTC2_UNORM:
261       case PIPE_FORMAT_LATC2_UNORM:
262          return V_008F14_IMG_DATA_FORMAT_BC5;
263       default:
264          return ~0;
265       }
266    }
267 
268    if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
269       switch (desc->format) {
270       case PIPE_FORMAT_ETC1_RGB8:
271       case PIPE_FORMAT_ETC2_RGB8:
272       case PIPE_FORMAT_ETC2_SRGB8:
273          return V_008F14_IMG_DATA_FORMAT_ETC2_RGB;
274       case PIPE_FORMAT_ETC2_RGB8A1:
275       case PIPE_FORMAT_ETC2_SRGB8A1:
276          return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA1;
277       case PIPE_FORMAT_ETC2_RGBA8:
278       case PIPE_FORMAT_ETC2_SRGBA8:
279          return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA;
280       case PIPE_FORMAT_ETC2_R11_UNORM:
281       case PIPE_FORMAT_ETC2_R11_SNORM:
282          return V_008F14_IMG_DATA_FORMAT_ETC2_R;
283       case PIPE_FORMAT_ETC2_RG11_UNORM:
284       case PIPE_FORMAT_ETC2_RG11_SNORM:
285          return V_008F14_IMG_DATA_FORMAT_ETC2_RG;
286       default:
287          break;
288       }
289    }
290 
291    if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
292       switch (desc->format) {
293       case PIPE_FORMAT_BPTC_RGBA_UNORM:
294       case PIPE_FORMAT_BPTC_SRGBA:
295          return V_008F14_IMG_DATA_FORMAT_BC7;
296       case PIPE_FORMAT_BPTC_RGB_FLOAT:
297       case PIPE_FORMAT_BPTC_RGB_UFLOAT:
298          return V_008F14_IMG_DATA_FORMAT_BC6;
299       default:
300          return ~0;
301       }
302    }
303 
304    if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
305       switch (desc->format) {
306       case PIPE_FORMAT_R8G8_B8G8_UNORM:
307       case PIPE_FORMAT_G8R8_B8R8_UNORM:
308       case PIPE_FORMAT_B8G8_R8G8_UNORM:
309          return V_008F14_IMG_DATA_FORMAT_GB_GR;
310       case PIPE_FORMAT_G8R8_G8B8_UNORM:
311       case PIPE_FORMAT_R8G8_R8B8_UNORM:
312       case PIPE_FORMAT_G8B8_G8R8_UNORM:
313          return V_008F14_IMG_DATA_FORMAT_BG_RG;
314       default:
315          return ~0;
316       }
317    }
318 
319    if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
320       switch (desc->format) {
321       case PIPE_FORMAT_DXT1_RGB:
322       case PIPE_FORMAT_DXT1_RGBA:
323       case PIPE_FORMAT_DXT1_SRGB:
324       case PIPE_FORMAT_DXT1_SRGBA:
325          return V_008F14_IMG_DATA_FORMAT_BC1;
326       case PIPE_FORMAT_DXT3_RGBA:
327       case PIPE_FORMAT_DXT3_SRGBA:
328          return V_008F14_IMG_DATA_FORMAT_BC2;
329       case PIPE_FORMAT_DXT5_RGBA:
330       case PIPE_FORMAT_DXT5_SRGBA:
331          return V_008F14_IMG_DATA_FORMAT_BC3;
332       default:
333          return ~0;
334       }
335    }
336 
337    if (desc->format == PIPE_FORMAT_R9G9B9E5_FLOAT) {
338       return V_008F14_IMG_DATA_FORMAT_5_9_9_9;
339    } else if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT) {
340       return V_008F14_IMG_DATA_FORMAT_10_11_11;
341    }
342 
343    /* hw cannot support mixed formats (except depth/stencil, since only
344     * depth is read).*/
345    if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
346       return ~0;
347 
348    if (first_non_void < 0 || first_non_void > 3)
349       return ~0;
350 
351    /* See whether the components are of the same size. */
352    for (i = 1; i < desc->nr_channels; i++) {
353       uniform = uniform && desc->channel[0].size == desc->channel[i].size;
354    }
355 
356    /* Non-uniform formats. */
357    if (!uniform) {
358       switch (desc->nr_channels) {
359       case 3:
360          if (desc->channel[0].size == 5 && desc->channel[1].size == 6 &&
361              desc->channel[2].size == 5) {
362             return V_008F14_IMG_DATA_FORMAT_5_6_5;
363          }
364          return ~0;
365       case 4:
366          /* 5551 and 1555 UINT formats fail on Gfx8/Carrizo´. */
367          if (info->family == CHIP_CARRIZO &&
368              desc->channel[1].size == 5 &&
369              desc->channel[2].size == 5 &&
370              desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED &&
371              desc->channel[first_non_void].pure_integer)
372             return ~0;
373 
374          if (desc->channel[0].size == 5 && desc->channel[1].size == 5 &&
375              desc->channel[2].size == 5 && desc->channel[3].size == 1) {
376             return V_008F14_IMG_DATA_FORMAT_1_5_5_5;
377          }
378          if (desc->channel[0].size == 1 && desc->channel[1].size == 5 &&
379              desc->channel[2].size == 5 && desc->channel[3].size == 5) {
380             return V_008F14_IMG_DATA_FORMAT_5_5_5_1;
381          }
382          if (desc->channel[0].size == 10 && desc->channel[1].size == 10 &&
383              desc->channel[2].size == 10 && desc->channel[3].size == 2) {
384             return V_008F14_IMG_DATA_FORMAT_2_10_10_10;
385          }
386          return ~0;
387       }
388       return ~0;
389    }
390 
391    /* uniform formats */
392    switch (desc->channel[first_non_void].size) {
393    case 4:
394       switch (desc->nr_channels) {
395       case 4:
396          /* 4444 UINT formats fail on Gfx8/Carrizo´. */
397          if (info->family == CHIP_CARRIZO &&
398              desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED &&
399              desc->channel[first_non_void].pure_integer)
400             return ~0;
401 
402          return V_008F14_IMG_DATA_FORMAT_4_4_4_4;
403       }
404       break;
405    case 8:
406       switch (desc->nr_channels) {
407       case 1:
408          return V_008F14_IMG_DATA_FORMAT_8;
409       case 2:
410          return V_008F14_IMG_DATA_FORMAT_8_8;
411       case 4:
412          return V_008F14_IMG_DATA_FORMAT_8_8_8_8;
413       }
414       break;
415    case 16:
416       switch (desc->nr_channels) {
417       case 1:
418          return V_008F14_IMG_DATA_FORMAT_16;
419       case 2:
420          return V_008F14_IMG_DATA_FORMAT_16_16;
421       case 4:
422          return V_008F14_IMG_DATA_FORMAT_16_16_16_16;
423       }
424       break;
425    case 32:
426       switch (desc->nr_channels) {
427       case 1:
428          return V_008F14_IMG_DATA_FORMAT_32;
429       case 2:
430          return V_008F14_IMG_DATA_FORMAT_32_32;
431       /* Not supported for render targets */
432       case 3:
433          return V_008F14_IMG_DATA_FORMAT_32_32_32;
434       case 4:
435          return V_008F14_IMG_DATA_FORMAT_32_32_32_32;
436       }
437       break;
438    case 64:
439       if (desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1)
440          return V_008F14_IMG_DATA_FORMAT_32_32;
441       break;
442    }
443 
444    return ~0;
445 }
446 
447 unsigned
ac_get_cb_format(enum amd_gfx_level gfx_level,enum pipe_format format)448 ac_get_cb_format(enum amd_gfx_level gfx_level, enum pipe_format format)
449 {
450    const struct util_format_description *desc = util_format_description(format);
451 
452 #define HAS_SIZE(x, y, z, w)                                                                       \
453    (desc->channel[0].size == (x) && desc->channel[1].size == (y) &&                                \
454     desc->channel[2].size == (z) && desc->channel[3].size == (w))
455 
456    if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
457       return V_028C70_COLOR_10_11_11;
458 
459    if (gfx_level >= GFX10_3 &&
460        format == PIPE_FORMAT_R9G9B9E5_FLOAT) /* isn't plain */
461       return V_028C70_COLOR_5_9_9_9;
462 
463    if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
464       return V_028C70_COLOR_INVALID;
465 
466    /* hw cannot support mixed formats (except depth/stencil, since
467     * stencil is not written to). */
468    if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
469       return V_028C70_COLOR_INVALID;
470 
471    int first_non_void = util_format_get_first_non_void_channel(format);
472 
473    /* Reject SCALED formats because we don't implement them for CB. */
474    if (first_non_void >= 0 && first_non_void <= 3 &&
475        (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED ||
476         desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) &&
477        !desc->channel[first_non_void].normalized &&
478        !desc->channel[first_non_void].pure_integer)
479       return V_028C70_COLOR_INVALID;
480 
481    switch (desc->nr_channels) {
482    case 1:
483       switch (desc->channel[0].size) {
484       case 8:
485          return V_028C70_COLOR_8;
486       case 16:
487          return V_028C70_COLOR_16;
488       case 32:
489          return V_028C70_COLOR_32;
490       case 64:
491          return V_028C70_COLOR_32_32;
492       }
493       break;
494    case 2:
495       if (desc->channel[0].size == desc->channel[1].size) {
496          switch (desc->channel[0].size) {
497          case 8:
498             return V_028C70_COLOR_8_8;
499          case 16:
500             return V_028C70_COLOR_16_16;
501          case 32:
502             return V_028C70_COLOR_32_32;
503          }
504       } else if (HAS_SIZE(8, 24, 0, 0)) {
505          return V_028C70_COLOR_24_8;
506       } else if (HAS_SIZE(24, 8, 0, 0)) {
507          return V_028C70_COLOR_8_24;
508       }
509       break;
510    case 3:
511       if (HAS_SIZE(5, 6, 5, 0)) {
512          return V_028C70_COLOR_5_6_5;
513       } else if (HAS_SIZE(32, 8, 24, 0)) {
514          return V_028C70_COLOR_X24_8_32_FLOAT;
515       }
516       break;
517    case 4:
518       if (desc->channel[0].size == desc->channel[1].size &&
519           desc->channel[0].size == desc->channel[2].size &&
520           desc->channel[0].size == desc->channel[3].size) {
521          switch (desc->channel[0].size) {
522          case 4:
523             return V_028C70_COLOR_4_4_4_4;
524          case 8:
525             return V_028C70_COLOR_8_8_8_8;
526          case 16:
527             return V_028C70_COLOR_16_16_16_16;
528          case 32:
529             return V_028C70_COLOR_32_32_32_32;
530          }
531       } else if (HAS_SIZE(5, 5, 5, 1)) {
532          return V_028C70_COLOR_1_5_5_5;
533       } else if (HAS_SIZE(1, 5, 5, 5)) {
534          return V_028C70_COLOR_5_5_5_1;
535       } else if (HAS_SIZE(10, 10, 10, 2)) {
536          return V_028C70_COLOR_2_10_10_10;
537       } else if (HAS_SIZE(2, 10, 10, 10)) {
538          return V_028C70_COLOR_10_10_10_2;
539       }
540       break;
541    }
542    return V_028C70_COLOR_INVALID;
543 }
544 
ac_get_cb_number_type(enum pipe_format format)545 unsigned ac_get_cb_number_type(enum pipe_format format)
546 {
547    const struct util_format_description *desc = util_format_description(format);
548    int chan = util_format_get_first_non_void_channel(format);
549 
550    if (chan == -1 || desc->channel[chan].type == UTIL_FORMAT_TYPE_FLOAT) {
551       return V_028C70_NUMBER_FLOAT;
552    } else {
553       if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
554          return V_028C70_NUMBER_SRGB;
555       } else if (desc->channel[chan].type == UTIL_FORMAT_TYPE_SIGNED) {
556          return desc->channel[chan].pure_integer ? V_028C70_NUMBER_SINT : V_028C70_NUMBER_SNORM;
557       } else if (desc->channel[chan].type == UTIL_FORMAT_TYPE_UNSIGNED) {
558          return desc->channel[chan].pure_integer ? V_028C70_NUMBER_UINT : V_028C70_NUMBER_UNORM;
559       } else {
560          return V_028C70_NUMBER_UNORM;
561       }
562    }
563 }
564 
565 unsigned
ac_translate_colorswap(enum amd_gfx_level gfx_level,enum pipe_format format,bool do_endian_swap)566 ac_translate_colorswap(enum amd_gfx_level gfx_level, enum pipe_format format, bool do_endian_swap)
567 {
568    const struct util_format_description *desc = util_format_description(format);
569 
570 #define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz)
571 
572    if (format == PIPE_FORMAT_R11G11B10_FLOAT) /* isn't plain */
573       return V_028C70_SWAP_STD;
574 
575    if (gfx_level >= GFX10_3 &&
576        format == PIPE_FORMAT_R9G9B9E5_FLOAT) /* isn't plain */
577       return V_028C70_SWAP_STD;
578 
579    if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
580       return ~0U;
581 
582    switch (desc->nr_channels) {
583    case 1:
584       if (HAS_SWIZZLE(0, X))
585          return V_028C70_SWAP_STD; /* X___ */
586       else if (HAS_SWIZZLE(3, X))
587          return V_028C70_SWAP_ALT_REV; /* ___X */
588       break;
589    case 2:
590       if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) ||
591           (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y)))
592          return V_028C70_SWAP_STD; /* XY__ */
593       else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) ||
594                (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) ||
595                (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X)))
596          /* YX__ */
597          return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
598       else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y))
599          return V_028C70_SWAP_ALT; /* X__Y */
600       else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X))
601          return V_028C70_SWAP_ALT_REV; /* Y__X */
602       break;
603    case 3:
604       if (HAS_SWIZZLE(0, X))
605          return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
606       else if (HAS_SWIZZLE(0, Z))
607          return V_028C70_SWAP_STD_REV; /* ZYX */
608       break;
609    case 4:
610       /* check the middle channels, the 1st and 4th channel can be NONE */
611       if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) {
612          return V_028C70_SWAP_STD; /* XYZW */
613       } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) {
614          return V_028C70_SWAP_STD_REV; /* WZYX */
615       } else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) {
616          return V_028C70_SWAP_ALT; /* ZYXW */
617       } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) {
618          /* YZWX */
619          if (desc->is_array)
620             return V_028C70_SWAP_ALT_REV;
621          else
622             return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
623       }
624       break;
625    }
626    return ~0U;
627 }
628 
629 bool
ac_is_colorbuffer_format_supported(enum amd_gfx_level gfx_level,enum pipe_format format)630 ac_is_colorbuffer_format_supported(enum amd_gfx_level gfx_level, enum pipe_format format)
631 {
632    return ac_get_cb_format(gfx_level, format) != V_028C70_COLOR_INVALID &&
633           ac_translate_colorswap(gfx_level, format, false) != ~0U;
634 }
635 
636 uint32_t
ac_colorformat_endian_swap(uint32_t colorformat)637 ac_colorformat_endian_swap(uint32_t colorformat)
638 {
639    if (UTIL_ARCH_BIG_ENDIAN) {
640       switch (colorformat) {
641       /* 8-bit buffers. */
642       case V_028C70_COLOR_8:
643          return V_028C70_ENDIAN_NONE;
644 
645       /* 16-bit buffers. */
646       case V_028C70_COLOR_5_6_5:
647       case V_028C70_COLOR_1_5_5_5:
648       case V_028C70_COLOR_4_4_4_4:
649       case V_028C70_COLOR_16:
650       case V_028C70_COLOR_8_8:
651          return V_028C70_ENDIAN_8IN16;
652 
653       /* 32-bit buffers. */
654       case V_028C70_COLOR_8_8_8_8:
655       case V_028C70_COLOR_2_10_10_10:
656       case V_028C70_COLOR_10_10_10_2:
657       case V_028C70_COLOR_8_24:
658       case V_028C70_COLOR_24_8:
659       case V_028C70_COLOR_16_16:
660          return V_028C70_ENDIAN_8IN32;
661 
662       /* 64-bit buffers. */
663       case V_028C70_COLOR_16_16_16_16:
664          return V_028C70_ENDIAN_8IN16;
665 
666       case V_028C70_COLOR_32_32:
667          return V_028C70_ENDIAN_8IN32;
668 
669       /* 128-bit buffers. */
670       case V_028C70_COLOR_32_32_32_32:
671          return V_028C70_ENDIAN_8IN32;
672       default:
673          return V_028C70_ENDIAN_NONE; /* Unsupported. */
674       }
675    } else {
676       return V_028C70_ENDIAN_NONE;
677    }
678 }
679 
680 uint32_t
ac_translate_dbformat(enum pipe_format format)681 ac_translate_dbformat(enum pipe_format format)
682 {
683    switch (format) {
684    case PIPE_FORMAT_Z16_UNORM:
685    case PIPE_FORMAT_Z16_UNORM_S8_UINT:
686       return V_028040_Z_16;
687    case PIPE_FORMAT_S8_UINT_Z24_UNORM:
688    case PIPE_FORMAT_X8Z24_UNORM:
689    case PIPE_FORMAT_Z24X8_UNORM:
690    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
691       return V_028040_Z_24; /* not present on GFX12 */
692    case PIPE_FORMAT_Z32_FLOAT:
693    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
694       return V_028040_Z_32_FLOAT;
695    default:
696       return V_028040_Z_INVALID;
697    }
698 }
699 
700 bool
ac_is_zs_format_supported(enum pipe_format format)701 ac_is_zs_format_supported(enum pipe_format format)
702 {
703    return ac_translate_dbformat(format) != V_028040_Z_INVALID;
704 }
705 
706 uint32_t
ac_border_color_swizzle(const struct util_format_description * desc)707 ac_border_color_swizzle(const struct util_format_description *desc)
708 {
709    unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
710 
711    if (desc->format == PIPE_FORMAT_S8_UINT) {
712       /* Swizzle of 8-bit stencil format is defined as _x__ but the hw expects XYZW. */
713       assert(desc->swizzle[1] == PIPE_SWIZZLE_X);
714       return bc_swizzle;
715    }
716 
717    if (desc->swizzle[3] == PIPE_SWIZZLE_X) {
718       /* For the pre-defined border color values (white, opaque
719        * black, transparent black), the only thing that matters is
720        * that the alpha channel winds up in the correct place
721        * (because the RGB channels are all the same) so either of
722        * these enumerations will work.
723        */
724       if (desc->swizzle[2] == PIPE_SWIZZLE_Y)
725          bc_swizzle = V_008F20_BC_SWIZZLE_WZYX;
726       else
727          bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ;
728    } else if (desc->swizzle[0] == PIPE_SWIZZLE_X) {
729       if (desc->swizzle[1] == PIPE_SWIZZLE_Y)
730          bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
731       else
732          bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ;
733    } else if (desc->swizzle[1] == PIPE_SWIZZLE_X) {
734       bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ;
735    } else if (desc->swizzle[2] == PIPE_SWIZZLE_X) {
736       bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW;
737    }
738 
739    return bc_swizzle;
740 }
741 
742 /** Linearize and convert luminance/intensity to red. */
743 enum pipe_format
ac_simplify_cb_format(enum pipe_format format)744 ac_simplify_cb_format(enum pipe_format format)
745 {
746    format = util_format_linear(format);
747    format = util_format_luminance_to_red(format);
748    return util_format_intensity_to_red(format);
749 }
750 
751 bool
ac_alpha_is_on_msb(const struct radeon_info * info,enum pipe_format format)752 ac_alpha_is_on_msb(const struct radeon_info *info, enum pipe_format format)
753 {
754    if (info->gfx_level >= GFX11)
755       return false;
756 
757    format = ac_simplify_cb_format(format);
758    const struct util_format_description *desc = util_format_description(format);
759    unsigned comp_swap = ac_translate_colorswap(info->gfx_level, format, false);
760 
761    /* The following code matches the hw behavior. */
762    if (desc->nr_channels == 1) {
763       return (comp_swap == V_028C70_SWAP_ALT_REV) != (info->family == CHIP_RAVEN2 ||
764                                                       info->family == CHIP_RENOIR);
765    }
766 
767    return comp_swap != V_028C70_SWAP_STD_REV && comp_swap != V_028C70_SWAP_ALT_REV;
768 }
769 
770 /* GFX6-8:
771  * - no integer format support
772  * - no depth format support (depth formats without shadow samplers are supported,
773  *   but that's not enough)
774  * - only single-channel formats are supported
775  * - limitations of early chips (GFX6 only): no R9G9B9E5 support
776  *
777  * GFX9+:
778  * - all formats are supported
779  */
780 bool
ac_is_reduction_mode_supported(const struct radeon_info * info,enum pipe_format format,bool shadow_samplers)781 ac_is_reduction_mode_supported(const struct radeon_info *info, enum pipe_format format,
782                                bool shadow_samplers)
783 {
784    const struct util_format_description *desc = util_format_description(format);
785 
786    if (info->gfx_level <= GFX8) {
787       /* old HW limitations */
788       if (info->gfx_level == GFX6 && format == PIPE_FORMAT_R9G9B9E5_FLOAT)
789          return false;
790 
791       /* reject if more than one channel */
792       if (desc->nr_channels > 1)
793          return false;
794 
795       /* no integer or depth format support */
796       if (util_format_is_pure_integer(format) ||
797           (shadow_samplers && util_format_has_depth(desc)))
798          return false;
799    }
800 
801    return true;
802 }
803