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