radv: don't expose linear depth surfaces on SI/CIK/VI either.
[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 /* Don't support linear depth surfaces */
649 linear = 0;
650 }
651 } else {
652 bool linear_sampling;
653 if (radv_is_sampler_format_supported(format, &linear_sampling)) {
654 linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
655 VK_FORMAT_FEATURE_BLIT_SRC_BIT;
656 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT |
657 VK_FORMAT_FEATURE_BLIT_SRC_BIT;
658
659 if (radv_is_filter_minmax_format_supported(format))
660 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT;
661
662 if (linear_sampling) {
663 linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
664 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
665 }
666 }
667 if (radv_is_colorbuffer_format_supported(format, &blendable)) {
668 linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
669 tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT;
670 if (blendable) {
671 linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
672 tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT;
673 }
674 }
675 if (tiled && !scaled) {
676 tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR |
677 VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
678 }
679
680 /* Tiled formatting does not support NPOT pixel sizes */
681 if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format)))
682 tiled = 0;
683 }
684
685 if (linear && !scaled) {
686 linear |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR |
687 VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR;
688 }
689
690 if (format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT) {
691 buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT;
692 linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
693 tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT;
694 }
695
696 switch(format) {
697 case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
698 case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
699 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
700 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
701 case VK_FORMAT_A2R10G10B10_SINT_PACK32:
702 case VK_FORMAT_A2B10G10R10_SINT_PACK32:
703 if (physical_device->rad_info.chip_class <= VI &&
704 physical_device->rad_info.family != CHIP_STONEY) {
705 buffer &= ~(VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT |
706 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT);
707 linear = 0;
708 tiled = 0;
709 }
710 break;
711 default:
712 break;
713 }
714
715 out_properties->linearTilingFeatures = linear;
716 out_properties->optimalTilingFeatures = tiled;
717 out_properties->bufferFeatures = buffer;
718 }
719
720 uint32_t radv_translate_colorformat(VkFormat format)
721 {
722 const struct vk_format_description *desc = vk_format_description(format);
723
724 #define HAS_SIZE(x,y,z,w) \
725 (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
726 desc->channel[2].size == (z) && desc->channel[3].size == (w))
727
728 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
729 return V_028C70_COLOR_10_11_11;
730
731 if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
732 return V_028C70_COLOR_INVALID;
733
734 /* hw cannot support mixed formats (except depth/stencil, since
735 * stencil is not written to). */
736 if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS)
737 return V_028C70_COLOR_INVALID;
738
739 switch (desc->nr_channels) {
740 case 1:
741 switch (desc->channel[0].size) {
742 case 8:
743 return V_028C70_COLOR_8;
744 case 16:
745 return V_028C70_COLOR_16;
746 case 32:
747 return V_028C70_COLOR_32;
748 }
749 break;
750 case 2:
751 if (desc->channel[0].size == desc->channel[1].size) {
752 switch (desc->channel[0].size) {
753 case 8:
754 return V_028C70_COLOR_8_8;
755 case 16:
756 return V_028C70_COLOR_16_16;
757 case 32:
758 return V_028C70_COLOR_32_32;
759 }
760 } else if (HAS_SIZE(8,24,0,0)) {
761 return V_028C70_COLOR_24_8;
762 } else if (HAS_SIZE(24,8,0,0)) {
763 return V_028C70_COLOR_8_24;
764 }
765 break;
766 case 3:
767 if (HAS_SIZE(5,6,5,0)) {
768 return V_028C70_COLOR_5_6_5;
769 } else if (HAS_SIZE(32,8,24,0)) {
770 return V_028C70_COLOR_X24_8_32_FLOAT;
771 }
772 break;
773 case 4:
774 if (desc->channel[0].size == desc->channel[1].size &&
775 desc->channel[0].size == desc->channel[2].size &&
776 desc->channel[0].size == desc->channel[3].size) {
777 switch (desc->channel[0].size) {
778 case 4:
779 return V_028C70_COLOR_4_4_4_4;
780 case 8:
781 return V_028C70_COLOR_8_8_8_8;
782 case 16:
783 return V_028C70_COLOR_16_16_16_16;
784 case 32:
785 return V_028C70_COLOR_32_32_32_32;
786 }
787 } else if (HAS_SIZE(5,5,5,1)) {
788 return V_028C70_COLOR_1_5_5_5;
789 } else if (HAS_SIZE(1,5,5,5)) {
790 return V_028C70_COLOR_5_5_5_1;
791 } else if (HAS_SIZE(10,10,10,2)) {
792 return V_028C70_COLOR_2_10_10_10;
793 }
794 break;
795 }
796 return V_028C70_COLOR_INVALID;
797 }
798
799 uint32_t radv_colorformat_endian_swap(uint32_t colorformat)
800 {
801 if (0/*SI_BIG_ENDIAN*/) {
802 switch(colorformat) {
803 /* 8-bit buffers. */
804 case V_028C70_COLOR_8:
805 return V_028C70_ENDIAN_NONE;
806
807 /* 16-bit buffers. */
808 case V_028C70_COLOR_5_6_5:
809 case V_028C70_COLOR_1_5_5_5:
810 case V_028C70_COLOR_4_4_4_4:
811 case V_028C70_COLOR_16:
812 case V_028C70_COLOR_8_8:
813 return V_028C70_ENDIAN_8IN16;
814
815 /* 32-bit buffers. */
816 case V_028C70_COLOR_8_8_8_8:
817 case V_028C70_COLOR_2_10_10_10:
818 case V_028C70_COLOR_8_24:
819 case V_028C70_COLOR_24_8:
820 case V_028C70_COLOR_16_16:
821 return V_028C70_ENDIAN_8IN32;
822
823 /* 64-bit buffers. */
824 case V_028C70_COLOR_16_16_16_16:
825 return V_028C70_ENDIAN_8IN16;
826
827 case V_028C70_COLOR_32_32:
828 return V_028C70_ENDIAN_8IN32;
829
830 /* 128-bit buffers. */
831 case V_028C70_COLOR_32_32_32_32:
832 return V_028C70_ENDIAN_8IN32;
833 default:
834 return V_028C70_ENDIAN_NONE; /* Unsupported. */
835 }
836 } else {
837 return V_028C70_ENDIAN_NONE;
838 }
839 }
840
841 uint32_t radv_translate_dbformat(VkFormat format)
842 {
843 switch (format) {
844 case VK_FORMAT_D16_UNORM:
845 case VK_FORMAT_D16_UNORM_S8_UINT:
846 return V_028040_Z_16;
847 case VK_FORMAT_D32_SFLOAT:
848 case VK_FORMAT_D32_SFLOAT_S8_UINT:
849 return V_028040_Z_32_FLOAT;
850 default:
851 return V_028040_Z_INVALID;
852 }
853 }
854
855 unsigned radv_translate_colorswap(VkFormat format, bool do_endian_swap)
856 {
857 const struct vk_format_description *desc = vk_format_description(format);
858
859 #define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == VK_SWIZZLE_##swz)
860
861 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
862 return V_028C70_SWAP_STD;
863
864 if (desc->layout != VK_FORMAT_LAYOUT_PLAIN)
865 return ~0U;
866
867 switch (desc->nr_channels) {
868 case 1:
869 if (HAS_SWIZZLE(0,X))
870 return V_028C70_SWAP_STD; /* X___ */
871 else if (HAS_SWIZZLE(3,X))
872 return V_028C70_SWAP_ALT_REV; /* ___X */
873 break;
874 case 2:
875 if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) ||
876 (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) ||
877 (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y)))
878 return V_028C70_SWAP_STD; /* XY__ */
879 else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) ||
880 (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) ||
881 (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X)))
882 /* YX__ */
883 return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
884 else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y))
885 return V_028C70_SWAP_ALT; /* X__Y */
886 else if (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(3,X))
887 return V_028C70_SWAP_ALT_REV; /* Y__X */
888 break;
889 case 3:
890 if (HAS_SWIZZLE(0,X))
891 return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
892 else if (HAS_SWIZZLE(0,Z))
893 return V_028C70_SWAP_STD_REV; /* ZYX */
894 break;
895 case 4:
896 /* check the middle channels, the 1st and 4th channel can be NONE */
897 if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z)) {
898 return V_028C70_SWAP_STD; /* XYZW */
899 } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y)) {
900 return V_028C70_SWAP_STD_REV; /* WZYX */
901 } else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X)) {
902 return V_028C70_SWAP_ALT; /* ZYXW */
903 } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,W)) {
904 /* YZWX */
905 if (desc->is_array)
906 return V_028C70_SWAP_ALT_REV;
907 else
908 return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
909 }
910 break;
911 }
912 return ~0U;
913 }
914
915 bool radv_format_pack_clear_color(VkFormat format,
916 uint32_t clear_vals[2],
917 VkClearColorValue *value)
918 {
919 const struct vk_format_description *desc = vk_format_description(format);
920
921 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
922 clear_vals[0] = float3_to_r11g11b10f(value->float32);
923 clear_vals[1] = 0;
924 return true;
925 }
926
927 if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) {
928 fprintf(stderr, "failed to fast clear for non-plain format %d\n", format);
929 return false;
930 }
931
932 if (!util_is_power_of_two_or_zero(desc->block.bits)) {
933 fprintf(stderr, "failed to fast clear for NPOT format %d\n", format);
934 return false;
935 }
936
937 if (desc->block.bits > 64) {
938 /*
939 * We have a 128 bits format, check if the first 3 components are the same.
940 * Every elements has to be 32 bits since we don't support 64-bit formats,
941 * and we can skip swizzling checks as alpha always comes last for these and
942 * we do not care about the rest as they have to be the same.
943 */
944 if (desc->channel[0].type == VK_FORMAT_TYPE_FLOAT) {
945 if (value->float32[0] != value->float32[1] ||
946 value->float32[0] != value->float32[2])
947 return false;
948 } else {
949 if (value->uint32[0] != value->uint32[1] ||
950 value->uint32[0] != value->uint32[2])
951 return false;
952 }
953 clear_vals[0] = value->uint32[0];
954 clear_vals[1] = value->uint32[3];
955 return true;
956 }
957 uint64_t clear_val = 0;
958
959 for (unsigned c = 0; c < 4; ++c) {
960 if (desc->swizzle[c] >= 4)
961 continue;
962
963 const struct vk_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
964 assert(channel->size);
965
966 uint64_t v = 0;
967 if (channel->pure_integer) {
968 v = value->uint32[c] & ((1ULL << channel->size) - 1);
969 } else if (channel->normalized) {
970 if (channel->type == VK_FORMAT_TYPE_UNSIGNED &&
971 desc->swizzle[c] < 3 &&
972 desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
973 assert(channel->size == 8);
974
975 v = util_format_linear_float_to_srgb_8unorm(value->float32[c]);
976 } else if (channel->type == VK_FORMAT_TYPE_UNSIGNED) {
977 v = MAX2(MIN2(value->float32[c], 1.0f), 0.0f) * ((1ULL << channel->size) - 1);
978 } else {
979 v = MAX2(MIN2(value->float32[c], 1.0f), -1.0f) * ((1ULL << (channel->size - 1)) - 1);
980 }
981 } else if (channel->type == VK_FORMAT_TYPE_FLOAT) {
982 if (channel->size == 32) {
983 memcpy(&v, &value->float32[c], 4);
984 } else if(channel->size == 16) {
985 v = util_float_to_half(value->float32[c]);
986 } else {
987 fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format);
988 return false;
989 }
990 } else {
991 fprintf(stderr, "failed to fast clear for unhandled component type in format %d\n", format);
992 return false;
993 }
994 clear_val |= (v & ((1ULL << channel->size) - 1)) << channel->shift;
995 }
996
997 clear_vals[0] = clear_val;
998 clear_vals[1] = clear_val >> 32;
999
1000 return true;
1001 }
1002
1003 void radv_GetPhysicalDeviceFormatProperties(
1004 VkPhysicalDevice physicalDevice,
1005 VkFormat format,
1006 VkFormatProperties* pFormatProperties)
1007 {
1008 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1009
1010 radv_physical_device_get_format_properties(physical_device,
1011 format,
1012 pFormatProperties);
1013 }
1014
1015 void radv_GetPhysicalDeviceFormatProperties2(
1016 VkPhysicalDevice physicalDevice,
1017 VkFormat format,
1018 VkFormatProperties2KHR* pFormatProperties)
1019 {
1020 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1021
1022 radv_physical_device_get_format_properties(physical_device,
1023 format,
1024 &pFormatProperties->formatProperties);
1025 }
1026
1027 static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device,
1028 const VkPhysicalDeviceImageFormatInfo2KHR *info,
1029 VkImageFormatProperties *pImageFormatProperties)
1030
1031 {
1032 VkFormatProperties format_props;
1033 VkFormatFeatureFlags format_feature_flags;
1034 VkExtent3D maxExtent;
1035 uint32_t maxMipLevels;
1036 uint32_t maxArraySize;
1037 VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1038
1039 radv_physical_device_get_format_properties(physical_device, info->format,
1040 &format_props);
1041 if (info->tiling == VK_IMAGE_TILING_LINEAR) {
1042 format_feature_flags = format_props.linearTilingFeatures;
1043 } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) {
1044 format_feature_flags = format_props.optimalTilingFeatures;
1045 } else {
1046 unreachable("bad VkImageTiling");
1047 }
1048
1049 if (format_feature_flags == 0)
1050 goto unsupported;
1051
1052 if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(info->format))
1053 goto unsupported;
1054
1055 switch (info->type) {
1056 default:
1057 unreachable("bad vkimage type\n");
1058 case VK_IMAGE_TYPE_1D:
1059 maxExtent.width = 16384;
1060 maxExtent.height = 1;
1061 maxExtent.depth = 1;
1062 maxMipLevels = 15; /* log2(maxWidth) + 1 */
1063 maxArraySize = 2048;
1064 break;
1065 case VK_IMAGE_TYPE_2D:
1066 maxExtent.width = 16384;
1067 maxExtent.height = 16384;
1068 maxExtent.depth = 1;
1069 maxMipLevels = 15; /* log2(maxWidth) + 1 */
1070 maxArraySize = 2048;
1071 break;
1072 case VK_IMAGE_TYPE_3D:
1073 maxExtent.width = 2048;
1074 maxExtent.height = 2048;
1075 maxExtent.depth = 2048;
1076 maxMipLevels = 12; /* log2(maxWidth) + 1 */
1077 maxArraySize = 1;
1078 break;
1079 }
1080
1081 if (info->tiling == VK_IMAGE_TILING_OPTIMAL &&
1082 info->type == VK_IMAGE_TYPE_2D &&
1083 (format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
1084 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
1085 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
1086 !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) {
1087 sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
1088 }
1089
1090 if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
1091 if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) {
1092 goto unsupported;
1093 }
1094 }
1095
1096 if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
1097 if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) {
1098 goto unsupported;
1099 }
1100 }
1101
1102 if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1103 if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) {
1104 goto unsupported;
1105 }
1106 }
1107
1108 if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1109 if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
1110 goto unsupported;
1111 }
1112 }
1113
1114 if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1115 if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) {
1116 goto unsupported;
1117 }
1118 }
1119
1120 if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1121 if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) {
1122 goto unsupported;
1123 }
1124 }
1125
1126 if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1127 if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
1128 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) {
1129 goto unsupported;
1130 }
1131 }
1132
1133 *pImageFormatProperties = (VkImageFormatProperties) {
1134 .maxExtent = maxExtent,
1135 .maxMipLevels = maxMipLevels,
1136 .maxArrayLayers = maxArraySize,
1137 .sampleCounts = sampleCounts,
1138
1139 /* FINISHME: Accurately calculate
1140 * VkImageFormatProperties::maxResourceSize.
1141 */
1142 .maxResourceSize = UINT32_MAX,
1143 };
1144
1145 return VK_SUCCESS;
1146 unsupported:
1147 *pImageFormatProperties = (VkImageFormatProperties) {
1148 .maxExtent = { 0, 0, 0 },
1149 .maxMipLevels = 0,
1150 .maxArrayLayers = 0,
1151 .sampleCounts = 0,
1152 .maxResourceSize = 0,
1153 };
1154
1155 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1156 }
1157
1158 VkResult radv_GetPhysicalDeviceImageFormatProperties(
1159 VkPhysicalDevice physicalDevice,
1160 VkFormat format,
1161 VkImageType type,
1162 VkImageTiling tiling,
1163 VkImageUsageFlags usage,
1164 VkImageCreateFlags createFlags,
1165 VkImageFormatProperties* pImageFormatProperties)
1166 {
1167 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1168
1169 const VkPhysicalDeviceImageFormatInfo2KHR info = {
1170 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR,
1171 .pNext = NULL,
1172 .format = format,
1173 .type = type,
1174 .tiling = tiling,
1175 .usage = usage,
1176 .flags = createFlags,
1177 };
1178
1179 return radv_get_image_format_properties(physical_device, &info,
1180 pImageFormatProperties);
1181 }
1182
1183 static void
1184 get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo,
1185 VkExternalMemoryHandleTypeFlagBitsKHR handleType,
1186 VkExternalMemoryPropertiesKHR *external_properties)
1187 {
1188 VkExternalMemoryFeatureFlagBitsKHR flags = 0;
1189 VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
1190 VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
1191 switch (handleType) {
1192 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
1193 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1194 switch (pImageFormatInfo->type) {
1195 case VK_IMAGE_TYPE_2D:
1196 flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
1197 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
1198 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1199 break;
1200 default:
1201 break;
1202 }
1203 break;
1204 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
1205 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
1206 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
1207 break;
1208 default:
1209 break;
1210 }
1211
1212 *external_properties = (VkExternalMemoryPropertiesKHR) {
1213 .externalMemoryFeatures = flags,
1214 .exportFromImportedHandleTypes = export_flags,
1215 .compatibleHandleTypes = compat_flags,
1216 };
1217 }
1218
1219 VkResult radv_GetPhysicalDeviceImageFormatProperties2(
1220 VkPhysicalDevice physicalDevice,
1221 const VkPhysicalDeviceImageFormatInfo2KHR *base_info,
1222 VkImageFormatProperties2KHR *base_props)
1223 {
1224 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1225 const VkPhysicalDeviceExternalImageFormatInfoKHR *external_info = NULL;
1226 VkExternalImageFormatPropertiesKHR *external_props = NULL;
1227 VkResult result;
1228
1229 result = radv_get_image_format_properties(physical_device, base_info,
1230 &base_props->imageFormatProperties);
1231 if (result != VK_SUCCESS)
1232 return result;
1233
1234 /* Extract input structs */
1235 vk_foreach_struct_const(s, base_info->pNext) {
1236 switch (s->sType) {
1237 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR:
1238 external_info = (const void *) s;
1239 break;
1240 default:
1241 break;
1242 }
1243 }
1244
1245 /* Extract output structs */
1246 vk_foreach_struct(s, base_props->pNext) {
1247 switch (s->sType) {
1248 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR:
1249 external_props = (void *) s;
1250 break;
1251 default:
1252 break;
1253 }
1254 }
1255
1256 /* From the Vulkan 1.0.42 spec:
1257 *
1258 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will
1259 * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not
1260 * present and VkExternalImageFormatPropertiesKHR will be ignored.
1261 */
1262 if (external_info && external_info->handleType != 0) {
1263 switch (external_info->handleType) {
1264 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
1265 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1266 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
1267 get_external_image_format_properties(base_info, external_info->handleType,
1268 &external_props->externalMemoryProperties);
1269 break;
1270 default:
1271 /* From the Vulkan 1.0.42 spec:
1272 *
1273 * If handleType is not compatible with the [parameters] specified
1274 * in VkPhysicalDeviceImageFormatInfo2KHR, then
1275 * vkGetPhysicalDeviceImageFormatProperties2KHR returns
1276 * VK_ERROR_FORMAT_NOT_SUPPORTED.
1277 */
1278 result = vk_errorf(physical_device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED,
1279 "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
1280 external_info->handleType);
1281 goto fail;
1282 }
1283 }
1284
1285 return VK_SUCCESS;
1286
1287 fail:
1288 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
1289 /* From the Vulkan 1.0.42 spec:
1290 *
1291 * If the combination of parameters to
1292 * vkGetPhysicalDeviceImageFormatProperties2KHR is not supported by
1293 * the implementation for use in vkCreateImage, then all members of
1294 * imageFormatProperties will be filled with zero.
1295 */
1296 base_props->imageFormatProperties = (VkImageFormatProperties) {0};
1297 }
1298
1299 return result;
1300 }
1301
1302 void radv_GetPhysicalDeviceSparseImageFormatProperties(
1303 VkPhysicalDevice physicalDevice,
1304 VkFormat format,
1305 VkImageType type,
1306 uint32_t samples,
1307 VkImageUsageFlags usage,
1308 VkImageTiling tiling,
1309 uint32_t* pNumProperties,
1310 VkSparseImageFormatProperties* pProperties)
1311 {
1312 /* Sparse images are not yet supported. */
1313 *pNumProperties = 0;
1314 }
1315
1316 void radv_GetPhysicalDeviceSparseImageFormatProperties2(
1317 VkPhysicalDevice physicalDevice,
1318 const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo,
1319 uint32_t *pPropertyCount,
1320 VkSparseImageFormatProperties2KHR* pProperties)
1321 {
1322 /* Sparse images are not yet supported. */
1323 *pPropertyCount = 0;
1324 }
1325
1326 void radv_GetPhysicalDeviceExternalBufferProperties(
1327 VkPhysicalDevice physicalDevice,
1328 const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo,
1329 VkExternalBufferPropertiesKHR *pExternalBufferProperties)
1330 {
1331 VkExternalMemoryFeatureFlagBitsKHR flags = 0;
1332 VkExternalMemoryHandleTypeFlagsKHR export_flags = 0;
1333 VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0;
1334 switch(pExternalBufferInfo->handleType) {
1335 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR:
1336 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1337 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR |
1338 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
1339 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR |
1340 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1341 break;
1342 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
1343 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR;
1344 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
1345 break;
1346 default:
1347 break;
1348 }
1349 pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHR) {
1350 .externalMemoryFeatures = flags,
1351 .exportFromImportedHandleTypes = export_flags,
1352 .compatibleHandleTypes = compat_flags,
1353 };
1354 }
1355
1356 /* DCC channel type categories within which formats can be reinterpreted
1357 * while keeping the same DCC encoding. The swizzle must also match. */
1358 enum dcc_channel_type {
1359 dcc_channel_float32,
1360 dcc_channel_uint32,
1361 dcc_channel_sint32,
1362 dcc_channel_float16,
1363 dcc_channel_uint16,
1364 dcc_channel_sint16,
1365 dcc_channel_uint_10_10_10_2,
1366 dcc_channel_uint8,
1367 dcc_channel_sint8,
1368 dcc_channel_incompatible,
1369 };
1370
1371 /* Return the type of DCC encoding. */
1372 static enum dcc_channel_type
1373 radv_get_dcc_channel_type(const struct vk_format_description *desc)
1374 {
1375 int i;
1376
1377 /* Find the first non-void channel. */
1378 for (i = 0; i < desc->nr_channels; i++)
1379 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
1380 break;
1381 if (i == desc->nr_channels)
1382 return dcc_channel_incompatible;
1383
1384 switch (desc->channel[i].size) {
1385 case 32:
1386 if (desc->channel[i].type == VK_FORMAT_TYPE_FLOAT)
1387 return dcc_channel_float32;
1388 if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED)
1389 return dcc_channel_uint32;
1390 return dcc_channel_sint32;
1391 case 16:
1392 if (desc->channel[i].type == VK_FORMAT_TYPE_FLOAT)
1393 return dcc_channel_float16;
1394 if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED)
1395 return dcc_channel_uint16;
1396 return dcc_channel_sint16;
1397 case 10:
1398 return dcc_channel_uint_10_10_10_2;
1399 case 8:
1400 if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED)
1401 return dcc_channel_uint8;
1402 return dcc_channel_sint8;
1403 default:
1404 return dcc_channel_incompatible;
1405 }
1406 }
1407
1408 /* Return if it's allowed to reinterpret one format as another with DCC enabled. */
1409 bool radv_dcc_formats_compatible(VkFormat format1,
1410 VkFormat format2)
1411 {
1412 const struct vk_format_description *desc1, *desc2;
1413 enum dcc_channel_type type1, type2;
1414 int i;
1415
1416 if (format1 == format2)
1417 return true;
1418
1419 desc1 = vk_format_description(format1);
1420 desc2 = vk_format_description(format2);
1421
1422 if (desc1->nr_channels != desc2->nr_channels)
1423 return false;
1424
1425 /* Swizzles must be the same. */
1426 for (i = 0; i < desc1->nr_channels; i++)
1427 if (desc1->swizzle[i] <= VK_SWIZZLE_W &&
1428 desc2->swizzle[i] <= VK_SWIZZLE_W &&
1429 desc1->swizzle[i] != desc2->swizzle[i])
1430 return false;
1431
1432 type1 = radv_get_dcc_channel_type(desc1);
1433 type2 = radv_get_dcc_channel_type(desc2);
1434
1435 return type1 != dcc_channel_incompatible &&
1436 type2 != dcc_channel_incompatible &&
1437 type1 == type2;
1438 }
1439