OSDN Git Service

util/vulkan: Move Vulkan utilities to src/vulkan/util
[android-x86/external-mesa.git] / src / amd / vulkan / radv_formats.c
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_private.h"
26
27 #include "vk_format.h"
28 #include "sid.h"
29 #include "r600d_common.h"
30
31 #include "vk_util.h"
32
33 #include "util/u_half.h"
34 #include "util/format_srgb.h"
35 #include "util/format_r11g11b10f.h"
36
37 uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *desc,
38                                           int first_non_void)
39 {
40         unsigned type;
41         int i;
42
43         if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
44                 return V_008F0C_BUF_DATA_FORMAT_10_11_11;
45
46         if (first_non_void < 0)
47                 return V_008F0C_BUF_DATA_FORMAT_INVALID;
48         type = desc->channel[first_non_void].type;
49
50         if (type == VK_FORMAT_TYPE_FIXED)
51                 return V_008F0C_BUF_DATA_FORMAT_INVALID;
52         if (desc->nr_channels == 4 &&
53             desc->channel[0].size == 10 &&
54             desc->channel[1].size == 10 &&
55             desc->channel[2].size == 10 &&
56             desc->channel[3].size == 2)
57                 return V_008F0C_BUF_DATA_FORMAT_2_10_10_10;
58
59         /* See whether the components are of the same size. */
60         for (i = 0; i < desc->nr_channels; i++) {
61                 if (desc->channel[first_non_void].size != desc->channel[i].size)
62                         return V_008F0C_BUF_DATA_FORMAT_INVALID;
63         }
64
65         switch (desc->channel[first_non_void].size) {
66         case 8:
67                 switch (desc->nr_channels) {
68                 case 1:
69                         return V_008F0C_BUF_DATA_FORMAT_8;
70                 case 2:
71                         return V_008F0C_BUF_DATA_FORMAT_8_8;
72                 case 4:
73                         return V_008F0C_BUF_DATA_FORMAT_8_8_8_8;
74                 }
75                 break;
76         case 16:
77                 switch (desc->nr_channels) {
78                 case 1:
79                         return V_008F0C_BUF_DATA_FORMAT_16;
80                 case 2:
81                         return V_008F0C_BUF_DATA_FORMAT_16_16;
82                 case 4:
83                         return V_008F0C_BUF_DATA_FORMAT_16_16_16_16;
84                 }
85                 break;
86         case 32:
87                 /* From the Southern Islands ISA documentation about MTBUF:
88                  * 'Memory reads of data in memory that is 32 or 64 bits do not
89                  * undergo any format conversion.'
90                  */
91                 if (type != VK_FORMAT_TYPE_FLOAT &&
92                     !desc->channel[first_non_void].pure_integer)
93                         return V_008F0C_BUF_DATA_FORMAT_INVALID;
94
95                 switch (desc->nr_channels) {
96                 case 1:
97                         return V_008F0C_BUF_DATA_FORMAT_32;
98                 case 2:
99                         return V_008F0C_BUF_DATA_FORMAT_32_32;
100                 case 3:
101                         return V_008F0C_BUF_DATA_FORMAT_32_32_32;
102                 case 4:
103                         return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
104                 }
105                 break;
106         }
107
108         return V_008F0C_BUF_DATA_FORMAT_INVALID;
109 }
110
111 uint32_t radv_translate_buffer_numformat(const struct vk_format_description *desc,
112                                          int first_non_void)
113 {
114         if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
115                 return V_008F0C_BUF_NUM_FORMAT_FLOAT;
116
117         if (first_non_void < 0)
118                 return ~0;
119
120         switch (desc->channel[first_non_void].type) {
121         case VK_FORMAT_TYPE_SIGNED:
122                 if (desc->channel[first_non_void].normalized)
123                         return V_008F0C_BUF_NUM_FORMAT_SNORM;
124                 else if (desc->channel[first_non_void].pure_integer)
125                         return V_008F0C_BUF_NUM_FORMAT_SINT;
126                 else
127                         return V_008F0C_BUF_NUM_FORMAT_SSCALED;
128                 break;
129         case VK_FORMAT_TYPE_UNSIGNED:
130                 if (desc->channel[first_non_void].normalized)
131                         return V_008F0C_BUF_NUM_FORMAT_UNORM;
132                 else if (desc->channel[first_non_void].pure_integer)
133                         return V_008F0C_BUF_NUM_FORMAT_UINT;
134                 else
135                         return V_008F0C_BUF_NUM_FORMAT_USCALED;
136                 break;
137         case VK_FORMAT_TYPE_FLOAT:
138         default:
139                 return V_008F0C_BUF_NUM_FORMAT_FLOAT;
140         }
141 }
142
143 uint32_t radv_translate_tex_dataformat(VkFormat format,
144                                        const struct vk_format_description *desc,
145                                        int first_non_void)
146 {
147         bool uniform = true;
148         int i;
149
150         if (!desc)
151                 return ~0;
152         /* Colorspace (return non-RGB formats directly). */
153         switch (desc->colorspace) {
154                 /* Depth stencil formats */
155         case VK_FORMAT_COLORSPACE_ZS:
156                 switch (format) {
157                 case VK_FORMAT_D16_UNORM:
158                         return V_008F14_IMG_DATA_FORMAT_16;
159                 case VK_FORMAT_D24_UNORM_S8_UINT:
160                 case VK_FORMAT_X8_D24_UNORM_PACK32:
161                         return V_008F14_IMG_DATA_FORMAT_8_24;
162                 case VK_FORMAT_S8_UINT:
163                         return V_008F14_IMG_DATA_FORMAT_8;
164                 case VK_FORMAT_D32_SFLOAT:
165                         return V_008F14_IMG_DATA_FORMAT_32;
166                 case VK_FORMAT_D32_SFLOAT_S8_UINT:
167                         return V_008F14_IMG_DATA_FORMAT_X24_8_32;
168                 default:
169                         goto out_unknown;
170                 }
171
172         case VK_FORMAT_COLORSPACE_YUV:
173                 goto out_unknown; /* TODO */
174
175         case VK_FORMAT_COLORSPACE_SRGB:
176                 if (desc->nr_channels != 4 && desc->nr_channels != 1)
177                         goto out_unknown;
178                 break;
179
180         default:
181                 break;
182         }
183
184         if (desc->layout == VK_FORMAT_LAYOUT_RGTC) {
185                 switch(format) {
186                 case VK_FORMAT_BC4_UNORM_BLOCK:
187                 case VK_FORMAT_BC4_SNORM_BLOCK:
188                         return V_008F14_IMG_DATA_FORMAT_BC4;
189                 case VK_FORMAT_BC5_UNORM_BLOCK:
190                 case VK_FORMAT_BC5_SNORM_BLOCK:
191                         return V_008F14_IMG_DATA_FORMAT_BC5;
192                 default:
193                         break;
194                 }
195         }
196
197         if (desc->layout == VK_FORMAT_LAYOUT_S3TC) {
198                 switch(format) {
199                 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
200                 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
201                 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
202                 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
203                         return V_008F14_IMG_DATA_FORMAT_BC1;
204                 case VK_FORMAT_BC2_UNORM_BLOCK:
205                 case VK_FORMAT_BC2_SRGB_BLOCK:
206                         return V_008F14_IMG_DATA_FORMAT_BC2;
207                 case VK_FORMAT_BC3_UNORM_BLOCK:
208                 case VK_FORMAT_BC3_SRGB_BLOCK:
209                         return V_008F14_IMG_DATA_FORMAT_BC3;
210                 default:
211                         break;
212                 }
213         }
214
215         if (desc->layout == VK_FORMAT_LAYOUT_BPTC) {
216                 switch(format) {
217                 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
218                 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
219                         return V_008F14_IMG_DATA_FORMAT_BC6;
220                 case VK_FORMAT_BC7_UNORM_BLOCK:
221                 case VK_FORMAT_BC7_SRGB_BLOCK:
222                         return V_008F14_IMG_DATA_FORMAT_BC7;
223                 default:
224                         break;
225                 }
226         }
227
228         if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
229                 return V_008F14_IMG_DATA_FORMAT_5_9_9_9;
230         } else if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
231                 return V_008F14_IMG_DATA_FORMAT_10_11_11;
232         }
233
234         /* R8G8Bx_SNORM - TODO CxV8U8 */
235
236         /* hw cannot support mixed formats (except depth/stencil, since only
237          * depth is read).*/
238         if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS)
239                 goto out_unknown;
240
241         /* See whether the components are of the same size. */
242         for (i = 1; i < desc->nr_channels; i++) {
243                 uniform = uniform && desc->channel[0].size == desc->channel[i].size;
244         }
245
246         /* Non-uniform formats. */
247         if (!uniform) {
248                 switch(desc->nr_channels) {
249                 case 3:
250                         if (desc->channel[0].size == 5 &&
251                             desc->channel[1].size == 6 &&
252                             desc->channel[2].size == 5) {
253                                 return V_008F14_IMG_DATA_FORMAT_5_6_5;
254                         }
255                         goto out_unknown;
256                 case 4:
257                         if (desc->channel[0].size == 5 &&
258                             desc->channel[1].size == 5 &&
259                             desc->channel[2].size == 5 &&
260                             desc->channel[3].size == 1) {
261                                 return V_008F14_IMG_DATA_FORMAT_1_5_5_5;
262                         }
263                         if (desc->channel[0].size == 1 &&
264                             desc->channel[1].size == 5 &&
265                             desc->channel[2].size == 5 &&
266                             desc->channel[3].size == 5) {
267                                 return V_008F14_IMG_DATA_FORMAT_5_5_5_1;
268                         }
269                         if (desc->channel[0].size == 10 &&
270                             desc->channel[1].size == 10 &&
271                             desc->channel[2].size == 10 &&
272                             desc->channel[3].size == 2) {
273                                 /* Closed VK driver does this also no 2/10/10/10 snorm */
274                                 if (desc->channel[0].type == VK_FORMAT_TYPE_SIGNED &&
275                                     desc->channel[0].normalized)
276                                         goto out_unknown;
277                                 return V_008F14_IMG_DATA_FORMAT_2_10_10_10;
278                         }
279                         goto out_unknown;
280                 }
281                 goto out_unknown;
282         }
283
284         if (first_non_void < 0 || first_non_void > 3)
285                 goto out_unknown;
286
287         /* uniform formats */
288         switch (desc->channel[first_non_void].size) {
289         case 4:
290                 switch (desc->nr_channels) {
291 #if 0 /* Not supported for render targets */
292                 case 2:
293                         return V_008F14_IMG_DATA_FORMAT_4_4;
294 #endif
295                 case 4:
296                         return V_008F14_IMG_DATA_FORMAT_4_4_4_4;
297                 }
298                 break;
299         case 8:
300                 switch (desc->nr_channels) {
301                 case 1:
302                         return V_008F14_IMG_DATA_FORMAT_8;
303                 case 2:
304                         return V_008F14_IMG_DATA_FORMAT_8_8;
305                 case 4:
306                         return V_008F14_IMG_DATA_FORMAT_8_8_8_8;
307                 }
308                 break;
309         case 16:
310                 switch (desc->nr_channels) {
311                 case 1:
312                         return V_008F14_IMG_DATA_FORMAT_16;
313                 case 2:
314                         return V_008F14_IMG_DATA_FORMAT_16_16;
315                 case 4:
316                         return V_008F14_IMG_DATA_FORMAT_16_16_16_16;
317                 }
318                 break;
319         case 32:
320                 switch (desc->nr_channels) {
321                 case 1:
322                         return V_008F14_IMG_DATA_FORMAT_32;
323                 case 2:
324                         return V_008F14_IMG_DATA_FORMAT_32_32;
325 #if 0 /* Not supported for render targets */
326                 case 3:
327                         return V_008F14_IMG_DATA_FORMAT_32_32_32;
328 #endif
329                 case 4:
330                         return V_008F14_IMG_DATA_FORMAT_32_32_32_32;
331                 }
332         }
333
334 out_unknown:
335         /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */
336         return ~0;
337 }
338
339 uint32_t radv_translate_tex_numformat(VkFormat format,
340                                       const struct vk_format_description *desc,
341                                       int first_non_void)
342 {
343         switch (format) {
344         case VK_FORMAT_D24_UNORM_S8_UINT:
345                 return V_008F14_IMG_NUM_FORMAT_UNORM;
346         default:
347                 if (first_non_void < 0) {
348                         if (vk_format_is_compressed(format)) {
349                                 switch (format) {
350                                 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
351                                 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
352                                 case VK_FORMAT_BC2_SRGB_BLOCK:
353                                 case VK_FORMAT_BC3_SRGB_BLOCK:
354                                 case VK_FORMAT_BC7_SRGB_BLOCK:
355                                         return V_008F14_IMG_NUM_FORMAT_SRGB;
356                                 case VK_FORMAT_BC4_SNORM_BLOCK:
357                                 case VK_FORMAT_BC5_SNORM_BLOCK:
358                                 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
359                                         return V_008F14_IMG_NUM_FORMAT_SNORM;
360                                 default:
361                                         return V_008F14_IMG_NUM_FORMAT_UNORM;
362                                 }
363                         } else if (desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) {
364                                 return V_008F14_IMG_NUM_FORMAT_UNORM;
365                         } else {
366                                 return V_008F14_IMG_NUM_FORMAT_FLOAT;
367                         }
368                 } else if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
369                         return V_008F14_IMG_NUM_FORMAT_SRGB;
370                 } else {
371                         switch (desc->channel[first_non_void].type) {
372                         case VK_FORMAT_TYPE_FLOAT:
373                                 return V_008F14_IMG_NUM_FORMAT_FLOAT;
374                         case VK_FORMAT_TYPE_SIGNED:
375                                 if (desc->channel[first_non_void].normalized)
376                                         return V_008F14_IMG_NUM_FORMAT_SNORM;
377                                 else if (desc->channel[first_non_void].pure_integer)
378                                         return V_008F14_IMG_NUM_FORMAT_SINT;
379                                 else
380                                         return V_008F14_IMG_NUM_FORMAT_SSCALED;
381                         case VK_FORMAT_TYPE_UNSIGNED:
382                                 if (desc->channel[first_non_void].normalized)
383                                         return V_008F14_IMG_NUM_FORMAT_UNORM;
384                                 else if (desc->channel[first_non_void].pure_integer)
385                                         return V_008F14_IMG_NUM_FORMAT_UINT;
386                                 else
387                                         return V_008F14_IMG_NUM_FORMAT_USCALED;
388                         default:
389                                 return V_008F14_IMG_NUM_FORMAT_UNORM;
390                         }
391                 }
392         }
393 }
394
395 uint32_t radv_translate_color_numformat(VkFormat format,
396                                         const struct vk_format_description *desc,
397                                         int first_non_void)
398 {
399         unsigned ntype;
400         if (first_non_void == -1 || desc->channel[first_non_void].type == VK_FORMAT_TYPE_FLOAT)
401                 ntype = V_028C70_NUMBER_FLOAT;
402         else {
403                 ntype = V_028C70_NUMBER_UNORM;
404                 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB)
405                         ntype = V_028C70_NUMBER_SRGB;
406                 else if (desc->channel[first_non_void].type == VK_FORMAT_TYPE_SIGNED) {
407                         if (desc->channel[first_non_void].pure_integer) {
408                                 ntype = V_028C70_NUMBER_SINT;
409                         } else if (desc->channel[first_non_void].normalized) {
410                                 ntype = V_028C70_NUMBER_SNORM;
411                         } else
412                                 ntype = ~0u;
413                 } else if (desc->channel[first_non_void].type == VK_FORMAT_TYPE_UNSIGNED) {
414                         if (desc->channel[first_non_void].pure_integer) {
415                                 ntype = V_028C70_NUMBER_UINT;
416                         } else if (desc->channel[first_non_void].normalized) {
417                                 ntype = V_028C70_NUMBER_UNORM;
418                         } else
419                                 ntype = ~0u;
420                 }
421         }
422         return ntype;
423 }
424
425 static bool radv_is_sampler_format_supported(VkFormat format, bool *linear_sampling)
426 {
427         const struct vk_format_description *desc = vk_format_description(format);
428         uint32_t num_format;
429         if (!desc || format == VK_FORMAT_UNDEFINED)
430                 return false;
431         num_format = radv_translate_tex_numformat(format, desc,
432                                                   vk_format_get_first_non_void_channel(format));
433
434         if (num_format == V_008F14_IMG_NUM_FORMAT_USCALED ||
435             num_format == V_008F14_IMG_NUM_FORMAT_SSCALED)
436                 return false;
437
438         if (num_format == V_008F14_IMG_NUM_FORMAT_UNORM ||
439             num_format == V_008F14_IMG_NUM_FORMAT_SNORM ||
440             num_format == V_008F14_IMG_NUM_FORMAT_FLOAT ||
441             num_format == V_008F14_IMG_NUM_FORMAT_SRGB)
442                 *linear_sampling = true;
443         else
444                 *linear_sampling = false;
445         return radv_translate_tex_dataformat(format, vk_format_description(format),
446                                              vk_format_get_first_non_void_channel(format)) != ~0U;
447 }
448
449
450 static bool radv_is_storage_image_format_supported(struct radv_physical_device *physical_device,
451                                                    VkFormat format)
452 {
453         const struct vk_format_description *desc = vk_format_description(format);
454         unsigned data_format, num_format;
455         if (!desc || format == VK_FORMAT_UNDEFINED)
456                 return false;
457
458         data_format = radv_translate_tex_dataformat(format, desc,
459                                                     vk_format_get_first_non_void_channel(format));
460         num_format = radv_translate_tex_numformat(format, desc,
461                                                   vk_format_get_first_non_void_channel(format));
462
463         if(data_format == ~0 || num_format == ~0)
464                 return false;
465
466         /* Extracted from the GCN3 ISA document. */
467         switch(num_format) {
468         case V_008F14_IMG_NUM_FORMAT_UNORM:
469         case V_008F14_IMG_NUM_FORMAT_SNORM:
470         case V_008F14_IMG_NUM_FORMAT_UINT:
471         case V_008F14_IMG_NUM_FORMAT_SINT:
472         case V_008F14_IMG_NUM_FORMAT_FLOAT:
473                 break;
474         default:
475                 return false;
476         }
477
478         switch(data_format) {
479         case V_008F14_IMG_DATA_FORMAT_8:
480         case V_008F14_IMG_DATA_FORMAT_16:
481         case V_008F14_IMG_DATA_FORMAT_8_8:
482         case V_008F14_IMG_DATA_FORMAT_32:
483         case V_008F14_IMG_DATA_FORMAT_16_16:
484         case V_008F14_IMG_DATA_FORMAT_10_11_11:
485         case V_008F14_IMG_DATA_FORMAT_11_11_10:
486         case V_008F14_IMG_DATA_FORMAT_10_10_10_2:
487         case V_008F14_IMG_DATA_FORMAT_2_10_10_10:
488         case V_008F14_IMG_DATA_FORMAT_8_8_8_8:
489         case V_008F14_IMG_DATA_FORMAT_32_32:
490         case V_008F14_IMG_DATA_FORMAT_16_16_16_16:
491         case V_008F14_IMG_DATA_FORMAT_32_32_32_32:
492         case V_008F14_IMG_DATA_FORMAT_5_6_5:
493         case V_008F14_IMG_DATA_FORMAT_1_5_5_5:
494         case V_008F14_IMG_DATA_FORMAT_5_5_5_1:
495         case V_008F14_IMG_DATA_FORMAT_4_4_4_4:
496                 /* TODO: FMASK formats. */
497                 return true;
498         default:
499                 return false;
500         }
501 }
502
503 static bool radv_is_buffer_format_supported(VkFormat format, bool *scaled)
504 {
505         const struct vk_format_description *desc = vk_format_description(format);
506         unsigned data_format, num_format;
507         if (!desc || format == VK_FORMAT_UNDEFINED)
508                 return false;
509
510         data_format = radv_translate_buffer_dataformat(desc,
511                                                        vk_format_get_first_non_void_channel(format));
512         num_format = radv_translate_buffer_numformat(desc,
513                                                      vk_format_get_first_non_void_channel(format));
514
515         *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) || (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED);
516         return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID &&
517                 num_format != ~0;
518 }
519
520 bool radv_is_colorbuffer_format_supported(VkFormat format, bool *blendable)
521 {
522         const struct vk_format_description *desc = vk_format_description(format);
523         uint32_t color_format = radv_translate_colorformat(format);
524         uint32_t color_swap = radv_translate_colorswap(format, false);
525         uint32_t color_num_format = radv_translate_color_numformat(format,
526                                                                    desc,
527                                                                    vk_format_get_first_non_void_channel(format));
528
529         if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT ||
530             color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 ||
531             color_format == V_028C70_COLOR_X24_8_32_FLOAT) {
532                 *blendable = false;
533         } else
534                 *blendable = true;
535         return color_format != V_028C70_COLOR_INVALID &&
536                 color_swap != ~0U &&
537                 color_num_format != ~0;
538 }
539
540 static bool radv_is_zs_format_supported(VkFormat format)
541 {
542         return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT;
543 }
544
545 static void
546 radv_physical_device_get_format_properties(struct radv_physical_device *physical_device,
547                                            VkFormat format,
548                                            VkFormatProperties *out_properties)
549 {
550         VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0;
551         const struct vk_format_description *desc = vk_format_description(format);
552         bool blendable;
553         bool scaled = false;
554         if (!desc) {
555                 out_properties->linearTilingFeatures = linear;
556                 out_properties->optimalTilingFeatures = tiled;
557                 out_properties->bufferFeatures = buffer;
558                 return;
559         }
560
561         if (radv_is_storage_image_format_supported(physical_device, format)) {
562                 tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
563                 linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT;
564         }
565
566         if (radv_is_buffer_format_supported(format, &scaled)) {
567                 buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT;
568                 if (!scaled)
569                         buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
570                                 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT;
571         }
572
573         if (vk_format_is_depth_or_stencil(format)) {
574                 if (radv_is_zs_format_supported(format)) {
575                         tiled |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT;
576                         tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT;
577                         tiled |= VK_FORMAT_FEATURE_BLIT_SRC_BIT |
578                                  VK_FORMAT_FEATURE_BLIT_DST_BIT;
579                         tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR |
580                                  VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
581                 }
582         } else {
583                 bool linear_sampling;
584                 if (radv_is_sampler_format_supported(format, &linear_sampling)) {
585                         linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
586                                 VK_FORMAT_FEATURE_BLIT_SRC_BIT;
587                         tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
588                                 VK_FORMAT_FEATURE_BLIT_SRC_BIT;
589                         if (linear_sampling) {
590                                 linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
591                                 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
592                         }
593                 }
594                 if (radv_is_colorbuffer_format_supported(format, &blendable)) {
595                         linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
596                         tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
597                         if (blendable) {
598                                 linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
599                                 tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
600                         }
601                 }
602                 if (tiled && util_is_power_of_two(vk_format_get_blocksize(format)) && !scaled) {
603                         tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR |
604                                  VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
605                 }
606         }
607
608         if (linear && util_is_power_of_two(vk_format_get_blocksize(format)) && !scaled) {
609                 linear |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR |
610                           VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
611         }
612
613         if (format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT) {
614                 buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
615                 linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
616                 tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
617         }
618
619         out_properties->linearTilingFeatures = linear;
620         out_properties->optimalTilingFeatures = tiled;
621         out_properties->bufferFeatures = buffer;
622 }
623
624 uint32_t radv_translate_colorformat(VkFormat format)
625 {
626         const struct vk_format_description *desc = vk_format_description(format);
627
628 #define HAS_SIZE(x,y,z,w)                                               \
629         (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
630          desc->channel[2].size == (z) && desc->channel[3].size == (w))
631
632         if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
633                 return V_028C70_COLOR_10_11_11;
634
635         if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
636                 return V_028C70_COLOR_INVALID;
637
638         /* hw cannot support mixed formats (except depth/stencil, since
639          * stencil is not written to). */
640         if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS)
641                 return V_028C70_COLOR_INVALID;
642
643         switch (desc->nr_channels) {
644         case 1:
645                 switch (desc->channel[0].size) {
646                 case 8:
647                         return V_028C70_COLOR_8;
648                 case 16:
649                         return V_028C70_COLOR_16;
650                 case 32:
651                         return V_028C70_COLOR_32;
652                 }
653                 break;
654         case 2:
655                 if (desc->channel[0].size == desc->channel[1].size) {
656                         switch (desc->channel[0].size) {
657                         case 8:
658                                 return V_028C70_COLOR_8_8;
659                         case 16:
660                                 return V_028C70_COLOR_16_16;
661                         case 32:
662                                 return V_028C70_COLOR_32_32;
663                         }
664                 } else if (HAS_SIZE(8,24,0,0)) {
665                         return V_028C70_COLOR_24_8;
666                 } else if (HAS_SIZE(24,8,0,0)) {
667                         return V_028C70_COLOR_8_24;
668                 }
669                 break;
670         case 3:
671                 if (HAS_SIZE(5,6,5,0)) {
672                         return V_028C70_COLOR_5_6_5;
673                 } else if (HAS_SIZE(32,8,24,0)) {
674                         return V_028C70_COLOR_X24_8_32_FLOAT;
675                 }
676                 break;
677         case 4:
678                 if (desc->channel[0].size == desc->channel[1].size &&
679                     desc->channel[0].size == desc->channel[2].size &&
680                     desc->channel[0].size == desc->channel[3].size) {
681                         switch (desc->channel[0].size) {
682                         case 4:
683                                 return V_028C70_COLOR_4_4_4_4;
684                         case 8:
685                                 return V_028C70_COLOR_8_8_8_8;
686                         case 16:
687                                 return V_028C70_COLOR_16_16_16_16;
688                         case 32:
689                                 return V_028C70_COLOR_32_32_32_32;
690                         }
691                 } else if (HAS_SIZE(5,5,5,1)) {
692                         return V_028C70_COLOR_1_5_5_5;
693                 } else if (HAS_SIZE(1,5,5,5)) {
694                         return V_028C70_COLOR_5_5_5_1;
695                 } else if (HAS_SIZE(10,10,10,2)) {
696                         return V_028C70_COLOR_2_10_10_10;
697                 }
698                 break;
699         }
700         return V_028C70_COLOR_INVALID;
701 }
702
703 uint32_t radv_colorformat_endian_swap(uint32_t colorformat)
704 {
705         if (0/*SI_BIG_ENDIAN*/) {
706                 switch(colorformat) {
707                         /* 8-bit buffers. */
708                 case V_028C70_COLOR_8:
709                         return V_028C70_ENDIAN_NONE;
710
711                         /* 16-bit buffers. */
712                 case V_028C70_COLOR_5_6_5:
713                 case V_028C70_COLOR_1_5_5_5:
714                 case V_028C70_COLOR_4_4_4_4:
715                 case V_028C70_COLOR_16:
716                 case V_028C70_COLOR_8_8:
717                         return V_028C70_ENDIAN_8IN16;
718
719                         /* 32-bit buffers. */
720                 case V_028C70_COLOR_8_8_8_8:
721                 case V_028C70_COLOR_2_10_10_10:
722                 case V_028C70_COLOR_8_24:
723                 case V_028C70_COLOR_24_8:
724                 case V_028C70_COLOR_16_16:
725                         return V_028C70_ENDIAN_8IN32;
726
727                         /* 64-bit buffers. */
728                 case V_028C70_COLOR_16_16_16_16:
729                         return V_028C70_ENDIAN_8IN16;
730
731                 case V_028C70_COLOR_32_32:
732                         return V_028C70_ENDIAN_8IN32;
733
734                         /* 128-bit buffers. */
735                 case V_028C70_COLOR_32_32_32_32:
736                         return V_028C70_ENDIAN_8IN32;
737                 default:
738                         return V_028C70_ENDIAN_NONE; /* Unsupported. */
739                 }
740         } else {
741                 return V_028C70_ENDIAN_NONE;
742         }
743 }
744
745 uint32_t radv_translate_dbformat(VkFormat format)
746 {
747         switch (format) {
748         case VK_FORMAT_D16_UNORM:
749         case VK_FORMAT_D16_UNORM_S8_UINT:
750                 return V_028040_Z_16;
751         case VK_FORMAT_D32_SFLOAT:
752         case VK_FORMAT_D32_SFLOAT_S8_UINT:
753                 return V_028040_Z_32_FLOAT;
754         default:
755                 return V_028040_Z_INVALID;
756         }
757 }
758
759 unsigned radv_translate_colorswap(VkFormat format, bool do_endian_swap)
760 {
761         const struct vk_format_description *desc = vk_format_description(format);
762
763 #define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == VK_SWIZZLE_##swz)
764
765         if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
766                 return V_0280A0_SWAP_STD;
767
768         if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
769                 return ~0U;
770
771         switch (desc->nr_channels) {
772         case 1:
773                 if (HAS_SWIZZLE(0,X))
774                         return V_0280A0_SWAP_STD; /* X___ */
775                 else if (HAS_SWIZZLE(3,X))
776                         return V_0280A0_SWAP_ALT_REV; /* ___X */
777                 break;
778         case 2:
779                 if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) ||
780                     (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) ||
781                     (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y)))
782                         return V_0280A0_SWAP_STD; /* XY__ */
783                 else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) ||
784                          (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) ||
785                          (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X)))
786                         /* YX__ */
787                         return (do_endian_swap ? V_0280A0_SWAP_STD : V_0280A0_SWAP_STD_REV);
788                 else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y))
789                         return V_0280A0_SWAP_ALT; /* X__Y */
790                 else if (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(3,X))
791                         return V_0280A0_SWAP_ALT_REV; /* Y__X */
792                 break;
793         case 3:
794                 if (HAS_SWIZZLE(0,X))
795                         return (do_endian_swap ? V_0280A0_SWAP_STD_REV : V_0280A0_SWAP_STD);
796                 else if (HAS_SWIZZLE(0,Z))
797                         return V_0280A0_SWAP_STD_REV; /* ZYX */
798                 break;
799         case 4:
800                 /* check the middle channels, the 1st and 4th channel can be NONE */
801                 if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z)) {
802                         return V_0280A0_SWAP_STD; /* XYZW */
803                 } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y)) {
804                         return V_0280A0_SWAP_STD_REV; /* WZYX */
805                 } else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X)) {
806                         return V_0280A0_SWAP_ALT; /* ZYXW */
807                 } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,W)) {
808                         /* YZWX */
809                         if (desc->is_array)
810                                 return V_0280A0_SWAP_ALT_REV;
811                         else
812                                 return (do_endian_swap ? V_0280A0_SWAP_ALT : V_0280A0_SWAP_ALT_REV);
813                 }
814                 break;
815         }
816         return ~0U;
817 }
818
819 bool radv_format_pack_clear_color(VkFormat format,
820                                   uint32_t clear_vals[2],
821                                   VkClearColorValue *value)
822 {
823         uint8_t r = 0, g = 0, b = 0, a = 0;
824         const struct vk_format_description *desc = vk_format_description(format);
825
826         if (vk_format_get_component_bits(format, VK_FORMAT_COLORSPACE_RGB, 0) <= 8) {
827                 if (desc->colorspace == VK_FORMAT_COLORSPACE_RGB) {
828                         r = float_to_ubyte(value->float32[0]);
829                         g = float_to_ubyte(value->float32[1]);
830                         b = float_to_ubyte(value->float32[2]);
831                         a = float_to_ubyte(value->float32[3]);
832                 } else if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
833                         r = util_format_linear_float_to_srgb_8unorm(value->float32[0]);
834                         g = util_format_linear_float_to_srgb_8unorm(value->float32[1]);
835                         b = util_format_linear_float_to_srgb_8unorm(value->float32[2]);
836                         a = float_to_ubyte(value->float32[3]);
837                 }
838         }
839         switch (format) {
840         case VK_FORMAT_R8_UNORM:
841         case VK_FORMAT_R8_SRGB:
842                 clear_vals[0] = r;
843                 clear_vals[1] = 0;
844                 break;
845         case VK_FORMAT_R8G8_UNORM:
846         case VK_FORMAT_R8G8_SRGB:
847                 clear_vals[0] = r | g << 8;
848                 clear_vals[1] = 0;
849                 break;
850         case VK_FORMAT_R8G8B8A8_SRGB:
851         case VK_FORMAT_R8G8B8A8_UNORM:
852                 clear_vals[0] = r | g << 8 | b << 16 | a << 24;
853                 clear_vals[1] = 0;
854                 break;
855         case VK_FORMAT_B8G8R8A8_SRGB:
856         case VK_FORMAT_B8G8R8A8_UNORM:
857                 clear_vals[0] = b | g << 8 | r << 16 | a << 24;
858                 clear_vals[1] = 0;
859                 break;
860         case VK_FORMAT_A8B8G8R8_UNORM_PACK32:
861         case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
862                 clear_vals[0] = r | g << 8 | b << 16 | a << 24;
863                 clear_vals[1] = 0;
864                 break;
865         case VK_FORMAT_R8_UINT:
866                 clear_vals[0] = value->uint32[0] & 0xff;
867                 clear_vals[1] = 0;
868                 break;
869         case VK_FORMAT_R8_SINT:
870                 clear_vals[0] = value->int32[0] & 0xff;
871                 clear_vals[1] = 0;
872                 break;
873         case VK_FORMAT_R16_UINT:
874                 clear_vals[0] = value->uint32[0] & 0xffff;
875                 clear_vals[1] = 0;
876                 break;
877         case VK_FORMAT_R8G8_UINT:
878                 clear_vals[0] = value->uint32[0] & 0xff;
879                 clear_vals[0] |= (value->uint32[1] & 0xff) << 8;
880                 clear_vals[1] = 0;
881                 break;
882         case VK_FORMAT_R8G8_SINT:
883                 clear_vals[0] = value->int32[0] & 0xff;
884                 clear_vals[0] |= (value->int32[1] & 0xff) << 8;
885                 clear_vals[1] = 0;
886                 break;
887         case VK_FORMAT_R8G8B8A8_UINT:
888                 clear_vals[0] = value->uint32[0] & 0xff;
889                 clear_vals[0] |= (value->uint32[1] & 0xff) << 8;
890                 clear_vals[0] |= (value->uint32[2] & 0xff) << 16;
891                 clear_vals[0] |= (value->uint32[3] & 0xff) << 24;
892                 clear_vals[1] = 0;
893                 break;
894         case VK_FORMAT_R8G8B8A8_SINT:
895                 clear_vals[0] = value->int32[0] & 0xff;
896                 clear_vals[0] |= (value->int32[1] & 0xff) << 8;
897                 clear_vals[0] |= (value->int32[2] & 0xff) << 16;
898                 clear_vals[0] |= (value->int32[3] & 0xff) << 24;
899                 clear_vals[1] = 0;
900                 break;
901         case VK_FORMAT_A8B8G8R8_UINT_PACK32:
902                 clear_vals[0] = value->uint32[0] & 0xff;
903                 clear_vals[0] |= (value->uint32[1] & 0xff) << 8;
904                 clear_vals[0] |= (value->uint32[2] & 0xff) << 16;
905                 clear_vals[0] |= (value->uint32[3] & 0xff) << 24;
906                 clear_vals[1] = 0;
907                 break;
908         case VK_FORMAT_R16G16_UINT:
909                 clear_vals[0] = value->uint32[0] & 0xffff;
910                 clear_vals[0] |= (value->uint32[1] & 0xffff) << 16;
911                 clear_vals[1] = 0;
912                 break;
913         case VK_FORMAT_R16G16B16A16_UINT:
914                 clear_vals[0] = value->uint32[0] & 0xffff;
915                 clear_vals[0] |= (value->uint32[1] & 0xffff) << 16;
916                 clear_vals[1] = value->uint32[2] & 0xffff;
917                 clear_vals[1] |= (value->uint32[3] & 0xffff) << 16;
918                 break;
919         case VK_FORMAT_R32_UINT:
920                 clear_vals[0] = value->uint32[0];
921                 clear_vals[1] = 0;
922                 break;
923         case VK_FORMAT_R32G32_UINT:
924                 clear_vals[0] = value->uint32[0];
925                 clear_vals[1] = value->uint32[1];
926                 break;
927         case VK_FORMAT_R32_SINT:
928                 clear_vals[0] = value->int32[0];
929                 clear_vals[1] = 0;
930                 break;
931         case VK_FORMAT_R16_SFLOAT:
932                 clear_vals[0] = util_float_to_half(value->float32[0]);
933                 clear_vals[1] = 0;
934                 break;
935         case VK_FORMAT_R16G16_SFLOAT:
936                 clear_vals[0] = util_float_to_half(value->float32[0]);
937                 clear_vals[0] |= (uint32_t)util_float_to_half(value->float32[1]) << 16;
938                 clear_vals[1] = 0;
939                 break;
940         case VK_FORMAT_R16G16B16A16_SFLOAT:
941                 clear_vals[0] = util_float_to_half(value->float32[0]);
942                 clear_vals[0] |= (uint32_t)util_float_to_half(value->float32[1]) << 16;
943                 clear_vals[1] = util_float_to_half(value->float32[2]);
944                 clear_vals[1] |= (uint32_t)util_float_to_half(value->float32[3]) << 16;
945                 break;
946         case VK_FORMAT_R16_UNORM:
947                 clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0xffff)) & 0xffff;
948                 clear_vals[1] = 0;
949                 break;
950         case VK_FORMAT_R16G16_UNORM:
951                 clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0xffff)) & 0xffff;
952                 clear_vals[0] |= ((uint16_t)util_iround(CLAMP(value->float32[1], 0.0f, 1.0f) * 0xffff)) << 16;
953                 clear_vals[1] = 0;
954                 break;
955         case VK_FORMAT_R16G16B16A16_UNORM:
956                 clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0xffff)) & 0xffff;
957                 clear_vals[0] |= ((uint16_t)util_iround(CLAMP(value->float32[1], 0.0f, 1.0f) * 0xffff)) << 16;
958                 clear_vals[1] = ((uint16_t)util_iround(CLAMP(value->float32[2], 0.0f, 1.0f) * 0xffff)) & 0xffff;
959                 clear_vals[1] |= ((uint16_t)util_iround(CLAMP(value->float32[3], 0.0f, 1.0f) * 0xffff)) << 16;
960                 break;
961         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
962                 clear_vals[0] = ((uint16_t)util_iround(CLAMP(value->float32[0], 0.0f, 1.0f) * 0x3ff)) & 0x3ff;
963                 clear_vals[0] |= (((uint16_t)util_iround(CLAMP(value->float32[1], 0.0f, 1.0f) * 0x3ff)) & 0x3ff) << 10;
964                 clear_vals[0] |= (((uint16_t)util_iround(CLAMP(value->float32[2], 0.0f, 1.0f) * 0x3ff)) & 0x3ff) << 20;
965                 clear_vals[0] |= (((uint16_t)util_iround(CLAMP(value->float32[3], 0.0f, 1.0f) * 0x3)) & 0x3) << 30;
966                 clear_vals[1] = 0;
967                 return true;
968         case VK_FORMAT_R32G32_SFLOAT:
969                 clear_vals[0] = fui(value->float32[0]);
970                 clear_vals[1] = fui(value->float32[1]);
971                 break;
972         case VK_FORMAT_R32_SFLOAT:
973                 clear_vals[1] = 0;
974                 clear_vals[0] = fui(value->float32[0]);
975                 break;
976         case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
977                 clear_vals[0] = float3_to_r11g11b10f(value->float32);
978                 clear_vals[1] = 0;
979                 break;
980         default:
981                 fprintf(stderr, "failed to fast clear %d\n", format);
982                 return false;
983         }
984         return true;
985 }
986
987 void radv_GetPhysicalDeviceFormatProperties(
988         VkPhysicalDevice                            physicalDevice,
989         VkFormat                                    format,
990         VkFormatProperties*                         pFormatProperties)
991 {
992         RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
993
994         radv_physical_device_get_format_properties(physical_device,
995                                                    format,
996                                                    pFormatProperties);
997 }
998
999 void radv_GetPhysicalDeviceFormatProperties2KHR(
1000         VkPhysicalDevice                            physicalDevice,
1001         VkFormat                                    format,
1002         VkFormatProperties2KHR*                         pFormatProperties)
1003 {
1004         RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1005
1006         radv_physical_device_get_format_properties(physical_device,
1007                                                    format,
1008                                                    &pFormatProperties->formatProperties);
1009 }
1010
1011 static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
1012                                                  const VkPhysicalDeviceImageFormatInfo2KHR *info,
1013                                                  VkImageFormatProperties *pImageFormatProperties)
1014
1015 {
1016         VkFormatProperties format_props;
1017         VkFormatFeatureFlags format_feature_flags;
1018         VkExtent3D maxExtent;
1019         uint32_t maxMipLevels;
1020         uint32_t maxArraySize;
1021         VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1022
1023         radv_physical_device_get_format_properties(physical_device, info->format,
1024                                                    &format_props);
1025         if (info->tiling == VK_IMAGE_TILING_LINEAR) {
1026                 format_feature_flags = format_props.linearTilingFeatures;
1027         } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
1028                 format_feature_flags = format_props.optimalTilingFeatures;
1029         } else {
1030                 unreachable("bad VkImageTiling");
1031         }
1032
1033         if (format_feature_flags == 0)
1034                 goto unsupported;
1035
1036         switch (info->type) {
1037         default:
1038                 unreachable("bad vkimage type\n");
1039         case VK_IMAGE_TYPE_1D:
1040                 maxExtent.width = 16384;
1041                 maxExtent.height = 1;
1042                 maxExtent.depth = 1;
1043                 maxMipLevels = 15; /* log2(maxWidth) + 1 */
1044                 maxArraySize = 2048;
1045                 break;
1046         case VK_IMAGE_TYPE_2D:
1047                 maxExtent.width = 16384;
1048                 maxExtent.height = 16384;
1049                 maxExtent.depth = 1;
1050                 maxMipLevels = 15; /* log2(maxWidth) + 1 */
1051                 maxArraySize = 2048;
1052                 break;
1053         case VK_IMAGE_TYPE_3D:
1054                 maxExtent.width = 2048;
1055                 maxExtent.height = 2048;
1056                 maxExtent.depth = 2048;
1057                 maxMipLevels = 12; /* log2(maxWidth) + 1 */
1058                 maxArraySize = 1;
1059                 break;
1060         }
1061
1062         if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
1063             info->type == VK_IMAGE_TYPE_2D &&
1064             (format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
1065                                      VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
1066             !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
1067             !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
1068                 sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
1069         }
1070
1071         if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
1072                 if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
1073                         goto unsupported;
1074                 }
1075         }
1076
1077         if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
1078                 if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
1079                         goto unsupported;
1080                 }
1081         }
1082
1083         if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1084                 if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
1085                         goto unsupported;
1086                 }
1087         }
1088
1089         if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1090                 if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
1091                         goto unsupported;
1092                 }
1093         }
1094
1095         *pImageFormatProperties = (VkImageFormatProperties) {
1096                 .maxExtent = maxExtent,
1097                 .maxMipLevels = maxMipLevels,
1098                 .maxArrayLayers = maxArraySize,
1099                 .sampleCounts = sampleCounts,
1100
1101                 /* FINISHME: Accurately calculate
1102                  * VkImageFormatProperties::maxResourceSize.
1103                  */
1104                 .maxResourceSize = UINT32_MAX,
1105         };
1106
1107         return VK_SUCCESS;
1108 unsupported:
1109         *pImageFormatProperties = (VkImageFormatProperties) {
1110                 .maxExtent = { 0, 0, 0 },
1111                 .maxMipLevels = 0,
1112                 .maxArrayLayers = 0,
1113                 .sampleCounts = 0,
1114                 .maxResourceSize = 0,
1115         };
1116
1117         return VK_ERROR_FORMAT_NOT_SUPPORTED;
1118 }
1119
1120 VkResult radv_GetPhysicalDeviceImageFormatProperties(
1121         VkPhysicalDevice                            physicalDevice,
1122         VkFormat                                    format,
1123         VkImageType                                 type,
1124         VkImageTiling                               tiling,
1125         VkImageUsageFlags                           usage,
1126         VkImageCreateFlags                          createFlags,
1127         VkImageFormatProperties*                    pImageFormatProperties)
1128 {
1129         RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1130
1131         const VkPhysicalDeviceImageFormatInfo2KHR info = {
1132                 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
1133                 .pNext = NULL,
1134                 .format = format,
1135                 .type = type,
1136                 .tiling = tiling,
1137                 .usage = usage,
1138                 .flags = createFlags,
1139         };
1140
1141         return radv_get_image_format_properties(physical_device, &info,
1142                                                 pImageFormatProperties);
1143 }
1144
1145 static void
1146 get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
1147                                      VkExternalMemoryPropertiesKHX *external_properties)
1148 {
1149         VkExternalMemoryFeatureFlagBitsKHX flags = 0;
1150         VkExternalMemoryHandleTypeFlagsKHX export_flags = 0;
1151         VkExternalMemoryHandleTypeFlagsKHX compat_flags = 0;
1152         switch (pImageFormatInfo->type) {
1153         case VK_IMAGE_TYPE_2D:
1154                 flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHX|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHX|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHX;
1155                 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX;
1156                 break;
1157         default:
1158                 break;
1159         }
1160
1161         *external_properties = (VkExternalMemoryPropertiesKHX) {
1162                 .externalMemoryFeatures = flags,
1163                 .exportFromImportedHandleTypes = export_flags,
1164                 .compatibleHandleTypes = compat_flags,
1165         };
1166 }
1167
1168 VkResult radv_GetPhysicalDeviceImageFormatProperties2KHR(
1169         VkPhysicalDevice                            physicalDevice,
1170         const VkPhysicalDeviceImageFormatInfo2KHR  *base_info,
1171         VkImageFormatProperties2KHR                *base_props)
1172 {
1173         RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1174         const VkPhysicalDeviceExternalImageFormatInfoKHX *external_info = NULL;
1175         VkExternalImageFormatPropertiesKHX *external_props = NULL;
1176         VkResult result;
1177
1178         result = radv_get_image_format_properties(physical_device, base_info,
1179                                                 &base_props->imageFormatProperties);
1180         if (result != VK_SUCCESS)
1181                 return result;
1182
1183            /* Extract input structs */
1184         vk_foreach_struct_const(s, base_info->pNext) {
1185                 switch (s->sType) {
1186                 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHX:
1187                         external_info = (const void *) s;
1188                         break;
1189                 default:
1190                         break;
1191                 }
1192         }
1193
1194         /* Extract output structs */
1195         vk_foreach_struct(s, base_props->pNext) {
1196                 switch (s->sType) {
1197                 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHX:
1198                         external_props = (void *) s;
1199                         break;
1200                 default:
1201                         break;
1202                 }
1203         }
1204
1205         /* From the Vulkan 1.0.42 spec:
1206          *
1207          *    If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
1208          *    behave as if VkPhysicalDeviceExternalImageFormatInfoKHX was not
1209          *    present and VkExternalImageFormatPropertiesKHX will be ignored.
1210          */
1211         if (external_info && external_info->handleType != 0) {
1212                 switch (external_info->handleType) {
1213                 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
1214                         get_external_image_format_properties(base_info, &external_props->externalMemoryProperties);
1215                         break;
1216                 default:
1217                         /* From the Vulkan 1.0.42 spec:
1218                          *
1219                          *    If handleType is not compatible with the [parameters] specified
1220                          *    in VkPhysicalDeviceImageFormatInfo2KHR, then
1221                          *    vkGetPhysicalDeviceImageFormatProperties2KHR returns
1222                          *    VK_ERROR_FORMAT_NOT_SUPPORTED.
1223                          */
1224                         result = vk_errorf(VK_ERROR_FORMAT_NOT_SUPPORTED,
1225                                            "unsupported VkExternalMemoryTypeFlagBitsKHX 0x%x",
1226                                            external_info->handleType);
1227                         goto fail;
1228                 }
1229         }
1230
1231         return VK_SUCCESS;
1232
1233 fail:
1234         if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
1235                 /* From the Vulkan 1.0.42 spec:
1236                  *
1237                  *    If the combination of parameters to
1238                  *    vkGetPhysicalDeviceImageFormatProperties2KHR is not supported by
1239                  *    the implementation for use in vkCreateImage, then all members of
1240                  *    imageFormatProperties will be filled with zero.
1241                  */
1242                 base_props->imageFormatProperties = (VkImageFormatProperties) {0};
1243         }
1244
1245         return result;
1246 }
1247
1248 void radv_GetPhysicalDeviceSparseImageFormatProperties(
1249         VkPhysicalDevice                            physicalDevice,
1250         VkFormat                                    format,
1251         VkImageType                                 type,
1252         uint32_t                                    samples,
1253         VkImageUsageFlags                           usage,
1254         VkImageTiling                               tiling,
1255         uint32_t*                                   pNumProperties,
1256         VkSparseImageFormatProperties*              pProperties)
1257 {
1258         /* Sparse images are not yet supported. */
1259         *pNumProperties = 0;
1260 }
1261
1262 void radv_GetPhysicalDeviceSparseImageFormatProperties2KHR(
1263         VkPhysicalDevice                            physicalDevice,
1264         const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo,
1265         uint32_t                                   *pPropertyCount,
1266         VkSparseImageFormatProperties2KHR*          pProperties)
1267 {
1268         /* Sparse images are not yet supported. */
1269         *pPropertyCount = 0;
1270 }
1271
1272 void radv_GetPhysicalDeviceExternalBufferPropertiesKHX(
1273         VkPhysicalDevice                            physicalDevice,
1274         const VkPhysicalDeviceExternalBufferInfoKHX *pExternalBufferInfo,
1275         VkExternalBufferPropertiesKHX               *pExternalBufferProperties)
1276 {
1277         VkExternalMemoryFeatureFlagBitsKHX flags = 0;
1278         VkExternalMemoryHandleTypeFlagsKHX export_flags = 0;
1279         VkExternalMemoryHandleTypeFlagsKHX compat_flags = 0;
1280         switch(pExternalBufferInfo->handleType) {
1281         case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX:
1282                 flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHX |
1283                         VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHX |
1284                         VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHX;
1285                 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHX;
1286                 break;
1287         default:
1288                 break;
1289         }
1290         pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHX) {
1291                 .externalMemoryFeatures = flags,
1292                 .exportFromImportedHandleTypes = export_flags,
1293                 .compatibleHandleTypes = compat_flags,
1294         };
1295 }