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