• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
41 uint32_t
radv_translate_buffer_dataformat(const struct util_format_description * desc,int first_non_void)42 radv_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 
116 uint32_t
radv_translate_buffer_numformat(const struct util_format_description * desc,int first_non_void)117 radv_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 
150 void
radv_translate_vertex_format(const struct radv_physical_device * pdevice,VkFormat format,const struct util_format_description * desc,unsigned * dfmt,unsigned * nfmt,bool * post_shuffle,enum radv_vs_input_alpha_adjust * alpha_adjust)151 radv_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 
202 uint32_t
radv_translate_tex_dataformat(VkFormat format,const struct util_format_description * desc,int first_non_void)203 radv_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 
417 out_unknown:
418    /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */
419    return ~0;
420 }
421 
422 uint32_t
radv_translate_tex_numformat(VkFormat format,const struct util_format_description * desc,int first_non_void)423 radv_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 
485 uint32_t
radv_translate_color_numformat(VkFormat format,const struct util_format_description * desc,int first_non_void)486 radv_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 
518 static bool
radv_is_sampler_format_supported(VkFormat format,bool * linear_sampling)519 radv_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 
542 bool
radv_is_atomic_format_supported(VkFormat format)543 radv_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 
550 bool
radv_is_storage_image_format_supported(struct radv_physical_device * physical_device,VkFormat format)551 radv_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 
606 bool
radv_is_buffer_format_supported(VkFormat format,bool * scaled)607 radv_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 
624 bool
radv_is_colorbuffer_format_supported(const struct radv_physical_device * pdevice,VkFormat format,bool * blendable)625 radv_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 
647 static bool
radv_is_zs_format_supported(VkFormat format)648 radv_is_zs_format_supported(VkFormat format)
649 {
650    return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT;
651 }
652 
653 static bool
radv_is_filter_minmax_format_supported(VkFormat format)654 radv_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 
683 bool
radv_device_supports_etc(struct radv_physical_device * physical_device)684 radv_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 
692 static void
radv_physical_device_get_format_properties(struct radv_physical_device * physical_device,VkFormat format,VkFormatProperties3 * out_properties)693 radv_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 
892 uint32_t
radv_translate_colorformat(VkFormat format)893 radv_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 
975 uint32_t
radv_colorformat_endian_swap(uint32_t colorformat)976 radv_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 
1018 uint32_t
radv_translate_dbformat(VkFormat format)1019 radv_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 
1033 unsigned
radv_translate_colorswap(VkFormat format,bool do_endian_swap)1034 radv_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 
1096 bool
radv_format_pack_clear_color(VkFormat format,uint32_t clear_vals[2],VkClearColorValue * value)1097 radv_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 
1197 static const struct ac_modifier_options radv_modifier_options = {
1198    .dcc = true,
1199    .dcc_retile = true,
1200 };
1201 
1202 static VkFormatFeatureFlags2
radv_get_modifier_flags(struct radv_physical_device * dev,VkFormat format,uint64_t modifier,const VkFormatProperties3 * props)1203 radv_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 
1233 static VkFormatFeatureFlags
features2_to_features(VkFormatFeatureFlags2 features2)1234 features2_to_features(VkFormatFeatureFlags2 features2)
1235 {
1236    return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
1237 }
1238 
1239 static void
radv_list_drm_format_modifiers(struct radv_physical_device * dev,VkFormat format,const VkFormatProperties3 * format_props,VkDrmFormatModifierPropertiesListEXT * mod_list)1240 radv_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 
1296 static void
radv_list_drm_format_modifiers_2(struct radv_physical_device * dev,VkFormat format,const VkFormatProperties3 * format_props,VkDrmFormatModifierPropertiesList2EXT * mod_list)1297 radv_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 
1353 static VkResult
radv_check_modifier_support(struct radv_physical_device * dev,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * props,VkFormat format,uint64_t modifier)1354 radv_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 
1434 VKAPI_ATTR void VKAPI_CALL
radv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)1435 radv_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 
1466 static VkResult
radv_get_image_format_properties(struct radv_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * info,VkFormat format,VkImageFormatProperties * pImageFormatProperties)1467 radv_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;
1666 unsupported:
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 
1678 static void
get_external_image_format_properties(struct radv_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkExternalMemoryHandleTypeFlagBits handleType,VkExternalMemoryProperties * external_properties,VkImageFormatProperties * format_properties)1679 get_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 
1761 VKAPI_ATTR VkResult VKAPI_CALL
radv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * base_info,VkImageFormatProperties2 * base_props)1762 radv_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 
1868 fail:
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 
1883 static void
fill_sparse_image_format_properties(struct radv_physical_device * pdev,VkFormat format,VkSparseImageFormatProperties * prop)1884 fill_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 
1904 VKAPI_ATTR void VKAPI_CALL
radv_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)1905 radv_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 
1940 VKAPI_ATTR void VKAPI_CALL
radv_GetImageSparseMemoryRequirements2(VkDevice _device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1941 radv_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 
1990 VKAPI_ATTR void VKAPI_CALL
radv_GetDeviceImageSparseMemoryRequirements(VkDevice device,const VkDeviceImageMemoryRequirements * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1991 radv_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 
2017 VKAPI_ATTR void VKAPI_CALL
radv_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)2018 radv_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. */
2048 enum 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. */
2056 static void
radv_get_dcc_channel_type(const struct util_format_description * desc,enum dcc_channel_type * type,unsigned * size)2057 radv_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. */
2091 bool
radv_dcc_formats_compatible(enum amd_gfx_level gfx_level,VkFormat format1,VkFormat format2,bool * sign_reinterpret)2092 radv_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