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