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