1/*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25#include "radv_debug.h"
26#include "radv_private.h"
27
28#include "sid.h"
29#include "vk_format.h"
30
31#include "vk_util.h"
32
33#include "ac_drm_fourcc.h"
34#include "util/format_r11g11b10f.h"
35#include "util/format_rgb9e5.h"
36#include "util/format_srgb.h"
37#include "util/half_float.h"
38#include "vulkan/util/vk_format.h"
39#include "vulkan/util/vk_enum_defines.h"
40
41uint32_t
42radv_translate_buffer_dataformat(const struct util_format_description *desc, int first_non_void)
43{
44   unsigned type;
45   int i;
46
47   assert(util_format_get_num_planes(desc->format) == 1);
48
49   if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
50      return V_008F0C_BUF_DATA_FORMAT_10_11_11;
51
52   if (first_non_void < 0)
53      return V_008F0C_BUF_DATA_FORMAT_INVALID;
54   type = desc->channel[first_non_void].type;
55
56   if (type == UTIL_FORMAT_TYPE_FIXED)
57      return V_008F0C_BUF_DATA_FORMAT_INVALID;
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         return V_008F0C_BUF_DATA_FORMAT_8;
73      case 2:
74         return V_008F0C_BUF_DATA_FORMAT_8_8;
75      case 4:
76         return V_008F0C_BUF_DATA_FORMAT_8_8_8_8;
77      }
78      break;
79   case 16:
80      switch (desc->nr_channels) {
81      case 1:
82         return V_008F0C_BUF_DATA_FORMAT_16;
83      case 2:
84         return V_008F0C_BUF_DATA_FORMAT_16_16;
85      case 4:
86         return V_008F0C_BUF_DATA_FORMAT_16_16_16_16;
87      }
88      break;
89   case 32:
90      /* From the Southern Islands ISA documentation about MTBUF:
91       * 'Memory reads of data in memory that is 32 or 64 bits do not
92       * undergo any format conversion.'
93       */
94      if (type != UTIL_FORMAT_TYPE_FLOAT && !desc->channel[first_non_void].pure_integer)
95         return V_008F0C_BUF_DATA_FORMAT_INVALID;
96
97      switch (desc->nr_channels) {
98      case 1:
99         return V_008F0C_BUF_DATA_FORMAT_32;
100      case 2:
101         return V_008F0C_BUF_DATA_FORMAT_32_32;
102      case 3:
103         return V_008F0C_BUF_DATA_FORMAT_32_32_32;
104      case 4:
105         return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
106      }
107      break;
108   case 64:
109      if (type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1)
110         return V_008F0C_BUF_DATA_FORMAT_32_32;
111   }
112
113   return V_008F0C_BUF_DATA_FORMAT_INVALID;
114}
115
116uint32_t
117radv_translate_buffer_numformat(const struct util_format_description *desc, int first_non_void)
118{
119   assert(util_format_get_num_planes(desc->format) == 1);
120
121   if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
122      return V_008F0C_BUF_NUM_FORMAT_FLOAT;
123
124   if (first_non_void < 0)
125      return ~0;
126
127   switch (desc->channel[first_non_void].type) {
128   case UTIL_FORMAT_TYPE_SIGNED:
129      if (desc->channel[first_non_void].normalized)
130         return V_008F0C_BUF_NUM_FORMAT_SNORM;
131      else if (desc->channel[first_non_void].pure_integer)
132         return V_008F0C_BUF_NUM_FORMAT_SINT;
133      else
134         return V_008F0C_BUF_NUM_FORMAT_SSCALED;
135      break;
136   case UTIL_FORMAT_TYPE_UNSIGNED:
137      if (desc->channel[first_non_void].normalized)
138         return V_008F0C_BUF_NUM_FORMAT_UNORM;
139      else if (desc->channel[first_non_void].pure_integer)
140         return V_008F0C_BUF_NUM_FORMAT_UINT;
141      else
142         return V_008F0C_BUF_NUM_FORMAT_USCALED;
143      break;
144   case UTIL_FORMAT_TYPE_FLOAT:
145   default:
146      return V_008F0C_BUF_NUM_FORMAT_FLOAT;
147   }
148}
149
150void
151radv_translate_vertex_format(const struct radv_physical_device *pdevice, VkFormat format,
152                             const struct util_format_description *desc, unsigned *dfmt,
153                             unsigned *nfmt, bool *post_shuffle,
154                             enum radv_vs_input_alpha_adjust *alpha_adjust)
155{
156   assert(desc->channel[0].type != UTIL_FORMAT_TYPE_VOID);
157   *nfmt = radv_translate_buffer_numformat(desc, 0);
158   *dfmt = radv_translate_buffer_dataformat(desc, 0);
159
160   *alpha_adjust = ALPHA_ADJUST_NONE;
161   if (pdevice->rad_info.gfx_level <= GFX8 && pdevice->rad_info.family != CHIP_STONEY) {
162      switch (format) {
163      case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
164      case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
165         *alpha_adjust = ALPHA_ADJUST_SNORM;
166         break;
167      case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
168      case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
169         *alpha_adjust = ALPHA_ADJUST_SSCALED;
170         break;
171      case VK_FORMAT_A2R10G10B10_SINT_PACK32:
172      case VK_FORMAT_A2B10G10R10_SINT_PACK32:
173         *alpha_adjust = ALPHA_ADJUST_SINT;
174         break;
175      default:
176         break;
177      }
178   }
179
180   switch (format) {
181   case VK_FORMAT_B8G8R8A8_UNORM:
182   case VK_FORMAT_B8G8R8A8_SNORM:
183   case VK_FORMAT_B8G8R8A8_USCALED:
184   case VK_FORMAT_B8G8R8A8_SSCALED:
185   case VK_FORMAT_B8G8R8A8_UINT:
186   case VK_FORMAT_B8G8R8A8_SINT:
187   case VK_FORMAT_B8G8R8A8_SRGB:
188   case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
189   case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
190   case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
191   case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
192   case VK_FORMAT_A2R10G10B10_UINT_PACK32:
193   case VK_FORMAT_A2R10G10B10_SINT_PACK32:
194      *post_shuffle = true;
195      break;
196   default:
197      *post_shuffle = false;
198      break;
199   }
200}
201
202uint32_t
203radv_translate_tex_dataformat(VkFormat format, const struct util_format_description *desc,
204                              int first_non_void)
205{
206   bool uniform = true;
207   int i;
208
209   assert(vk_format_get_plane_count(format) == 1);
210
211   /* Colorspace (return non-RGB formats directly). */
212   switch (desc->colorspace) {
213      /* Depth stencil formats */
214   case UTIL_FORMAT_COLORSPACE_ZS:
215      switch (format) {
216      case VK_FORMAT_D16_UNORM:
217         return V_008F14_IMG_DATA_FORMAT_16;
218      case VK_FORMAT_D24_UNORM_S8_UINT:
219      case VK_FORMAT_X8_D24_UNORM_PACK32:
220         return V_008F14_IMG_DATA_FORMAT_8_24;
221      case VK_FORMAT_S8_UINT:
222         return V_008F14_IMG_DATA_FORMAT_8;
223      case VK_FORMAT_D32_SFLOAT:
224         return V_008F14_IMG_DATA_FORMAT_32;
225      case VK_FORMAT_D32_SFLOAT_S8_UINT:
226         return V_008F14_IMG_DATA_FORMAT_X24_8_32;
227      default:
228         goto out_unknown;
229      }
230
231   case UTIL_FORMAT_COLORSPACE_YUV:
232      goto out_unknown; /* TODO */
233
234   default:
235      break;
236   }
237
238   if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
239      switch (format) {
240      /* Don't ask me why this looks inverted. PAL does the same. */
241      case VK_FORMAT_G8B8G8R8_422_UNORM:
242         return V_008F14_IMG_DATA_FORMAT_BG_RG;
243      case VK_FORMAT_B8G8R8G8_422_UNORM:
244         return V_008F14_IMG_DATA_FORMAT_GB_GR;
245      default:
246         goto out_unknown;
247      }
248   }
249
250   if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
251      switch (format) {
252      case VK_FORMAT_BC4_UNORM_BLOCK:
253      case VK_FORMAT_BC4_SNORM_BLOCK:
254         return V_008F14_IMG_DATA_FORMAT_BC4;
255      case VK_FORMAT_BC5_UNORM_BLOCK:
256      case VK_FORMAT_BC5_SNORM_BLOCK:
257         return V_008F14_IMG_DATA_FORMAT_BC5;
258      default:
259         break;
260      }
261   }
262
263   if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
264      switch (format) {
265      case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
266      case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
267      case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
268      case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
269         return V_008F14_IMG_DATA_FORMAT_BC1;
270      case VK_FORMAT_BC2_UNORM_BLOCK:
271      case VK_FORMAT_BC2_SRGB_BLOCK:
272         return V_008F14_IMG_DATA_FORMAT_BC2;
273      case VK_FORMAT_BC3_UNORM_BLOCK:
274      case VK_FORMAT_BC3_SRGB_BLOCK:
275         return V_008F14_IMG_DATA_FORMAT_BC3;
276      default:
277         break;
278      }
279   }
280
281   if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
282      switch (format) {
283      case VK_FORMAT_BC6H_UFLOAT_BLOCK:
284      case VK_FORMAT_BC6H_SFLOAT_BLOCK:
285         return V_008F14_IMG_DATA_FORMAT_BC6;
286      case VK_FORMAT_BC7_UNORM_BLOCK:
287      case VK_FORMAT_BC7_SRGB_BLOCK:
288         return V_008F14_IMG_DATA_FORMAT_BC7;
289      default:
290         break;
291      }
292   }
293
294   if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
295      switch (format) {
296      case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
297      case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
298         return V_008F14_IMG_DATA_FORMAT_ETC2_RGB;
299      case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
300      case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
301         return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA1;
302      case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
303      case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
304         return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA;
305      case VK_FORMAT_EAC_R11_UNORM_BLOCK:
306      case VK_FORMAT_EAC_R11_SNORM_BLOCK:
307         return V_008F14_IMG_DATA_FORMAT_ETC2_R;
308      case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
309      case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
310         return V_008F14_IMG_DATA_FORMAT_ETC2_RG;
311      default:
312         break;
313      }
314   }
315
316   if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
317      return V_008F14_IMG_DATA_FORMAT_5_9_9_9;
318   } else if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
319      return V_008F14_IMG_DATA_FORMAT_10_11_11;
320   }
321
322   /* R8G8Bx_SNORM - TODO CxV8U8 */
323
324   /* hw cannot support mixed formats (except depth/stencil, since only
325    * depth is read).*/
326   if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
327      goto out_unknown;
328
329   /* See whether the components are of the same size. */
330   for (i = 1; i < desc->nr_channels; i++) {
331      uniform = uniform && desc->channel[0].size == desc->channel[i].size;
332   }
333
334   /* Non-uniform formats. */
335   if (!uniform) {
336      switch (desc->nr_channels) {
337      case 3:
338         if (desc->channel[0].size == 5 && desc->channel[1].size == 6 &&
339             desc->channel[2].size == 5) {
340            return V_008F14_IMG_DATA_FORMAT_5_6_5;
341         }
342         goto out_unknown;
343      case 4:
344         if (desc->channel[0].size == 5 && desc->channel[1].size == 5 &&
345             desc->channel[2].size == 5 && desc->channel[3].size == 1) {
346            return V_008F14_IMG_DATA_FORMAT_1_5_5_5;
347         }
348         if (desc->channel[0].size == 1 && desc->channel[1].size == 5 &&
349             desc->channel[2].size == 5 && desc->channel[3].size == 5) {
350            return V_008F14_IMG_DATA_FORMAT_5_5_5_1;
351         }
352         if (desc->channel[0].size == 10 && desc->channel[1].size == 10 &&
353             desc->channel[2].size == 10 && desc->channel[3].size == 2) {
354            /* Closed VK driver does this also no 2/10/10/10 snorm */
355            if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[0].normalized)
356               goto out_unknown;
357            return V_008F14_IMG_DATA_FORMAT_2_10_10_10;
358         }
359         goto out_unknown;
360      }
361      goto out_unknown;
362   }
363
364   if (first_non_void < 0 || first_non_void > 3)
365      goto out_unknown;
366
367   /* uniform formats */
368   switch (desc->channel[first_non_void].size) {
369   case 4:
370      switch (desc->nr_channels) {
371#if 0 /* Not supported for render targets */
372		case 2:
373			return V_008F14_IMG_DATA_FORMAT_4_4;
374#endif
375      case 4:
376         return V_008F14_IMG_DATA_FORMAT_4_4_4_4;
377      }
378      break;
379   case 8:
380      switch (desc->nr_channels) {
381      case 1:
382         return V_008F14_IMG_DATA_FORMAT_8;
383      case 2:
384         return V_008F14_IMG_DATA_FORMAT_8_8;
385      case 4:
386         return V_008F14_IMG_DATA_FORMAT_8_8_8_8;
387      }
388      break;
389   case 16:
390      switch (desc->nr_channels) {
391      case 1:
392         return V_008F14_IMG_DATA_FORMAT_16;
393      case 2:
394         return V_008F14_IMG_DATA_FORMAT_16_16;
395      case 4:
396         return V_008F14_IMG_DATA_FORMAT_16_16_16_16;
397      }
398      break;
399   case 32:
400      switch (desc->nr_channels) {
401      case 1:
402         return V_008F14_IMG_DATA_FORMAT_32;
403      case 2:
404         return V_008F14_IMG_DATA_FORMAT_32_32;
405      case 3:
406         return V_008F14_IMG_DATA_FORMAT_32_32_32;
407      case 4:
408         return V_008F14_IMG_DATA_FORMAT_32_32_32_32;
409      }
410      break;
411   case 64:
412      if (desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1)
413         return V_008F14_IMG_DATA_FORMAT_32_32;
414      break;
415   }
416
417out_unknown:
418   /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */
419   return ~0;
420}
421
422uint32_t
423radv_translate_tex_numformat(VkFormat format, const struct util_format_description *desc,
424                             int first_non_void)
425{
426   assert(vk_format_get_plane_count(format) == 1);
427
428   switch (format) {
429   case VK_FORMAT_D24_UNORM_S8_UINT:
430      return V_008F14_IMG_NUM_FORMAT_UNORM;
431   default:
432      if (first_non_void < 0) {
433         if (vk_format_is_compressed(format)) {
434            switch (format) {
435            case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
436            case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
437            case VK_FORMAT_BC2_SRGB_BLOCK:
438            case VK_FORMAT_BC3_SRGB_BLOCK:
439            case VK_FORMAT_BC7_SRGB_BLOCK:
440            case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
441            case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
442            case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
443               return V_008F14_IMG_NUM_FORMAT_SRGB;
444            case VK_FORMAT_BC4_SNORM_BLOCK:
445            case VK_FORMAT_BC5_SNORM_BLOCK:
446            case VK_FORMAT_BC6H_SFLOAT_BLOCK:
447            case VK_FORMAT_EAC_R11_SNORM_BLOCK:
448            case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
449               return V_008F14_IMG_NUM_FORMAT_SNORM;
450            default:
451               return V_008F14_IMG_NUM_FORMAT_UNORM;
452            }
453         } else if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
454            return V_008F14_IMG_NUM_FORMAT_UNORM;
455         } else {
456            return V_008F14_IMG_NUM_FORMAT_FLOAT;
457         }
458      } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
459         return V_008F14_IMG_NUM_FORMAT_SRGB;
460      } else {
461         switch (desc->channel[first_non_void].type) {
462         case UTIL_FORMAT_TYPE_FLOAT:
463            return V_008F14_IMG_NUM_FORMAT_FLOAT;
464         case UTIL_FORMAT_TYPE_SIGNED:
465            if (desc->channel[first_non_void].normalized)
466               return V_008F14_IMG_NUM_FORMAT_SNORM;
467            else if (desc->channel[first_non_void].pure_integer)
468               return V_008F14_IMG_NUM_FORMAT_SINT;
469            else
470               return V_008F14_IMG_NUM_FORMAT_SSCALED;
471         case UTIL_FORMAT_TYPE_UNSIGNED:
472            if (desc->channel[first_non_void].normalized)
473               return V_008F14_IMG_NUM_FORMAT_UNORM;
474            else if (desc->channel[first_non_void].pure_integer)
475               return V_008F14_IMG_NUM_FORMAT_UINT;
476            else
477               return V_008F14_IMG_NUM_FORMAT_USCALED;
478         default:
479            return V_008F14_IMG_NUM_FORMAT_UNORM;
480         }
481      }
482   }
483}
484
485uint32_t
486radv_translate_color_numformat(VkFormat format, const struct util_format_description *desc,
487                               int first_non_void)
488{
489   unsigned ntype;
490
491   assert(vk_format_get_plane_count(format) == 1);
492
493   if (first_non_void == -1 || desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_FLOAT)
494      ntype = V_028C70_NUMBER_FLOAT;
495   else {
496      ntype = V_028C70_NUMBER_UNORM;
497      if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
498         ntype = V_028C70_NUMBER_SRGB;
499      else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) {
500         if (desc->channel[first_non_void].pure_integer) {
501            ntype = V_028C70_NUMBER_SINT;
502         } else if (desc->channel[first_non_void].normalized) {
503            ntype = V_028C70_NUMBER_SNORM;
504         } else
505            ntype = ~0u;
506      } else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED) {
507         if (desc->channel[first_non_void].pure_integer) {
508            ntype = V_028C70_NUMBER_UINT;
509         } else if (desc->channel[first_non_void].normalized) {
510            ntype = V_028C70_NUMBER_UNORM;
511         } else
512            ntype = ~0u;
513      }
514   }
515   return ntype;
516}
517
518static bool
519radv_is_sampler_format_supported(VkFormat format, bool *linear_sampling)
520{
521   const struct util_format_description *desc = vk_format_description(format);
522   uint32_t num_format;
523   if (format == VK_FORMAT_UNDEFINED || format == VK_FORMAT_R64_UINT ||
524       format == VK_FORMAT_R64_SINT)
525      return false;
526   num_format =
527      radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format));
528
529   if (num_format == V_008F14_IMG_NUM_FORMAT_USCALED ||
530       num_format == V_008F14_IMG_NUM_FORMAT_SSCALED)
531      return false;
532
533   if (num_format == V_008F14_IMG_NUM_FORMAT_UNORM || num_format == V_008F14_IMG_NUM_FORMAT_SNORM ||
534       num_format == V_008F14_IMG_NUM_FORMAT_FLOAT || num_format == V_008F14_IMG_NUM_FORMAT_SRGB)
535      *linear_sampling = true;
536   else
537      *linear_sampling = false;
538   return radv_translate_tex_dataformat(format, vk_format_description(format),
539                                        vk_format_get_first_non_void_channel(format)) != ~0U;
540}
541
542bool
543radv_is_atomic_format_supported(VkFormat format)
544{
545   return format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT ||
546          format == VK_FORMAT_R32_SFLOAT || format == VK_FORMAT_R64_UINT ||
547          format == VK_FORMAT_R64_SINT;
548}
549
550bool
551radv_is_storage_image_format_supported(struct radv_physical_device *physical_device,
552                                       VkFormat format)
553{
554   const struct util_format_description *desc = vk_format_description(format);
555   unsigned data_format, num_format;
556   if (format == VK_FORMAT_UNDEFINED)
557      return false;
558
559   data_format =
560      radv_translate_tex_dataformat(format, desc, vk_format_get_first_non_void_channel(format));
561   num_format =
562      radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format));
563
564   if (data_format == ~0 || num_format == ~0)
565      return false;
566
567   /* Extracted from the GCN3 ISA document. */
568   switch (num_format) {
569   case V_008F14_IMG_NUM_FORMAT_UNORM:
570   case V_008F14_IMG_NUM_FORMAT_SNORM:
571   case V_008F14_IMG_NUM_FORMAT_UINT:
572   case V_008F14_IMG_NUM_FORMAT_SINT:
573   case V_008F14_IMG_NUM_FORMAT_FLOAT:
574      break;
575   default:
576      return false;
577   }
578
579   switch (data_format) {
580   case V_008F14_IMG_DATA_FORMAT_8:
581   case V_008F14_IMG_DATA_FORMAT_16:
582   case V_008F14_IMG_DATA_FORMAT_8_8:
583   case V_008F14_IMG_DATA_FORMAT_32:
584   case V_008F14_IMG_DATA_FORMAT_16_16:
585   case V_008F14_IMG_DATA_FORMAT_10_11_11:
586   case V_008F14_IMG_DATA_FORMAT_11_11_10:
587   case V_008F14_IMG_DATA_FORMAT_10_10_10_2:
588   case V_008F14_IMG_DATA_FORMAT_2_10_10_10:
589   case V_008F14_IMG_DATA_FORMAT_8_8_8_8:
590   case V_008F14_IMG_DATA_FORMAT_32_32:
591   case V_008F14_IMG_DATA_FORMAT_16_16_16_16:
592   case V_008F14_IMG_DATA_FORMAT_32_32_32_32:
593   case V_008F14_IMG_DATA_FORMAT_5_6_5:
594   case V_008F14_IMG_DATA_FORMAT_1_5_5_5:
595   case V_008F14_IMG_DATA_FORMAT_5_5_5_1:
596   case V_008F14_IMG_DATA_FORMAT_4_4_4_4:
597      /* TODO: FMASK formats. */
598      return true;
599   case V_008F14_IMG_DATA_FORMAT_5_9_9_9:
600      return physical_device->rad_info.gfx_level >= GFX10_3;
601   default:
602      return false;
603   }
604}
605
606bool
607radv_is_buffer_format_supported(VkFormat format, bool *scaled)
608{
609   const struct util_format_description *desc = vk_format_description(format);
610   unsigned data_format, num_format;
611   if (format == VK_FORMAT_UNDEFINED)
612      return false;
613
614   data_format =
615      radv_translate_buffer_dataformat(desc, vk_format_get_first_non_void_channel(format));
616   num_format = radv_translate_buffer_numformat(desc, vk_format_get_first_non_void_channel(format));
617
618   if (scaled)
619      *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) ||
620                (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED);
621   return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID && num_format != ~0;
622}
623
624bool
625radv_is_colorbuffer_format_supported(const struct radv_physical_device *pdevice, VkFormat format,
626                                     bool *blendable)
627{
628   const struct util_format_description *desc = vk_format_description(format);
629   uint32_t color_format = radv_translate_colorformat(format);
630   uint32_t color_swap = radv_translate_colorswap(format, false);
631   uint32_t color_num_format =
632      radv_translate_color_numformat(format, desc, vk_format_get_first_non_void_channel(format));
633
634   if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT ||
635       color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 ||
636       color_format == V_028C70_COLOR_X24_8_32_FLOAT) {
637      *blendable = false;
638   } else
639      *blendable = true;
640
641   if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 && pdevice->rad_info.gfx_level < GFX10_3)
642      return false;
643
644   return color_format != V_028C70_COLOR_INVALID && color_swap != ~0U && color_num_format != ~0;
645}
646
647static bool
648radv_is_zs_format_supported(VkFormat format)
649{
650   return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT;
651}
652
653static bool
654radv_is_filter_minmax_format_supported(VkFormat format)
655{
656   /* From the Vulkan spec 1.1.71:
657    *
658    * "The following formats must support the
659    *  VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with
660    *  VK_IMAGE_TILING_OPTIMAL, if they support
661    *  VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT."
662    */
663   /* TODO: enable more formats. */
664   switch (format) {
665   case VK_FORMAT_R8_UNORM:
666   case VK_FORMAT_R8_SNORM:
667   case VK_FORMAT_R16_UNORM:
668   case VK_FORMAT_R16_SNORM:
669   case VK_FORMAT_R16_SFLOAT:
670   case VK_FORMAT_R32_SFLOAT:
671   case VK_FORMAT_D16_UNORM:
672   case VK_FORMAT_X8_D24_UNORM_PACK32:
673   case VK_FORMAT_D32_SFLOAT:
674   case VK_FORMAT_D16_UNORM_S8_UINT:
675   case VK_FORMAT_D24_UNORM_S8_UINT:
676   case VK_FORMAT_D32_SFLOAT_S8_UINT:
677      return true;
678   default:
679      return false;
680   }
681}
682
683bool
684radv_device_supports_etc(struct radv_physical_device *physical_device)
685{
686   return physical_device->rad_info.family == CHIP_VEGA10 ||
687          physical_device->rad_info.family == CHIP_RAVEN ||
688          physical_device->rad_info.family == CHIP_RAVEN2 ||
689          physical_device->rad_info.family == CHIP_STONEY;
690}
691
692static void
693radv_physical_device_get_format_properties(struct radv_physical_device *physical_device,
694                                           VkFormat format, VkFormatProperties3 *out_properties)
695{
696   VkFormatFeatureFlags2 linear = 0, tiled = 0, buffer = 0;
697   const struct util_format_description *desc = vk_format_description(format);
698   bool blendable;
699   bool scaled = false;
700   /* TODO: implement some software emulation of SUBSAMPLED formats. */
701   if (desc->format == PIPE_FORMAT_NONE || desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
702      out_properties->linearTilingFeatures = linear;
703      out_properties->optimalTilingFeatures = tiled;
704      out_properties->bufferFeatures = buffer;
705      return;
706   }
707
708   if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && !radv_device_supports_etc(physical_device) &&
709       !physical_device->emulate_etc2) {
710      out_properties->linearTilingFeatures = linear;
711      out_properties->optimalTilingFeatures = tiled;
712      out_properties->bufferFeatures = buffer;
713      return;
714   }
715
716   const bool multiplanar = vk_format_get_plane_count(format) > 1;
717   if (multiplanar || desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
718      uint64_t tiling = VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT |
719                        VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT |
720                        VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT |
721                        VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT |
722                        VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT;
723
724      /* The subsampled formats have no support for linear filters. */
725      if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
726         tiling |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT;
727      }
728
729      if (multiplanar)
730         tiling |= VK_FORMAT_FEATURE_2_DISJOINT_BIT;
731
732      /* Fails for unknown reasons with linear tiling & subsampled formats. */
733      out_properties->linearTilingFeatures =
734         desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED ? 0 : tiling;
735      out_properties->optimalTilingFeatures = tiling;
736      out_properties->bufferFeatures = 0;
737      return;
738   }
739
740   if (radv_is_storage_image_format_supported(physical_device, format)) {
741      tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT |
742               VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
743               VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
744      linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT |
745                VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
746                VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
747   }
748
749   if (radv_is_buffer_format_supported(format, &scaled)) {
750      if (format != VK_FORMAT_R64_UINT && format != VK_FORMAT_R64_SINT &&
751          !vk_format_is_srgb(format)) {
752         buffer |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT;
753         if (!scaled)
754            buffer |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT;
755      }
756      buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT |
757                VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT |
758                VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT;
759   }
760
761   if (vk_format_is_depth_or_stencil(format)) {
762      if (radv_is_zs_format_supported(format)) {
763         tiled |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT;
764         tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT;
765         tiled |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
766         tiled |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
767
768         if (radv_is_filter_minmax_format_supported(format))
769            tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
770
771         if (vk_format_has_depth(format)) {
772            tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT |
773                     VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT;
774         }
775
776         /* Don't support blitting surfaces with depth/stencil. */
777         if (vk_format_has_depth(format) && vk_format_has_stencil(format))
778            tiled &= ~VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
779
780         /* Don't support linear depth surfaces */
781         linear = 0;
782      }
783   } else {
784      bool linear_sampling;
785      if (radv_is_sampler_format_supported(format, &linear_sampling)) {
786         linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
787         tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
788
789         if (radv_is_filter_minmax_format_supported(format))
790            tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT;
791
792         if (linear_sampling) {
793            linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
794            tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
795         }
796
797         /* Don't support blitting for R32G32B32 formats. */
798         if (format == VK_FORMAT_R32G32B32_SFLOAT || format == VK_FORMAT_R32G32B32_UINT ||
799             format == VK_FORMAT_R32G32B32_SINT) {
800            linear &= ~VK_FORMAT_FEATURE_2_BLIT_SRC_BIT;
801         }
802      }
803      if (radv_is_colorbuffer_format_supported(physical_device, format, &blendable)) {
804         linear |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
805         tiled |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT;
806         if (blendable) {
807            linear |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
808            tiled |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT;
809         }
810      }
811      if (tiled && !scaled) {
812         tiled |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
813      }
814
815      /* Tiled formatting does not support NPOT pixel sizes */
816      if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format)))
817         tiled = 0;
818   }
819
820   if (linear && !scaled) {
821      linear |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT;
822   }
823
824   if (radv_is_atomic_format_supported(format)) {
825      buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
826      linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
827      tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT;
828   }
829
830   switch (format) {
831   case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
832   case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
833   case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
834   case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
835   case VK_FORMAT_A2R10G10B10_SINT_PACK32:
836   case VK_FORMAT_A2B10G10R10_SINT_PACK32:
837      buffer &=
838         ~(VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT);
839      linear = 0;
840      tiled = 0;
841      break;
842   default:
843      break;
844   }
845
846   switch (format) {
847   case VK_FORMAT_R32G32_SFLOAT:
848   case VK_FORMAT_R32G32B32_SFLOAT:
849   case VK_FORMAT_R32G32B32A32_SFLOAT:
850   case VK_FORMAT_R16G16_SFLOAT:
851   case VK_FORMAT_R16G16B16_SFLOAT:
852   case VK_FORMAT_R16G16B16A16_SFLOAT:
853   case VK_FORMAT_R16G16_SNORM:
854   case VK_FORMAT_R16G16_UNORM:
855   case VK_FORMAT_R16G16B16A16_SNORM:
856   case VK_FORMAT_R16G16B16A16_UNORM:
857   case VK_FORMAT_R8G8_SNORM:
858   case VK_FORMAT_R8G8_UNORM:
859   case VK_FORMAT_R8G8B8A8_SNORM:
860   case VK_FORMAT_R8G8B8A8_UNORM:
861   case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
862      buffer |= VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR;
863      break;
864   default:
865      break;
866   }
867   /* addrlib does not support linear compressed textures. */
868   if (vk_format_is_compressed(format))
869      linear = 0;
870
871   /* From the Vulkan spec 1.2.163:
872    *
873    * "VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT must be supported for the
874    *  following formats if the attachmentFragmentShadingRate feature is supported:"
875    *
876    * - VK_FORMAT_R8_UINT
877    */
878   if (format == VK_FORMAT_R8_UINT) {
879      tiled |= VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
880   }
881
882   /* It's invalid to expose buffer features with depth/stencil formats. */
883   if (vk_format_is_depth_or_stencil(format)) {
884      buffer = 0;
885   }
886
887   out_properties->linearTilingFeatures = linear;
888   out_properties->optimalTilingFeatures = tiled;
889   out_properties->bufferFeatures = buffer;
890}
891
892uint32_t
893radv_translate_colorformat(VkFormat format)
894{
895   const struct util_format_description *desc = vk_format_description(format);
896
897#define HAS_SIZE(x, y, z, w)                                                                       \
898   (desc->channel[0].size == (x) && desc->channel[1].size == (y) &&                                \
899    desc->channel[2].size == (z) && desc->channel[3].size == (w))
900
901   if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
902      return V_028C70_COLOR_10_11_11;
903
904   if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
905      return V_028C70_COLOR_5_9_9_9;
906
907   if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
908      return V_028C70_COLOR_INVALID;
909
910   /* hw cannot support mixed formats (except depth/stencil, since
911    * stencil is not written to). */
912   if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
913      return V_028C70_COLOR_INVALID;
914
915   switch (desc->nr_channels) {
916   case 1:
917      switch (desc->channel[0].size) {
918      case 8:
919         return V_028C70_COLOR_8;
920      case 16:
921         return V_028C70_COLOR_16;
922      case 32:
923         return V_028C70_COLOR_32;
924      }
925      break;
926   case 2:
927      if (desc->channel[0].size == desc->channel[1].size) {
928         switch (desc->channel[0].size) {
929         case 8:
930            return V_028C70_COLOR_8_8;
931         case 16:
932            return V_028C70_COLOR_16_16;
933         case 32:
934            return V_028C70_COLOR_32_32;
935         }
936      } else if (HAS_SIZE(8, 24, 0, 0)) {
937         return V_028C70_COLOR_24_8;
938      } else if (HAS_SIZE(24, 8, 0, 0)) {
939         return V_028C70_COLOR_8_24;
940      }
941      break;
942   case 3:
943      if (HAS_SIZE(5, 6, 5, 0)) {
944         return V_028C70_COLOR_5_6_5;
945      } else if (HAS_SIZE(32, 8, 24, 0)) {
946         return V_028C70_COLOR_X24_8_32_FLOAT;
947      }
948      break;
949   case 4:
950      if (desc->channel[0].size == desc->channel[1].size &&
951          desc->channel[0].size == desc->channel[2].size &&
952          desc->channel[0].size == desc->channel[3].size) {
953         switch (desc->channel[0].size) {
954         case 4:
955            return V_028C70_COLOR_4_4_4_4;
956         case 8:
957            return V_028C70_COLOR_8_8_8_8;
958         case 16:
959            return V_028C70_COLOR_16_16_16_16;
960         case 32:
961            return V_028C70_COLOR_32_32_32_32;
962         }
963      } else if (HAS_SIZE(5, 5, 5, 1)) {
964         return V_028C70_COLOR_1_5_5_5;
965      } else if (HAS_SIZE(1, 5, 5, 5)) {
966         return V_028C70_COLOR_5_5_5_1;
967      } else if (HAS_SIZE(10, 10, 10, 2)) {
968         return V_028C70_COLOR_2_10_10_10;
969      }
970      break;
971   }
972   return V_028C70_COLOR_INVALID;
973}
974
975uint32_t
976radv_colorformat_endian_swap(uint32_t colorformat)
977{
978   if (0 /*SI_BIG_ENDIAN*/) {
979      switch (colorformat) {
980         /* 8-bit buffers. */
981      case V_028C70_COLOR_8:
982         return V_028C70_ENDIAN_NONE;
983
984         /* 16-bit buffers. */
985      case V_028C70_COLOR_5_6_5:
986      case V_028C70_COLOR_1_5_5_5:
987      case V_028C70_COLOR_4_4_4_4:
988      case V_028C70_COLOR_16:
989      case V_028C70_COLOR_8_8:
990         return V_028C70_ENDIAN_8IN16;
991
992         /* 32-bit buffers. */
993      case V_028C70_COLOR_8_8_8_8:
994      case V_028C70_COLOR_2_10_10_10:
995      case V_028C70_COLOR_8_24:
996      case V_028C70_COLOR_24_8:
997      case V_028C70_COLOR_16_16:
998         return V_028C70_ENDIAN_8IN32;
999
1000         /* 64-bit buffers. */
1001      case V_028C70_COLOR_16_16_16_16:
1002         return V_028C70_ENDIAN_8IN16;
1003
1004      case V_028C70_COLOR_32_32:
1005         return V_028C70_ENDIAN_8IN32;
1006
1007         /* 128-bit buffers. */
1008      case V_028C70_COLOR_32_32_32_32:
1009         return V_028C70_ENDIAN_8IN32;
1010      default:
1011         return V_028C70_ENDIAN_NONE; /* Unsupported. */
1012      }
1013   } else {
1014      return V_028C70_ENDIAN_NONE;
1015   }
1016}
1017
1018uint32_t
1019radv_translate_dbformat(VkFormat format)
1020{
1021   switch (format) {
1022   case VK_FORMAT_D16_UNORM:
1023   case VK_FORMAT_D16_UNORM_S8_UINT:
1024      return V_028040_Z_16;
1025   case VK_FORMAT_D32_SFLOAT:
1026   case VK_FORMAT_D32_SFLOAT_S8_UINT:
1027      return V_028040_Z_32_FLOAT;
1028   default:
1029      return V_028040_Z_INVALID;
1030   }
1031}
1032
1033unsigned
1034radv_translate_colorswap(VkFormat format, bool do_endian_swap)
1035{
1036   const struct util_format_description *desc = vk_format_description(format);
1037
1038#define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz)
1039
1040   if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
1041      return V_028C70_SWAP_STD;
1042
1043   if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
1044      return V_028C70_SWAP_STD;
1045
1046   if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
1047      return ~0U;
1048
1049   switch (desc->nr_channels) {
1050   case 1:
1051      if (HAS_SWIZZLE(0, X))
1052         return V_028C70_SWAP_STD; /* X___ */
1053      else if (HAS_SWIZZLE(3, X))
1054         return V_028C70_SWAP_ALT_REV; /* ___X */
1055      break;
1056   case 2:
1057      if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) ||
1058          (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y)))
1059         return V_028C70_SWAP_STD; /* XY__ */
1060      else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) ||
1061               (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) ||
1062               (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X)))
1063         /* YX__ */
1064         return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
1065      else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y))
1066         return V_028C70_SWAP_ALT; /* X__Y */
1067      else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X))
1068         return V_028C70_SWAP_ALT_REV; /* Y__X */
1069      break;
1070   case 3:
1071      if (HAS_SWIZZLE(0, X))
1072         return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
1073      else if (HAS_SWIZZLE(0, Z))
1074         return V_028C70_SWAP_STD_REV; /* ZYX */
1075      break;
1076   case 4:
1077      /* check the middle channels, the 1st and 4th channel can be NONE */
1078      if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) {
1079         return V_028C70_SWAP_STD; /* XYZW */
1080      } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) {
1081         return V_028C70_SWAP_STD_REV; /* WZYX */
1082      } else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) {
1083         return V_028C70_SWAP_ALT; /* ZYXW */
1084      } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) {
1085         /* YZWX */
1086         if (desc->is_array)
1087            return V_028C70_SWAP_ALT_REV;
1088         else
1089            return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
1090      }
1091      break;
1092   }
1093   return ~0U;
1094}
1095
1096bool
1097radv_format_pack_clear_color(VkFormat format, uint32_t clear_vals[2], VkClearColorValue *value)
1098{
1099   const struct util_format_description *desc = vk_format_description(format);
1100
1101   if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
1102      clear_vals[0] = float3_to_r11g11b10f(value->float32);
1103      clear_vals[1] = 0;
1104      return true;
1105   } else if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
1106      clear_vals[0] = float3_to_rgb9e5(value->float32);
1107      clear_vals[1] = 0;
1108      return true;
1109   }
1110
1111   if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
1112      fprintf(stderr, "failed to fast clear for non-plain format %d\n", format);
1113      return false;
1114   }
1115
1116   if (!util_is_power_of_two_or_zero(desc->block.bits)) {
1117      fprintf(stderr, "failed to fast clear for NPOT format %d\n", format);
1118      return false;
1119   }
1120
1121   if (desc->block.bits > 64) {
1122      /*
1123       * We have a 128 bits format, check if the first 3 components are the same.
1124       * Every elements has to be 32 bits since we don't support 64-bit formats,
1125       * and we can skip swizzling checks as alpha always comes last for these and
1126       * we do not care about the rest as they have to be the same.
1127       */
1128      if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
1129         if (value->float32[0] != value->float32[1] || value->float32[0] != value->float32[2])
1130            return false;
1131      } else {
1132         if (value->uint32[0] != value->uint32[1] || value->uint32[0] != value->uint32[2])
1133            return false;
1134      }
1135      clear_vals[0] = value->uint32[0];
1136      clear_vals[1] = value->uint32[3];
1137      return true;
1138   }
1139   uint64_t clear_val = 0;
1140
1141   for (unsigned c = 0; c < 4; ++c) {
1142      if (desc->swizzle[c] >= 4)
1143         continue;
1144
1145      const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
1146      assert(channel->size);
1147
1148      uint64_t v = 0;
1149      if (channel->pure_integer) {
1150         v = value->uint32[c] & ((1ULL << channel->size) - 1);
1151      } else if (channel->normalized) {
1152         if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED && desc->swizzle[c] < 3 &&
1153             desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
1154            assert(channel->size == 8);
1155
1156            v = util_format_linear_float_to_srgb_8unorm(value->float32[c]);
1157         } else {
1158            float f = MIN2(value->float32[c], 1.0f);
1159
1160            if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED) {
1161               f = MAX2(f, 0.0f) * ((1ULL << channel->size) - 1);
1162            } else {
1163               f = MAX2(f, -1.0f) * ((1ULL << (channel->size - 1)) - 1);
1164            }
1165
1166            /* The hardware rounds before conversion. */
1167            if (f > 0)
1168               f += 0.5f;
1169            else
1170               f -= 0.5f;
1171
1172            v = (uint64_t)f;
1173         }
1174      } else if (channel->type == UTIL_FORMAT_TYPE_FLOAT) {
1175         if (channel->size == 32) {
1176            memcpy(&v, &value->float32[c], 4);
1177         } else if (channel->size == 16) {
1178            v = _mesa_float_to_float16_rtz(value->float32[c]);
1179         } else {
1180            fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format);
1181            return false;
1182         }
1183      } else {
1184         fprintf(stderr, "failed to fast clear for unhandled component type in format %d\n",
1185                 format);
1186         return false;
1187      }
1188      clear_val |= (v & ((1ULL << channel->size) - 1)) << channel->shift;
1189   }
1190
1191   clear_vals[0] = clear_val;
1192   clear_vals[1] = clear_val >> 32;
1193
1194   return true;
1195}
1196
1197static const struct ac_modifier_options radv_modifier_options = {
1198   .dcc = true,
1199   .dcc_retile = true,
1200};
1201
1202static VkFormatFeatureFlags2
1203radv_get_modifier_flags(struct radv_physical_device *dev, VkFormat format, uint64_t modifier,
1204                        const VkFormatProperties3 *props)
1205{
1206   VkFormatFeatureFlags2 features;
1207
1208   if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format))
1209      return 0;
1210
1211   if (modifier == DRM_FORMAT_MOD_LINEAR)
1212      features = props->linearTilingFeatures;
1213   else
1214      features = props->optimalTilingFeatures;
1215
1216   /* Unconditionally disable DISJOINT support for modifiers for now */
1217   features &= ~VK_FORMAT_FEATURE_2_DISJOINT_BIT;
1218
1219   if (ac_modifier_has_dcc(modifier)) {
1220      /* Only disable support for STORAGE_IMAGE on modifiers that
1221       * do not support DCC image stores.
1222       */
1223      if (!ac_modifier_supports_dcc_image_stores(modifier) || radv_is_atomic_format_supported(format))
1224         features &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT;
1225
1226      if (dev->instance->debug_flags & (RADV_DEBUG_NO_DCC | RADV_DEBUG_NO_DISPLAY_DCC))
1227         return 0;
1228   }
1229
1230   return features;
1231}
1232
1233static VkFormatFeatureFlags
1234features2_to_features(VkFormatFeatureFlags2 features2)
1235{
1236   return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
1237}
1238
1239static void
1240radv_list_drm_format_modifiers(struct radv_physical_device *dev, VkFormat format,
1241                               const VkFormatProperties3 *format_props,
1242                               VkDrmFormatModifierPropertiesListEXT *mod_list)
1243{
1244   unsigned mod_count;
1245
1246   if (!mod_list)
1247      return;
1248
1249   if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) {
1250      mod_list->drmFormatModifierCount = 0;
1251      return;
1252   }
1253
1254   VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out,
1255                          mod_list->pDrmFormatModifierProperties,
1256                          &mod_list->drmFormatModifierCount);
1257
1258   ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1259                              vk_format_to_pipe_format(format), &mod_count, NULL);
1260
1261   uint64_t *mods = malloc(mod_count * sizeof(uint64_t));
1262   if (!mods) {
1263      /* We can't return an error here ... */
1264      mod_list->drmFormatModifierCount = 0;
1265      return;
1266   }
1267   ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1268                              vk_format_to_pipe_format(format), &mod_count, mods);
1269
1270   for (unsigned i = 0; i < mod_count; ++i) {
1271      VkFormatFeatureFlags2 features =
1272         radv_get_modifier_flags(dev, format, mods[i], format_props);
1273      unsigned planes = vk_format_get_plane_count(format);
1274      if (planes == 1) {
1275         if (ac_modifier_has_dcc_retile(mods[i]))
1276            planes = 3;
1277         else if (ac_modifier_has_dcc(mods[i]))
1278            planes = 2;
1279      }
1280
1281      if (!features)
1282         continue;
1283
1284      vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, out_props) {
1285         *out_props = (VkDrmFormatModifierPropertiesEXT) {
1286            .drmFormatModifier = mods[i],
1287            .drmFormatModifierPlaneCount = planes,
1288            .drmFormatModifierTilingFeatures = features2_to_features(features),
1289         };
1290      };
1291   }
1292
1293   free(mods);
1294}
1295
1296static void
1297radv_list_drm_format_modifiers_2(struct radv_physical_device *dev, VkFormat format,
1298                                 const VkFormatProperties3 *format_props,
1299                                 VkDrmFormatModifierPropertiesList2EXT *mod_list)
1300{
1301   unsigned mod_count;
1302
1303   if (!mod_list)
1304      return;
1305
1306   if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) {
1307      mod_list->drmFormatModifierCount = 0;
1308      return;
1309   }
1310
1311   VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out,
1312                          mod_list->pDrmFormatModifierProperties,
1313                          &mod_list->drmFormatModifierCount);
1314
1315   ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1316                              vk_format_to_pipe_format(format), &mod_count, NULL);
1317
1318   uint64_t *mods = malloc(mod_count * sizeof(uint64_t));
1319   if (!mods) {
1320      /* We can't return an error here ... */
1321      mod_list->drmFormatModifierCount = 0;
1322      return;
1323   }
1324   ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1325                              vk_format_to_pipe_format(format), &mod_count, mods);
1326
1327   for (unsigned i = 0; i < mod_count; ++i) {
1328      VkFormatFeatureFlags2 features =
1329         radv_get_modifier_flags(dev, format, mods[i], format_props);
1330      unsigned planes = vk_format_get_plane_count(format);
1331      if (planes == 1) {
1332         if (ac_modifier_has_dcc_retile(mods[i]))
1333            planes = 3;
1334         else if (ac_modifier_has_dcc(mods[i]))
1335            planes = 2;
1336      }
1337
1338      if (!features)
1339         continue;
1340
1341      vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, out_props) {
1342         *out_props = (VkDrmFormatModifierProperties2EXT) {
1343            .drmFormatModifier = mods[i],
1344            .drmFormatModifierPlaneCount = planes,
1345            .drmFormatModifierTilingFeatures = features,
1346         };
1347      };
1348   }
1349
1350   free(mods);
1351}
1352
1353static VkResult
1354radv_check_modifier_support(struct radv_physical_device *dev,
1355                            const VkPhysicalDeviceImageFormatInfo2 *info,
1356                            VkImageFormatProperties *props, VkFormat format, uint64_t modifier)
1357{
1358   const struct util_format_description *desc = vk_format_description(format);
1359   uint32_t max_width, max_height;
1360
1361   if (info->type != VK_IMAGE_TYPE_2D)
1362      return VK_ERROR_FORMAT_NOT_SUPPORTED;
1363
1364   if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && dev->emulate_etc2)
1365      return VK_ERROR_FORMAT_NOT_SUPPORTED;
1366
1367   /* We did not add modifiers for sparse textures. */
1368   if (info->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT |
1369                      VK_IMAGE_CREATE_SPARSE_ALIASED_BIT))
1370      return VK_ERROR_FORMAT_NOT_SUPPORTED;
1371
1372   /*
1373    * Need to check the modifier is supported in general:
1374    * "If the drmFormatModifier is incompatible with the parameters specified
1375    * in VkPhysicalDeviceImageFormatInfo2 and its pNext chain, then
1376    * vkGetPhysicalDeviceImageFormatProperties2 returns VK_ERROR_FORMAT_NOT_SUPPORTED.
1377    * The implementation must support the query of any drmFormatModifier,
1378    * including unknown and invalid modifier values."
1379    */
1380   VkDrmFormatModifierPropertiesListEXT mod_list = {
1381      .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
1382   };
1383
1384   VkFormatProperties2 format_props2 = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
1385                                        .pNext = &mod_list};
1386
1387   radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format,
1388                                           &format_props2);
1389
1390   if (!mod_list.drmFormatModifierCount)
1391      return VK_ERROR_FORMAT_NOT_SUPPORTED;
1392
1393   mod_list.pDrmFormatModifierProperties =
1394      calloc(mod_list.drmFormatModifierCount, sizeof(*mod_list.pDrmFormatModifierProperties));
1395   if (!mod_list.pDrmFormatModifierProperties)
1396      return VK_ERROR_OUT_OF_HOST_MEMORY;
1397
1398   radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format,
1399                                           &format_props2);
1400
1401   bool found = false;
1402   for (uint32_t i = 0; i < mod_list.drmFormatModifierCount && !found; ++i)
1403      if (mod_list.pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
1404         found = true;
1405
1406   free(mod_list.pDrmFormatModifierProperties);
1407
1408   if (!found)
1409      return VK_ERROR_FORMAT_NOT_SUPPORTED;
1410
1411   bool need_dcc_sign_reinterpret = false;
1412   if (ac_modifier_has_dcc(modifier) &&
1413       !radv_are_formats_dcc_compatible(dev, info->pNext, format, info->flags,
1414                                        &need_dcc_sign_reinterpret) &&
1415       !need_dcc_sign_reinterpret)
1416      return VK_ERROR_FORMAT_NOT_SUPPORTED;
1417
1418   /* We can expand this as needed and implemented but there is not much demand
1419    * for more. */
1420   if (ac_modifier_has_dcc(modifier)) {
1421      props->maxMipLevels = 1;
1422      props->maxArrayLayers = 1;
1423   }
1424
1425   ac_modifier_max_extent(&dev->rad_info, modifier, &max_width, &max_height);
1426   props->maxExtent.width = MIN2(props->maxExtent.width, max_width);
1427   props->maxExtent.height = MIN2(props->maxExtent.width, max_height);
1428
1429   /* We don't support MSAA for modifiers */
1430   props->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
1431   return VK_SUCCESS;
1432}
1433
1434VKAPI_ATTR void VKAPI_CALL
1435radv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
1436                                        VkFormatProperties2 *pFormatProperties)
1437{
1438   RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1439   VkFormatProperties3 format_props;
1440
1441   radv_physical_device_get_format_properties(physical_device, format, &format_props);
1442
1443   pFormatProperties->formatProperties.linearTilingFeatures =
1444      features2_to_features(format_props.linearTilingFeatures);
1445   pFormatProperties->formatProperties.optimalTilingFeatures =
1446      features2_to_features(format_props.optimalTilingFeatures);
1447   pFormatProperties->formatProperties.bufferFeatures =
1448      features2_to_features(format_props.bufferFeatures);
1449
1450   VkFormatProperties3 *format_props_extended =
1451      vk_find_struct(pFormatProperties, FORMAT_PROPERTIES_3);
1452   if (format_props_extended) {
1453      format_props_extended->linearTilingFeatures = format_props.linearTilingFeatures;
1454      format_props_extended->optimalTilingFeatures = format_props.optimalTilingFeatures;
1455      format_props_extended->bufferFeatures = format_props.bufferFeatures;
1456   }
1457
1458   radv_list_drm_format_modifiers(
1459      physical_device, format, &format_props,
1460      vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT));
1461   radv_list_drm_format_modifiers_2(
1462      physical_device, format, &format_props,
1463      vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT));
1464}
1465
1466static VkResult
1467radv_get_image_format_properties(struct radv_physical_device *physical_device,
1468                                 const VkPhysicalDeviceImageFormatInfo2 *info, VkFormat format,
1469                                 VkImageFormatProperties *pImageFormatProperties)
1470
1471{
1472   VkFormatProperties3 format_props;
1473   VkFormatFeatureFlags2 format_feature_flags;
1474   VkExtent3D maxExtent;
1475   uint32_t maxMipLevels;
1476   uint32_t maxArraySize;
1477   VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1478   const struct util_format_description *desc = vk_format_description(format);
1479   enum amd_gfx_level gfx_level = physical_device->rad_info.gfx_level;
1480   VkImageTiling tiling = info->tiling;
1481   const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *mod_info =
1482      vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
1483   VkResult result = VK_ERROR_FORMAT_NOT_SUPPORTED;
1484
1485   radv_physical_device_get_format_properties(physical_device, format, &format_props);
1486   if (tiling == VK_IMAGE_TILING_LINEAR) {
1487      format_feature_flags = format_props.linearTilingFeatures;
1488   } else if (tiling == VK_IMAGE_TILING_OPTIMAL) {
1489      format_feature_flags = format_props.optimalTilingFeatures;
1490   } else if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
1491      format_feature_flags = radv_get_modifier_flags(physical_device, format,
1492                                                     mod_info->drmFormatModifier, &format_props);
1493   } else {
1494      unreachable("bad VkImageTiling");
1495   }
1496
1497   if (format_feature_flags == 0)
1498      goto unsupported;
1499
1500   if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(format))
1501      goto unsupported;
1502
1503   switch (info->type) {
1504   default:
1505      unreachable("bad vkimage type\n");
1506   case VK_IMAGE_TYPE_1D:
1507      maxExtent.width = 16384;
1508      maxExtent.height = 1;
1509      maxExtent.depth = 1;
1510      maxMipLevels = 15; /* log2(maxWidth) + 1 */
1511      maxArraySize = gfx_level >= GFX10 ? 8192 : 2048;
1512      break;
1513   case VK_IMAGE_TYPE_2D:
1514      maxExtent.width = 16384;
1515      maxExtent.height = 16384;
1516      maxExtent.depth = 1;
1517      maxMipLevels = 15; /* log2(maxWidth) + 1 */
1518      maxArraySize = gfx_level >= GFX10 ? 8192 : 2048;
1519      break;
1520   case VK_IMAGE_TYPE_3D:
1521      if (gfx_level >= GFX10) {
1522         maxExtent.width = 8192;
1523         maxExtent.height = 8192;
1524         maxExtent.depth = 8192;
1525      } else {
1526         maxExtent.width = 2048;
1527         maxExtent.height = 2048;
1528         maxExtent.depth = 2048;
1529      }
1530      maxMipLevels = util_logbase2(maxExtent.width) + 1;
1531      maxArraySize = 1;
1532      break;
1533   }
1534
1535   if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
1536      /* Might be able to support but the entire format support is
1537       * messy, so taking the lazy way out. */
1538      maxArraySize = 1;
1539   }
1540
1541   if (tiling == VK_IMAGE_TILING_OPTIMAL && info->type == VK_IMAGE_TYPE_2D &&
1542       (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
1543                                VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
1544       !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
1545       !(info->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)) {
1546      sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
1547   }
1548
1549   if (tiling == VK_IMAGE_TILING_LINEAR &&
1550       (format == VK_FORMAT_R32G32B32_SFLOAT || format == VK_FORMAT_R32G32B32_SINT ||
1551        format == VK_FORMAT_R32G32B32_UINT)) {
1552      /* R32G32B32 is a weird format and the driver currently only
1553       * supports the barely minimum.
1554       * TODO: Implement more if we really need to.
1555       */
1556      if (info->type == VK_IMAGE_TYPE_3D)
1557         goto unsupported;
1558      maxArraySize = 1;
1559      maxMipLevels = 1;
1560   }
1561
1562   /* We can't create 3d compressed 128bpp images that can be rendered to on GFX9 */
1563   if (physical_device->rad_info.gfx_level >= GFX9 && info->type == VK_IMAGE_TYPE_3D &&
1564       vk_format_get_blocksizebits(format) == 128 && vk_format_is_compressed(format) &&
1565       (info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
1566       ((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) ||
1567        (info->usage & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT))) {
1568      goto unsupported;
1569   }
1570
1571   /* From the Vulkan 1.3.206 spec:
1572    *
1573    * "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT specifies that the image can be created with usage flags
1574    * that are not supported for the format the image is created with but are supported for at least
1575    * one format a VkImageView created from the image can have."
1576    */
1577   VkImageUsageFlags image_usage = info->usage;
1578   if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT)
1579      image_usage = 0;
1580
1581   if (image_usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
1582      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) {
1583         goto unsupported;
1584      }
1585   }
1586
1587   if (image_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
1588      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) {
1589         goto unsupported;
1590      }
1591   }
1592
1593   if (image_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1594      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) {
1595         goto unsupported;
1596      }
1597   }
1598
1599   if (image_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1600      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) {
1601         goto unsupported;
1602      }
1603   }
1604
1605   if (image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1606      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) {
1607         goto unsupported;
1608      }
1609   }
1610
1611   if (image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1612      if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) {
1613         goto unsupported;
1614      }
1615   }
1616
1617   if (image_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1618      if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT |
1619                                    VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT))) {
1620         goto unsupported;
1621      }
1622   }
1623
1624   /* Sparse resources with multi-planar formats are unsupported. */
1625   if (info->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
1626      if (vk_format_get_plane_count(format) > 1)
1627         goto unsupported;
1628   }
1629
1630   if (info->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
1631      /* Sparse textures are only supported on GFX8+. */
1632      if (physical_device->rad_info.gfx_level < GFX8)
1633         goto unsupported;
1634
1635      if (vk_format_get_plane_count(format) > 1 || info->type != VK_IMAGE_TYPE_2D ||
1636          info->tiling != VK_IMAGE_TILING_OPTIMAL || vk_format_is_depth_or_stencil(format))
1637         goto unsupported;
1638   }
1639
1640   if ((info->flags &
1641        (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) &&
1642       (desc->layout == UTIL_FORMAT_LAYOUT_ETC && physical_device->emulate_etc2)) {
1643      goto unsupported;
1644   }
1645
1646   *pImageFormatProperties = (VkImageFormatProperties){
1647      .maxExtent = maxExtent,
1648      .maxMipLevels = maxMipLevels,
1649      .maxArrayLayers = maxArraySize,
1650      .sampleCounts = sampleCounts,
1651
1652      /* FINISHME: Accurately calculate
1653       * VkImageFormatProperties::maxResourceSize.
1654       */
1655      .maxResourceSize = UINT32_MAX,
1656   };
1657
1658   if (mod_info) {
1659      result = radv_check_modifier_support(physical_device, info, pImageFormatProperties, format,
1660                                           mod_info->drmFormatModifier);
1661      if (result != VK_SUCCESS)
1662         goto unsupported;
1663   }
1664
1665   return VK_SUCCESS;
1666unsupported:
1667   *pImageFormatProperties = (VkImageFormatProperties){
1668      .maxExtent = {0, 0, 0},
1669      .maxMipLevels = 0,
1670      .maxArrayLayers = 0,
1671      .sampleCounts = 0,
1672      .maxResourceSize = 0,
1673   };
1674
1675   return result;
1676}
1677
1678static void
1679get_external_image_format_properties(struct radv_physical_device *physical_device,
1680                                     const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
1681                                     VkExternalMemoryHandleTypeFlagBits handleType,
1682                                     VkExternalMemoryProperties *external_properties,
1683                                     VkImageFormatProperties *format_properties)
1684{
1685   VkExternalMemoryFeatureFlagBits flags = 0;
1686   VkExternalMemoryHandleTypeFlags export_flags = 0;
1687   VkExternalMemoryHandleTypeFlags compat_flags = 0;
1688   const struct util_format_description *desc = vk_format_description(pImageFormatInfo->format);
1689
1690   if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && physical_device->emulate_etc2)
1691      return;
1692
1693   if (pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1694      return;
1695
1696   switch (handleType) {
1697   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1698      if (pImageFormatInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1699         break;
1700
1701      switch (pImageFormatInfo->type) {
1702      case VK_IMAGE_TYPE_2D:
1703         flags =
1704            VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1705
1706         compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1707         break;
1708      default:
1709         break;
1710      }
1711      break;
1712   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
1713      switch (pImageFormatInfo->type) {
1714      case VK_IMAGE_TYPE_2D:
1715         flags =
1716            VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1717         if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
1718            flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
1719
1720         compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
1721         break;
1722      default:
1723         break;
1724      }
1725      break;
1726   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
1727      if (!physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer)
1728         break;
1729
1730      if (!radv_android_gralloc_supports_format(pImageFormatInfo->format, pImageFormatInfo->usage))
1731         break;
1732
1733      if (pImageFormatInfo->type != VK_IMAGE_TYPE_2D)
1734         break;
1735
1736      format_properties->maxMipLevels = MIN2(1, format_properties->maxMipLevels);
1737      format_properties->maxArrayLayers = MIN2(1, format_properties->maxArrayLayers);
1738      format_properties->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
1739
1740      flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1741      if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
1742         flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
1743
1744      compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
1745      break;
1746   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
1747      flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1748      compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
1749      break;
1750   default:
1751      break;
1752   }
1753
1754   *external_properties = (VkExternalMemoryProperties){
1755      .externalMemoryFeatures = flags,
1756      .exportFromImportedHandleTypes = export_flags,
1757      .compatibleHandleTypes = compat_flags,
1758   };
1759}
1760
1761VKAPI_ATTR VkResult VKAPI_CALL
1762radv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
1763                                             const VkPhysicalDeviceImageFormatInfo2 *base_info,
1764                                             VkImageFormatProperties2 *base_props)
1765{
1766   RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1767   const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
1768   VkExternalImageFormatProperties *external_props = NULL;
1769   struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
1770   VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
1771   VkTextureLODGatherFormatPropertiesAMD *texture_lod_props = NULL;
1772   VkResult result;
1773   VkFormat format = radv_select_android_external_format(base_info->pNext, base_info->format);
1774
1775   result = radv_get_image_format_properties(physical_device, base_info, format,
1776                                             &base_props->imageFormatProperties);
1777   if (result != VK_SUCCESS)
1778      return result;
1779
1780   /* Extract input structs */
1781   vk_foreach_struct_const(s, base_info->pNext)
1782   {
1783      switch (s->sType) {
1784      case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
1785         external_info = (const void *)s;
1786         break;
1787      default:
1788         break;
1789      }
1790   }
1791
1792   /* Extract output structs */
1793   vk_foreach_struct(s, base_props->pNext)
1794   {
1795      switch (s->sType) {
1796      case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
1797         external_props = (void *)s;
1798         break;
1799      case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
1800         ycbcr_props = (void *)s;
1801         break;
1802      case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID:
1803         android_usage = (void *)s;
1804         break;
1805      case VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD:
1806         texture_lod_props = (void *)s;
1807         break;
1808      default:
1809         break;
1810      }
1811   }
1812
1813   bool ahb_supported =
1814      physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer;
1815   if (android_usage && ahb_supported) {
1816#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
1817      android_usage->androidHardwareBufferUsage =
1818         radv_ahb_usage_from_vk_usage(base_info->flags, base_info->usage);
1819#endif
1820   }
1821
1822   /* From the Vulkan 1.0.97 spec:
1823    *
1824    *    If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
1825    *    behave as if VkPhysicalDeviceExternalImageFormatInfo was not
1826    *    present and VkExternalImageFormatProperties will be ignored.
1827    */
1828   if (external_info && external_info->handleType != 0) {
1829      VkExternalImageFormatProperties fallback_external_props;
1830
1831      if (!external_props) {
1832         memset(&fallback_external_props, 0, sizeof(fallback_external_props));
1833         external_props = &fallback_external_props;
1834      }
1835
1836      get_external_image_format_properties(physical_device, base_info, external_info->handleType,
1837                                           &external_props->externalMemoryProperties,
1838                                           &base_props->imageFormatProperties);
1839      if (!external_props->externalMemoryProperties.externalMemoryFeatures) {
1840         /* From the Vulkan 1.0.97 spec:
1841          *
1842          *    If handleType is not compatible with the [parameters] specified
1843          *    in VkPhysicalDeviceImageFormatInfo2, then
1844          *    vkGetPhysicalDeviceImageFormatProperties2 returns
1845          *    VK_ERROR_FORMAT_NOT_SUPPORTED.
1846          */
1847         result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
1848                            "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
1849                            external_info->handleType);
1850         goto fail;
1851      }
1852   }
1853
1854   if (ycbcr_props) {
1855      ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format);
1856   }
1857
1858   if (texture_lod_props) {
1859      if (physical_device->rad_info.gfx_level >= GFX9) {
1860         texture_lod_props->supportsTextureGatherLODBiasAMD = true;
1861      } else {
1862         texture_lod_props->supportsTextureGatherLODBiasAMD = !vk_format_is_int(format);
1863      }
1864   }
1865
1866   return VK_SUCCESS;
1867
1868fail:
1869   if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
1870      /* From the Vulkan 1.0.97 spec:
1871       *
1872       *    If the combination of parameters to
1873       *    vkGetPhysicalDeviceImageFormatProperties2 is not supported by
1874       *    the implementation for use in vkCreateImage, then all members of
1875       *    imageFormatProperties will be filled with zero.
1876       */
1877      base_props->imageFormatProperties = (VkImageFormatProperties){0};
1878   }
1879
1880   return result;
1881}
1882
1883static void
1884fill_sparse_image_format_properties(struct radv_physical_device *pdev, VkFormat format,
1885                                    VkSparseImageFormatProperties *prop)
1886{
1887   prop->aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1888   prop->flags = 0;
1889
1890   /* On GFX8 we first subdivide by level and then layer, leading to a single
1891    * miptail. On GFX9+ we first subdivide by layer and then level which results
1892    * in a miptail per layer. */
1893   if (pdev->rad_info.gfx_level < GFX9)
1894      prop->flags |= VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT;
1895
1896   /* This assumes the sparse image tile size is always 64 KiB (1 << 16) */
1897   unsigned l2_size = 16 - util_logbase2(vk_format_get_blocksize(format));
1898   unsigned w = (1u << ((l2_size + 1) / 2)) * vk_format_get_blockwidth(format);
1899   unsigned h = (1u << (l2_size / 2)) * vk_format_get_blockheight(format);
1900
1901   prop->imageGranularity = (VkExtent3D){w, h, 1};
1902}
1903
1904VKAPI_ATTR void VKAPI_CALL
1905radv_GetPhysicalDeviceSparseImageFormatProperties2(
1906   VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
1907   uint32_t *pPropertyCount, VkSparseImageFormatProperties2 *pProperties)
1908{
1909   RADV_FROM_HANDLE(radv_physical_device, pdev, physicalDevice);
1910   VkResult result;
1911
1912   if (pFormatInfo->samples > VK_SAMPLE_COUNT_1_BIT) {
1913      *pPropertyCount = 0;
1914      return;
1915   }
1916
1917   const VkPhysicalDeviceImageFormatInfo2 fmt_info = {
1918      .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
1919      .format = pFormatInfo->format,
1920      .type = pFormatInfo->type,
1921      .tiling = pFormatInfo->tiling,
1922      .usage = pFormatInfo->usage,
1923      .flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT};
1924
1925   VkImageFormatProperties fmt_props;
1926   result = radv_get_image_format_properties(pdev, &fmt_info, pFormatInfo->format, &fmt_props);
1927   if (result != VK_SUCCESS) {
1928      *pPropertyCount = 0;
1929      return;
1930   }
1931
1932   VK_OUTARRAY_MAKE_TYPED(VkSparseImageFormatProperties2, out, pProperties, pPropertyCount);
1933
1934   vk_outarray_append_typed(VkSparseImageFormatProperties2, &out, prop)
1935   {
1936      fill_sparse_image_format_properties(pdev, pFormatInfo->format, &prop->properties);
1937   };
1938}
1939
1940VKAPI_ATTR void VKAPI_CALL
1941radv_GetImageSparseMemoryRequirements2(VkDevice _device,
1942                                       const VkImageSparseMemoryRequirementsInfo2 *pInfo,
1943                                       uint32_t *pSparseMemoryRequirementCount,
1944                                       VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1945{
1946   RADV_FROM_HANDLE(radv_device, device, _device);
1947   RADV_FROM_HANDLE(radv_image, image, pInfo->image);
1948
1949   if (!(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
1950      *pSparseMemoryRequirementCount = 0;
1951      return;
1952   }
1953
1954   VK_OUTARRAY_MAKE_TYPED(VkSparseImageMemoryRequirements2, out, pSparseMemoryRequirements,
1955                          pSparseMemoryRequirementCount);
1956
1957   vk_outarray_append_typed(VkSparseImageMemoryRequirements2, &out, req)
1958   {
1959      fill_sparse_image_format_properties(device->physical_device, image->vk.format,
1960                                          &req->memoryRequirements.formatProperties);
1961      req->memoryRequirements.imageMipTailFirstLod = image->planes[0].surface.first_mip_tail_level;
1962
1963      if (req->memoryRequirements.imageMipTailFirstLod < image->info.levels) {
1964         if (device->physical_device->rad_info.gfx_level >= GFX9) {
1965            /* The tail is always a single tile per layer. */
1966            req->memoryRequirements.imageMipTailSize = 65536;
1967            req->memoryRequirements.imageMipTailOffset =
1968               image->planes[0]
1969                  .surface.u.gfx9.prt_level_offset[req->memoryRequirements.imageMipTailFirstLod] &
1970               ~65535;
1971            req->memoryRequirements.imageMipTailStride =
1972               image->planes[0].surface.u.gfx9.surf_slice_size;
1973         } else {
1974            req->memoryRequirements.imageMipTailOffset =
1975               (uint64_t)image->planes[0]
1976                  .surface.u.legacy.level[req->memoryRequirements.imageMipTailFirstLod]
1977                  .offset_256B * 256;
1978            req->memoryRequirements.imageMipTailSize =
1979               image->size - req->memoryRequirements.imageMipTailOffset;
1980            req->memoryRequirements.imageMipTailStride = 0;
1981         }
1982      } else {
1983         req->memoryRequirements.imageMipTailSize = 0;
1984         req->memoryRequirements.imageMipTailOffset = 0;
1985         req->memoryRequirements.imageMipTailStride = 0;
1986      }
1987   };
1988}
1989
1990VKAPI_ATTR void VKAPI_CALL
1991radv_GetDeviceImageSparseMemoryRequirements(VkDevice device,
1992                                            const VkDeviceImageMemoryRequirements* pInfo,
1993                                            uint32_t *pSparseMemoryRequirementCount,
1994                                            VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1995{
1996   UNUSED VkResult result;
1997   VkImage image;
1998
1999   /* Determining the image size/alignment require to create a surface, which is complicated without
2000    * creating an image.
2001    * TODO: Avoid creating an image.
2002    */
2003   result = radv_CreateImage(device, pInfo->pCreateInfo, NULL, &image);
2004   assert(result == VK_SUCCESS);
2005
2006   VkImageSparseMemoryRequirementsInfo2 info2 = {
2007      .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
2008      .image = image,
2009   };
2010
2011   radv_GetImageSparseMemoryRequirements2(device, &info2, pSparseMemoryRequirementCount,
2012                                          pSparseMemoryRequirements);
2013
2014   radv_DestroyImage(device, image, NULL);
2015}
2016
2017VKAPI_ATTR void VKAPI_CALL
2018radv_GetPhysicalDeviceExternalBufferProperties(
2019   VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
2020   VkExternalBufferProperties *pExternalBufferProperties)
2021{
2022   VkExternalMemoryFeatureFlagBits flags = 0;
2023   VkExternalMemoryHandleTypeFlags export_flags = 0;
2024   VkExternalMemoryHandleTypeFlags compat_flags = 0;
2025   switch (pExternalBufferInfo->handleType) {
2026   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
2027   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
2028      flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
2029      compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
2030                                    VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
2031      break;
2032   case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
2033      flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
2034      compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
2035      break;
2036   default:
2037      break;
2038   }
2039   pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties){
2040      .externalMemoryFeatures = flags,
2041      .exportFromImportedHandleTypes = export_flags,
2042      .compatibleHandleTypes = compat_flags,
2043   };
2044}
2045
2046/* DCC channel type categories within which formats can be reinterpreted
2047 * while keeping the same DCC encoding. The swizzle must also match. */
2048enum dcc_channel_type {
2049   dcc_channel_float,
2050   dcc_channel_uint,
2051   dcc_channel_sint,
2052   dcc_channel_incompatible,
2053};
2054
2055/* Return the type of DCC encoding. */
2056static void
2057radv_get_dcc_channel_type(const struct util_format_description *desc, enum dcc_channel_type *type,
2058                          unsigned *size)
2059{
2060   int i;
2061
2062   /* Find the first non-void channel. */
2063   for (i = 0; i < desc->nr_channels; i++)
2064      if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
2065         break;
2066   if (i == desc->nr_channels) {
2067      *type = dcc_channel_incompatible;
2068      return;
2069   }
2070
2071   switch (desc->channel[i].size) {
2072   case 32:
2073   case 16:
2074   case 10:
2075   case 8:
2076      *size = desc->channel[i].size;
2077      if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)
2078         *type = dcc_channel_float;
2079      else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
2080         *type = dcc_channel_uint;
2081      else
2082         *type = dcc_channel_sint;
2083      break;
2084   default:
2085      *type = dcc_channel_incompatible;
2086      break;
2087   }
2088}
2089
2090/* Return if it's allowed to reinterpret one format as another with DCC enabled. */
2091bool
2092radv_dcc_formats_compatible(enum amd_gfx_level gfx_level, VkFormat format1, VkFormat format2,
2093                            bool *sign_reinterpret)
2094{
2095   const struct util_format_description *desc1, *desc2;
2096   enum dcc_channel_type type1, type2;
2097   unsigned size1, size2;
2098   int i;
2099
2100   /* All formats are compatible on GFX11. */
2101   if (gfx_level >= GFX11)
2102      return true;
2103
2104   if (format1 == format2)
2105      return true;
2106
2107   desc1 = vk_format_description(format1);
2108   desc2 = vk_format_description(format2);
2109
2110   if (desc1->nr_channels != desc2->nr_channels)
2111      return false;
2112
2113   /* Swizzles must be the same. */
2114   for (i = 0; i < desc1->nr_channels; i++)
2115      if (desc1->swizzle[i] <= PIPE_SWIZZLE_W && desc2->swizzle[i] <= PIPE_SWIZZLE_W &&
2116          desc1->swizzle[i] != desc2->swizzle[i])
2117         return false;
2118
2119   radv_get_dcc_channel_type(desc1, &type1, &size1);
2120   radv_get_dcc_channel_type(desc2, &type2, &size2);
2121
2122   if (type1 == dcc_channel_incompatible || type2 == dcc_channel_incompatible ||
2123       (type1 == dcc_channel_float) != (type2 == dcc_channel_float) || size1 != size2)
2124      return false;
2125
2126   if (type1 != type2)
2127      *sign_reinterpret = true;
2128
2129   return true;
2130}
2131