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_debug.h"
26 #include "radv_private.h"
27
28 #include "sid.h"
29 #include "vk_format.h"
30
31 #include "vk_util.h"
32
33 #include "ac_drm_fourcc.h"
34 #include "util/format_r11g11b10f.h"
35 #include "util/format_rgb9e5.h"
36 #include "util/format_srgb.h"
37 #include "util/half_float.h"
38 #include "vulkan/util/vk_format.h"
39 #include "vulkan/util/vk_enum_defines.h"
40
41 uint32_t
radv_translate_buffer_dataformat(const struct util_format_description * desc,int first_non_void)42 radv_translate_buffer_dataformat(const struct util_format_description *desc, int first_non_void)
43 {
44 unsigned type;
45 int i;
46
47 assert(util_format_get_num_planes(desc->format) == 1);
48
49 if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
50 return V_008F0C_BUF_DATA_FORMAT_10_11_11;
51
52 if (first_non_void < 0)
53 return V_008F0C_BUF_DATA_FORMAT_INVALID;
54 type = desc->channel[first_non_void].type;
55
56 if (type == UTIL_FORMAT_TYPE_FIXED)
57 return V_008F0C_BUF_DATA_FORMAT_INVALID;
58 if (desc->nr_channels == 4 && desc->channel[0].size == 10 && desc->channel[1].size == 10 &&
59 desc->channel[2].size == 10 && desc->channel[3].size == 2)
60 return V_008F0C_BUF_DATA_FORMAT_2_10_10_10;
61
62 /* See whether the components are of the same size. */
63 for (i = 0; i < desc->nr_channels; i++) {
64 if (desc->channel[first_non_void].size != desc->channel[i].size)
65 return V_008F0C_BUF_DATA_FORMAT_INVALID;
66 }
67
68 switch (desc->channel[first_non_void].size) {
69 case 8:
70 switch (desc->nr_channels) {
71 case 1:
72 return V_008F0C_BUF_DATA_FORMAT_8;
73 case 2:
74 return V_008F0C_BUF_DATA_FORMAT_8_8;
75 case 4:
76 return V_008F0C_BUF_DATA_FORMAT_8_8_8_8;
77 }
78 break;
79 case 16:
80 switch (desc->nr_channels) {
81 case 1:
82 return V_008F0C_BUF_DATA_FORMAT_16;
83 case 2:
84 return V_008F0C_BUF_DATA_FORMAT_16_16;
85 case 4:
86 return V_008F0C_BUF_DATA_FORMAT_16_16_16_16;
87 }
88 break;
89 case 32:
90 /* From the Southern Islands ISA documentation about MTBUF:
91 * 'Memory reads of data in memory that is 32 or 64 bits do not
92 * undergo any format conversion.'
93 */
94 if (type != UTIL_FORMAT_TYPE_FLOAT && !desc->channel[first_non_void].pure_integer)
95 return V_008F0C_BUF_DATA_FORMAT_INVALID;
96
97 switch (desc->nr_channels) {
98 case 1:
99 return V_008F0C_BUF_DATA_FORMAT_32;
100 case 2:
101 return V_008F0C_BUF_DATA_FORMAT_32_32;
102 case 3:
103 return V_008F0C_BUF_DATA_FORMAT_32_32_32;
104 case 4:
105 return V_008F0C_BUF_DATA_FORMAT_32_32_32_32;
106 }
107 break;
108 case 64:
109 if (type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1)
110 return V_008F0C_BUF_DATA_FORMAT_32_32;
111 }
112
113 return V_008F0C_BUF_DATA_FORMAT_INVALID;
114 }
115
116 uint32_t
radv_translate_buffer_numformat(const struct util_format_description * desc,int first_non_void)117 radv_translate_buffer_numformat(const struct util_format_description *desc, int first_non_void)
118 {
119 assert(util_format_get_num_planes(desc->format) == 1);
120
121 if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT)
122 return V_008F0C_BUF_NUM_FORMAT_FLOAT;
123
124 if (first_non_void < 0)
125 return ~0;
126
127 switch (desc->channel[first_non_void].type) {
128 case UTIL_FORMAT_TYPE_SIGNED:
129 if (desc->channel[first_non_void].normalized)
130 return V_008F0C_BUF_NUM_FORMAT_SNORM;
131 else if (desc->channel[first_non_void].pure_integer)
132 return V_008F0C_BUF_NUM_FORMAT_SINT;
133 else
134 return V_008F0C_BUF_NUM_FORMAT_SSCALED;
135 break;
136 case UTIL_FORMAT_TYPE_UNSIGNED:
137 if (desc->channel[first_non_void].normalized)
138 return V_008F0C_BUF_NUM_FORMAT_UNORM;
139 else if (desc->channel[first_non_void].pure_integer)
140 return V_008F0C_BUF_NUM_FORMAT_UINT;
141 else
142 return V_008F0C_BUF_NUM_FORMAT_USCALED;
143 break;
144 case UTIL_FORMAT_TYPE_FLOAT:
145 default:
146 return V_008F0C_BUF_NUM_FORMAT_FLOAT;
147 }
148 }
149
150 void
radv_translate_vertex_format(const struct radv_physical_device * pdevice,VkFormat format,const struct util_format_description * desc,unsigned * dfmt,unsigned * nfmt,bool * post_shuffle,enum radv_vs_input_alpha_adjust * alpha_adjust)151 radv_translate_vertex_format(const struct radv_physical_device *pdevice, VkFormat format,
152 const struct util_format_description *desc, unsigned *dfmt,
153 unsigned *nfmt, bool *post_shuffle,
154 enum radv_vs_input_alpha_adjust *alpha_adjust)
155 {
156 assert(desc->channel[0].type != UTIL_FORMAT_TYPE_VOID);
157 *nfmt = radv_translate_buffer_numformat(desc, 0);
158 *dfmt = radv_translate_buffer_dataformat(desc, 0);
159
160 *alpha_adjust = ALPHA_ADJUST_NONE;
161 if (pdevice->rad_info.chip_class <= GFX8 && pdevice->rad_info.family != CHIP_STONEY) {
162 switch (format) {
163 case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
164 case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
165 *alpha_adjust = ALPHA_ADJUST_SNORM;
166 break;
167 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
168 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
169 *alpha_adjust = ALPHA_ADJUST_SSCALED;
170 break;
171 case VK_FORMAT_A2R10G10B10_SINT_PACK32:
172 case VK_FORMAT_A2B10G10R10_SINT_PACK32:
173 *alpha_adjust = ALPHA_ADJUST_SINT;
174 break;
175 default:
176 break;
177 }
178 }
179
180 switch (format) {
181 case VK_FORMAT_B8G8R8A8_UNORM:
182 case VK_FORMAT_B8G8R8A8_SNORM:
183 case VK_FORMAT_B8G8R8A8_USCALED:
184 case VK_FORMAT_B8G8R8A8_SSCALED:
185 case VK_FORMAT_B8G8R8A8_UINT:
186 case VK_FORMAT_B8G8R8A8_SINT:
187 case VK_FORMAT_B8G8R8A8_SRGB:
188 case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
189 case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
190 case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
191 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
192 case VK_FORMAT_A2R10G10B10_UINT_PACK32:
193 case VK_FORMAT_A2R10G10B10_SINT_PACK32:
194 *post_shuffle = true;
195 break;
196 default:
197 *post_shuffle = false;
198 break;
199 }
200 }
201
202 uint32_t
radv_translate_tex_dataformat(VkFormat format,const struct util_format_description * desc,int first_non_void)203 radv_translate_tex_dataformat(VkFormat format, const struct util_format_description *desc,
204 int first_non_void)
205 {
206 bool uniform = true;
207 int i;
208
209 assert(vk_format_get_plane_count(format) == 1);
210
211 if (!desc)
212 return ~0;
213 /* Colorspace (return non-RGB formats directly). */
214 switch (desc->colorspace) {
215 /* Depth stencil formats */
216 case UTIL_FORMAT_COLORSPACE_ZS:
217 switch (format) {
218 case VK_FORMAT_D16_UNORM:
219 return V_008F14_IMG_DATA_FORMAT_16;
220 case VK_FORMAT_D24_UNORM_S8_UINT:
221 case VK_FORMAT_X8_D24_UNORM_PACK32:
222 return V_008F14_IMG_DATA_FORMAT_8_24;
223 case VK_FORMAT_S8_UINT:
224 return V_008F14_IMG_DATA_FORMAT_8;
225 case VK_FORMAT_D32_SFLOAT:
226 return V_008F14_IMG_DATA_FORMAT_32;
227 case VK_FORMAT_D32_SFLOAT_S8_UINT:
228 return V_008F14_IMG_DATA_FORMAT_X24_8_32;
229 default:
230 goto out_unknown;
231 }
232
233 case UTIL_FORMAT_COLORSPACE_YUV:
234 goto out_unknown; /* TODO */
235
236 default:
237 break;
238 }
239
240 if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
241 switch (format) {
242 /* Don't ask me why this looks inverted. PAL does the same. */
243 case VK_FORMAT_G8B8G8R8_422_UNORM:
244 return V_008F14_IMG_DATA_FORMAT_BG_RG;
245 case VK_FORMAT_B8G8R8G8_422_UNORM:
246 return V_008F14_IMG_DATA_FORMAT_GB_GR;
247 default:
248 goto out_unknown;
249 }
250 }
251
252 if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) {
253 switch (format) {
254 case VK_FORMAT_BC4_UNORM_BLOCK:
255 case VK_FORMAT_BC4_SNORM_BLOCK:
256 return V_008F14_IMG_DATA_FORMAT_BC4;
257 case VK_FORMAT_BC5_UNORM_BLOCK:
258 case VK_FORMAT_BC5_SNORM_BLOCK:
259 return V_008F14_IMG_DATA_FORMAT_BC5;
260 default:
261 break;
262 }
263 }
264
265 if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) {
266 switch (format) {
267 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
268 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
269 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
270 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
271 return V_008F14_IMG_DATA_FORMAT_BC1;
272 case VK_FORMAT_BC2_UNORM_BLOCK:
273 case VK_FORMAT_BC2_SRGB_BLOCK:
274 return V_008F14_IMG_DATA_FORMAT_BC2;
275 case VK_FORMAT_BC3_UNORM_BLOCK:
276 case VK_FORMAT_BC3_SRGB_BLOCK:
277 return V_008F14_IMG_DATA_FORMAT_BC3;
278 default:
279 break;
280 }
281 }
282
283 if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC) {
284 switch (format) {
285 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
286 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
287 return V_008F14_IMG_DATA_FORMAT_BC6;
288 case VK_FORMAT_BC7_UNORM_BLOCK:
289 case VK_FORMAT_BC7_SRGB_BLOCK:
290 return V_008F14_IMG_DATA_FORMAT_BC7;
291 default:
292 break;
293 }
294 }
295
296 if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
297 switch (format) {
298 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
299 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
300 return V_008F14_IMG_DATA_FORMAT_ETC2_RGB;
301 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
302 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
303 return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA1;
304 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
305 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
306 return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA;
307 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
308 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
309 return V_008F14_IMG_DATA_FORMAT_ETC2_R;
310 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
311 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
312 return V_008F14_IMG_DATA_FORMAT_ETC2_RG;
313 default:
314 break;
315 }
316 }
317
318 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
319 return V_008F14_IMG_DATA_FORMAT_5_9_9_9;
320 } else if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
321 return V_008F14_IMG_DATA_FORMAT_10_11_11;
322 }
323
324 /* R8G8Bx_SNORM - TODO CxV8U8 */
325
326 /* hw cannot support mixed formats (except depth/stencil, since only
327 * depth is read).*/
328 if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
329 goto out_unknown;
330
331 /* See whether the components are of the same size. */
332 for (i = 1; i < desc->nr_channels; i++) {
333 uniform = uniform && desc->channel[0].size == desc->channel[i].size;
334 }
335
336 /* Non-uniform formats. */
337 if (!uniform) {
338 switch (desc->nr_channels) {
339 case 3:
340 if (desc->channel[0].size == 5 && desc->channel[1].size == 6 &&
341 desc->channel[2].size == 5) {
342 return V_008F14_IMG_DATA_FORMAT_5_6_5;
343 }
344 goto out_unknown;
345 case 4:
346 if (desc->channel[0].size == 5 && desc->channel[1].size == 5 &&
347 desc->channel[2].size == 5 && desc->channel[3].size == 1) {
348 return V_008F14_IMG_DATA_FORMAT_1_5_5_5;
349 }
350 if (desc->channel[0].size == 1 && desc->channel[1].size == 5 &&
351 desc->channel[2].size == 5 && desc->channel[3].size == 5) {
352 return V_008F14_IMG_DATA_FORMAT_5_5_5_1;
353 }
354 if (desc->channel[0].size == 10 && desc->channel[1].size == 10 &&
355 desc->channel[2].size == 10 && desc->channel[3].size == 2) {
356 /* Closed VK driver does this also no 2/10/10/10 snorm */
357 if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[0].normalized)
358 goto out_unknown;
359 return V_008F14_IMG_DATA_FORMAT_2_10_10_10;
360 }
361 goto out_unknown;
362 }
363 goto out_unknown;
364 }
365
366 if (first_non_void < 0 || first_non_void > 3)
367 goto out_unknown;
368
369 /* uniform formats */
370 switch (desc->channel[first_non_void].size) {
371 case 4:
372 switch (desc->nr_channels) {
373 #if 0 /* Not supported for render targets */
374 case 2:
375 return V_008F14_IMG_DATA_FORMAT_4_4;
376 #endif
377 case 4:
378 return V_008F14_IMG_DATA_FORMAT_4_4_4_4;
379 }
380 break;
381 case 8:
382 switch (desc->nr_channels) {
383 case 1:
384 return V_008F14_IMG_DATA_FORMAT_8;
385 case 2:
386 return V_008F14_IMG_DATA_FORMAT_8_8;
387 case 4:
388 return V_008F14_IMG_DATA_FORMAT_8_8_8_8;
389 }
390 break;
391 case 16:
392 switch (desc->nr_channels) {
393 case 1:
394 return V_008F14_IMG_DATA_FORMAT_16;
395 case 2:
396 return V_008F14_IMG_DATA_FORMAT_16_16;
397 case 4:
398 return V_008F14_IMG_DATA_FORMAT_16_16_16_16;
399 }
400 break;
401 case 32:
402 switch (desc->nr_channels) {
403 case 1:
404 return V_008F14_IMG_DATA_FORMAT_32;
405 case 2:
406 return V_008F14_IMG_DATA_FORMAT_32_32;
407 case 3:
408 return V_008F14_IMG_DATA_FORMAT_32_32_32;
409 case 4:
410 return V_008F14_IMG_DATA_FORMAT_32_32_32_32;
411 }
412 break;
413 case 64:
414 if (desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1)
415 return V_008F14_IMG_DATA_FORMAT_32_32;
416 break;
417 }
418
419 out_unknown:
420 /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */
421 return ~0;
422 }
423
424 uint32_t
radv_translate_tex_numformat(VkFormat format,const struct util_format_description * desc,int first_non_void)425 radv_translate_tex_numformat(VkFormat format, const struct util_format_description *desc,
426 int first_non_void)
427 {
428 assert(vk_format_get_plane_count(format) == 1);
429
430 switch (format) {
431 case VK_FORMAT_D24_UNORM_S8_UINT:
432 return V_008F14_IMG_NUM_FORMAT_UNORM;
433 default:
434 if (first_non_void < 0) {
435 if (vk_format_is_compressed(format)) {
436 switch (format) {
437 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
438 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
439 case VK_FORMAT_BC2_SRGB_BLOCK:
440 case VK_FORMAT_BC3_SRGB_BLOCK:
441 case VK_FORMAT_BC7_SRGB_BLOCK:
442 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
443 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
444 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
445 return V_008F14_IMG_NUM_FORMAT_SRGB;
446 case VK_FORMAT_BC4_SNORM_BLOCK:
447 case VK_FORMAT_BC5_SNORM_BLOCK:
448 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
449 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
450 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
451 return V_008F14_IMG_NUM_FORMAT_SNORM;
452 default:
453 return V_008F14_IMG_NUM_FORMAT_UNORM;
454 }
455 } else if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
456 return V_008F14_IMG_NUM_FORMAT_UNORM;
457 } else {
458 return V_008F14_IMG_NUM_FORMAT_FLOAT;
459 }
460 } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
461 return V_008F14_IMG_NUM_FORMAT_SRGB;
462 } else {
463 switch (desc->channel[first_non_void].type) {
464 case UTIL_FORMAT_TYPE_FLOAT:
465 return V_008F14_IMG_NUM_FORMAT_FLOAT;
466 case UTIL_FORMAT_TYPE_SIGNED:
467 if (desc->channel[first_non_void].normalized)
468 return V_008F14_IMG_NUM_FORMAT_SNORM;
469 else if (desc->channel[first_non_void].pure_integer)
470 return V_008F14_IMG_NUM_FORMAT_SINT;
471 else
472 return V_008F14_IMG_NUM_FORMAT_SSCALED;
473 case UTIL_FORMAT_TYPE_UNSIGNED:
474 if (desc->channel[first_non_void].normalized)
475 return V_008F14_IMG_NUM_FORMAT_UNORM;
476 else if (desc->channel[first_non_void].pure_integer)
477 return V_008F14_IMG_NUM_FORMAT_UINT;
478 else
479 return V_008F14_IMG_NUM_FORMAT_USCALED;
480 default:
481 return V_008F14_IMG_NUM_FORMAT_UNORM;
482 }
483 }
484 }
485 }
486
487 uint32_t
radv_translate_color_numformat(VkFormat format,const struct util_format_description * desc,int first_non_void)488 radv_translate_color_numformat(VkFormat format, const struct util_format_description *desc,
489 int first_non_void)
490 {
491 unsigned ntype;
492
493 assert(vk_format_get_plane_count(format) == 1);
494
495 if (first_non_void == -1 || desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_FLOAT)
496 ntype = V_028C70_NUMBER_FLOAT;
497 else {
498 ntype = V_028C70_NUMBER_UNORM;
499 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
500 ntype = V_028C70_NUMBER_SRGB;
501 else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) {
502 if (desc->channel[first_non_void].pure_integer) {
503 ntype = V_028C70_NUMBER_SINT;
504 } else if (desc->channel[first_non_void].normalized) {
505 ntype = V_028C70_NUMBER_SNORM;
506 } else
507 ntype = ~0u;
508 } else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED) {
509 if (desc->channel[first_non_void].pure_integer) {
510 ntype = V_028C70_NUMBER_UINT;
511 } else if (desc->channel[first_non_void].normalized) {
512 ntype = V_028C70_NUMBER_UNORM;
513 } else
514 ntype = ~0u;
515 }
516 }
517 return ntype;
518 }
519
520 static bool
radv_is_sampler_format_supported(VkFormat format,bool * linear_sampling)521 radv_is_sampler_format_supported(VkFormat format, bool *linear_sampling)
522 {
523 const struct util_format_description *desc = vk_format_description(format);
524 uint32_t num_format;
525 if (!desc || format == VK_FORMAT_UNDEFINED || format == VK_FORMAT_R64_UINT ||
526 format == VK_FORMAT_R64_SINT)
527 return false;
528 num_format =
529 radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format));
530
531 if (num_format == V_008F14_IMG_NUM_FORMAT_USCALED ||
532 num_format == V_008F14_IMG_NUM_FORMAT_SSCALED)
533 return false;
534
535 if (num_format == V_008F14_IMG_NUM_FORMAT_UNORM || num_format == V_008F14_IMG_NUM_FORMAT_SNORM ||
536 num_format == V_008F14_IMG_NUM_FORMAT_FLOAT || num_format == V_008F14_IMG_NUM_FORMAT_SRGB)
537 *linear_sampling = true;
538 else
539 *linear_sampling = false;
540 return radv_translate_tex_dataformat(format, vk_format_description(format),
541 vk_format_get_first_non_void_channel(format)) != ~0U;
542 }
543
544 bool
radv_is_atomic_format_supported(VkFormat format)545 radv_is_atomic_format_supported(VkFormat format)
546 {
547 return format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT ||
548 format == VK_FORMAT_R32_SFLOAT || format == VK_FORMAT_R64_UINT ||
549 format == VK_FORMAT_R64_SINT;
550 }
551
552 bool
radv_is_storage_image_format_supported(struct radv_physical_device * physical_device,VkFormat format)553 radv_is_storage_image_format_supported(struct radv_physical_device *physical_device,
554 VkFormat format)
555 {
556 const struct util_format_description *desc = vk_format_description(format);
557 unsigned data_format, num_format;
558 if (!desc || format == VK_FORMAT_UNDEFINED)
559 return false;
560
561 data_format =
562 radv_translate_tex_dataformat(format, desc, vk_format_get_first_non_void_channel(format));
563 num_format =
564 radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format));
565
566 if (data_format == ~0 || num_format == ~0)
567 return false;
568
569 /* Extracted from the GCN3 ISA document. */
570 switch (num_format) {
571 case V_008F14_IMG_NUM_FORMAT_UNORM:
572 case V_008F14_IMG_NUM_FORMAT_SNORM:
573 case V_008F14_IMG_NUM_FORMAT_UINT:
574 case V_008F14_IMG_NUM_FORMAT_SINT:
575 case V_008F14_IMG_NUM_FORMAT_FLOAT:
576 break;
577 default:
578 return false;
579 }
580
581 switch (data_format) {
582 case V_008F14_IMG_DATA_FORMAT_8:
583 case V_008F14_IMG_DATA_FORMAT_16:
584 case V_008F14_IMG_DATA_FORMAT_8_8:
585 case V_008F14_IMG_DATA_FORMAT_32:
586 case V_008F14_IMG_DATA_FORMAT_16_16:
587 case V_008F14_IMG_DATA_FORMAT_10_11_11:
588 case V_008F14_IMG_DATA_FORMAT_11_11_10:
589 case V_008F14_IMG_DATA_FORMAT_10_10_10_2:
590 case V_008F14_IMG_DATA_FORMAT_2_10_10_10:
591 case V_008F14_IMG_DATA_FORMAT_8_8_8_8:
592 case V_008F14_IMG_DATA_FORMAT_32_32:
593 case V_008F14_IMG_DATA_FORMAT_16_16_16_16:
594 case V_008F14_IMG_DATA_FORMAT_32_32_32_32:
595 case V_008F14_IMG_DATA_FORMAT_5_6_5:
596 case V_008F14_IMG_DATA_FORMAT_1_5_5_5:
597 case V_008F14_IMG_DATA_FORMAT_5_5_5_1:
598 case V_008F14_IMG_DATA_FORMAT_4_4_4_4:
599 /* TODO: FMASK formats. */
600 return true;
601 case V_008F14_IMG_DATA_FORMAT_5_9_9_9:
602 return physical_device->rad_info.chip_class >= GFX10_3;
603 default:
604 return false;
605 }
606 }
607
608 bool
radv_is_buffer_format_supported(VkFormat format,bool * scaled)609 radv_is_buffer_format_supported(VkFormat format, bool *scaled)
610 {
611 const struct util_format_description *desc = vk_format_description(format);
612 unsigned data_format, num_format;
613 if (!desc || format == VK_FORMAT_UNDEFINED)
614 return false;
615
616 data_format =
617 radv_translate_buffer_dataformat(desc, vk_format_get_first_non_void_channel(format));
618 num_format = radv_translate_buffer_numformat(desc, vk_format_get_first_non_void_channel(format));
619
620 if (scaled)
621 *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) ||
622 (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED);
623 return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID && num_format != ~0;
624 }
625
626 bool
radv_is_colorbuffer_format_supported(const struct radv_physical_device * pdevice,VkFormat format,bool * blendable)627 radv_is_colorbuffer_format_supported(const struct radv_physical_device *pdevice, VkFormat format,
628 bool *blendable)
629 {
630 const struct util_format_description *desc = vk_format_description(format);
631 uint32_t color_format = radv_translate_colorformat(format);
632 uint32_t color_swap = radv_translate_colorswap(format, false);
633 uint32_t color_num_format =
634 radv_translate_color_numformat(format, desc, vk_format_get_first_non_void_channel(format));
635
636 if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT ||
637 color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 ||
638 color_format == V_028C70_COLOR_X24_8_32_FLOAT) {
639 *blendable = false;
640 } else
641 *blendable = true;
642
643 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 && pdevice->rad_info.chip_class < GFX10_3)
644 return false;
645
646 return color_format != V_028C70_COLOR_INVALID && color_swap != ~0U && color_num_format != ~0;
647 }
648
649 static bool
radv_is_zs_format_supported(VkFormat format)650 radv_is_zs_format_supported(VkFormat format)
651 {
652 return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT;
653 }
654
655 static bool
radv_is_filter_minmax_format_supported(VkFormat format)656 radv_is_filter_minmax_format_supported(VkFormat format)
657 {
658 /* From the Vulkan spec 1.1.71:
659 *
660 * "The following formats must support the
661 * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR feature with
662 * VK_IMAGE_TILING_OPTIMAL, if they support
663 * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR."
664 */
665 /* TODO: enable more formats. */
666 switch (format) {
667 case VK_FORMAT_R8_UNORM:
668 case VK_FORMAT_R8_SNORM:
669 case VK_FORMAT_R16_UNORM:
670 case VK_FORMAT_R16_SNORM:
671 case VK_FORMAT_R16_SFLOAT:
672 case VK_FORMAT_R32_SFLOAT:
673 case VK_FORMAT_D16_UNORM:
674 case VK_FORMAT_X8_D24_UNORM_PACK32:
675 case VK_FORMAT_D32_SFLOAT:
676 case VK_FORMAT_D16_UNORM_S8_UINT:
677 case VK_FORMAT_D24_UNORM_S8_UINT:
678 case VK_FORMAT_D32_SFLOAT_S8_UINT:
679 return true;
680 default:
681 return false;
682 }
683 }
684
685 bool
radv_device_supports_etc(struct radv_physical_device * physical_device)686 radv_device_supports_etc(struct radv_physical_device *physical_device)
687 {
688 return physical_device->rad_info.family == CHIP_VEGA10 ||
689 physical_device->rad_info.family == CHIP_RAVEN ||
690 physical_device->rad_info.family == CHIP_RAVEN2 ||
691 physical_device->rad_info.family == CHIP_STONEY;
692 }
693
694 static void
radv_physical_device_get_format_properties(struct radv_physical_device * physical_device,VkFormat format,VkFormatProperties3KHR * out_properties)695 radv_physical_device_get_format_properties(struct radv_physical_device *physical_device,
696 VkFormat format, VkFormatProperties3KHR *out_properties)
697 {
698 VkFormatFeatureFlags2KHR linear = 0, tiled = 0, buffer = 0;
699 const struct util_format_description *desc = vk_format_description(format);
700 bool blendable;
701 bool scaled = false;
702 /* TODO: implement some software emulation of SUBSAMPLED formats. */
703 if (!desc || vk_format_to_pipe_format(format) == PIPE_FORMAT_NONE ||
704 desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
705 out_properties->linearTilingFeatures = linear;
706 out_properties->optimalTilingFeatures = tiled;
707 out_properties->bufferFeatures = buffer;
708 return;
709 }
710
711 if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && !radv_device_supports_etc(physical_device)) {
712 out_properties->linearTilingFeatures = linear;
713 out_properties->optimalTilingFeatures = tiled;
714 out_properties->bufferFeatures = buffer;
715 return;
716 }
717
718 if (vk_format_get_plane_count(format) > 1 || desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
719 uint64_t tiling = VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR |
720 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR |
721 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR |
722 VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR |
723 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR;
724
725 /* The subsampled formats have no support for linear filters. */
726 if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
727 tiling |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR;
728 }
729
730 /* Fails for unknown reasons with linear tiling & subsampled formats. */
731 out_properties->linearTilingFeatures =
732 desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED ? 0 : tiling;
733 out_properties->optimalTilingFeatures = tiling;
734 out_properties->bufferFeatures = 0;
735 return;
736 }
737
738 if (radv_is_storage_image_format_supported(physical_device, format)) {
739 tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR |
740 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR |
741 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
742 linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR |
743 VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR |
744 VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR;
745 }
746
747 if (radv_is_buffer_format_supported(format, &scaled)) {
748 if (format != VK_FORMAT_R64_UINT && format != VK_FORMAT_R64_SINT) {
749 buffer |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR;
750 if (!scaled)
751 buffer |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR;
752 }
753 buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR;
754 }
755
756 if (vk_format_is_depth_or_stencil(format)) {
757 if (radv_is_zs_format_supported(format)) {
758 tiled |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR;
759 tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR;
760 tiled |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR | VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR;
761 tiled |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR;
762
763 if (radv_is_filter_minmax_format_supported(format))
764 tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR;
765
766 if (vk_format_has_depth(format)) {
767 tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR |
768 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR;
769 }
770
771 /* Don't support blitting surfaces with depth/stencil. */
772 if (vk_format_has_depth(format) && vk_format_has_stencil(format))
773 tiled &= ~VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR;
774
775 /* Don't support linear depth surfaces */
776 linear = 0;
777 }
778 } else {
779 bool linear_sampling;
780 if (radv_is_sampler_format_supported(format, &linear_sampling)) {
781 linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR | VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR;
782 tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR | VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR;
783
784 if (radv_is_filter_minmax_format_supported(format))
785 tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR;
786
787 if (linear_sampling) {
788 linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR;
789 tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR;
790 }
791
792 /* Don't support blitting for R32G32B32 formats. */
793 if (format == VK_FORMAT_R32G32B32_SFLOAT || format == VK_FORMAT_R32G32B32_UINT ||
794 format == VK_FORMAT_R32G32B32_SINT) {
795 linear &= ~VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR;
796 }
797 }
798 if (radv_is_colorbuffer_format_supported(physical_device, format, &blendable)) {
799 linear |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR | VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR;
800 tiled |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR | VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR;
801 if (blendable) {
802 linear |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR;
803 tiled |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR;
804 }
805 }
806 if (tiled && !scaled) {
807 tiled |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR;
808 }
809
810 /* Tiled formatting does not support NPOT pixel sizes */
811 if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format)))
812 tiled = 0;
813 }
814
815 if (linear && !scaled) {
816 linear |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR;
817 }
818
819 if (radv_is_atomic_format_supported(format)) {
820 buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR;
821 linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR;
822 tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR;
823 }
824
825 switch (format) {
826 case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
827 case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
828 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
829 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
830 case VK_FORMAT_A2R10G10B10_SINT_PACK32:
831 case VK_FORMAT_A2B10G10R10_SINT_PACK32:
832 buffer &=
833 ~(VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR | VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR);
834 linear = 0;
835 tiled = 0;
836 break;
837 default:
838 break;
839 }
840
841 switch (format) {
842 case VK_FORMAT_R32G32_SFLOAT:
843 case VK_FORMAT_R32G32B32_SFLOAT:
844 case VK_FORMAT_R32G32B32A32_SFLOAT:
845 case VK_FORMAT_R16G16_SFLOAT:
846 case VK_FORMAT_R16G16B16_SFLOAT:
847 case VK_FORMAT_R16G16B16A16_SFLOAT:
848 case VK_FORMAT_R16G16_SNORM:
849 case VK_FORMAT_R16G16B16A16_SNORM:
850 case VK_FORMAT_R16G16B16A16_UNORM:
851 buffer |= VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR;
852 break;
853 default:
854 break;
855 }
856 /* addrlib does not support linear compressed textures. */
857 if (vk_format_is_compressed(format))
858 linear = 0;
859
860 /* From the Vulkan spec 1.2.163:
861 *
862 * "VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR must be supported for the
863 * following formats if the attachmentFragmentShadingRate feature is supported:"
864 *
865 * - VK_FORMAT_R8_UINT
866 */
867 if (format == VK_FORMAT_R8_UINT) {
868 tiled |= VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR;
869 }
870
871 /* It's invalid to expose buffer features with depth/stencil formats. */
872 if (vk_format_is_depth_or_stencil(format)) {
873 buffer = 0;
874 }
875
876 out_properties->linearTilingFeatures = linear;
877 out_properties->optimalTilingFeatures = tiled;
878 out_properties->bufferFeatures = buffer;
879 }
880
881 uint32_t
radv_translate_colorformat(VkFormat format)882 radv_translate_colorformat(VkFormat format)
883 {
884 const struct util_format_description *desc = vk_format_description(format);
885
886 #define HAS_SIZE(x, y, z, w) \
887 (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \
888 desc->channel[2].size == (z) && desc->channel[3].size == (w))
889
890 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */
891 return V_028C70_COLOR_10_11_11;
892
893 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
894 return V_028C70_COLOR_5_9_9_9;
895
896 if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
897 return V_028C70_COLOR_INVALID;
898
899 /* hw cannot support mixed formats (except depth/stencil, since
900 * stencil is not written to). */
901 if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
902 return V_028C70_COLOR_INVALID;
903
904 switch (desc->nr_channels) {
905 case 1:
906 switch (desc->channel[0].size) {
907 case 8:
908 return V_028C70_COLOR_8;
909 case 16:
910 return V_028C70_COLOR_16;
911 case 32:
912 return V_028C70_COLOR_32;
913 }
914 break;
915 case 2:
916 if (desc->channel[0].size == desc->channel[1].size) {
917 switch (desc->channel[0].size) {
918 case 8:
919 return V_028C70_COLOR_8_8;
920 case 16:
921 return V_028C70_COLOR_16_16;
922 case 32:
923 return V_028C70_COLOR_32_32;
924 }
925 } else if (HAS_SIZE(8, 24, 0, 0)) {
926 return V_028C70_COLOR_24_8;
927 } else if (HAS_SIZE(24, 8, 0, 0)) {
928 return V_028C70_COLOR_8_24;
929 }
930 break;
931 case 3:
932 if (HAS_SIZE(5, 6, 5, 0)) {
933 return V_028C70_COLOR_5_6_5;
934 } else if (HAS_SIZE(32, 8, 24, 0)) {
935 return V_028C70_COLOR_X24_8_32_FLOAT;
936 }
937 break;
938 case 4:
939 if (desc->channel[0].size == desc->channel[1].size &&
940 desc->channel[0].size == desc->channel[2].size &&
941 desc->channel[0].size == desc->channel[3].size) {
942 switch (desc->channel[0].size) {
943 case 4:
944 return V_028C70_COLOR_4_4_4_4;
945 case 8:
946 return V_028C70_COLOR_8_8_8_8;
947 case 16:
948 return V_028C70_COLOR_16_16_16_16;
949 case 32:
950 return V_028C70_COLOR_32_32_32_32;
951 }
952 } else if (HAS_SIZE(5, 5, 5, 1)) {
953 return V_028C70_COLOR_1_5_5_5;
954 } else if (HAS_SIZE(1, 5, 5, 5)) {
955 return V_028C70_COLOR_5_5_5_1;
956 } else if (HAS_SIZE(10, 10, 10, 2)) {
957 return V_028C70_COLOR_2_10_10_10;
958 }
959 break;
960 }
961 return V_028C70_COLOR_INVALID;
962 }
963
964 uint32_t
radv_colorformat_endian_swap(uint32_t colorformat)965 radv_colorformat_endian_swap(uint32_t colorformat)
966 {
967 if (0 /*SI_BIG_ENDIAN*/) {
968 switch (colorformat) {
969 /* 8-bit buffers. */
970 case V_028C70_COLOR_8:
971 return V_028C70_ENDIAN_NONE;
972
973 /* 16-bit buffers. */
974 case V_028C70_COLOR_5_6_5:
975 case V_028C70_COLOR_1_5_5_5:
976 case V_028C70_COLOR_4_4_4_4:
977 case V_028C70_COLOR_16:
978 case V_028C70_COLOR_8_8:
979 return V_028C70_ENDIAN_8IN16;
980
981 /* 32-bit buffers. */
982 case V_028C70_COLOR_8_8_8_8:
983 case V_028C70_COLOR_2_10_10_10:
984 case V_028C70_COLOR_8_24:
985 case V_028C70_COLOR_24_8:
986 case V_028C70_COLOR_16_16:
987 return V_028C70_ENDIAN_8IN32;
988
989 /* 64-bit buffers. */
990 case V_028C70_COLOR_16_16_16_16:
991 return V_028C70_ENDIAN_8IN16;
992
993 case V_028C70_COLOR_32_32:
994 return V_028C70_ENDIAN_8IN32;
995
996 /* 128-bit buffers. */
997 case V_028C70_COLOR_32_32_32_32:
998 return V_028C70_ENDIAN_8IN32;
999 default:
1000 return V_028C70_ENDIAN_NONE; /* Unsupported. */
1001 }
1002 } else {
1003 return V_028C70_ENDIAN_NONE;
1004 }
1005 }
1006
1007 uint32_t
radv_translate_dbformat(VkFormat format)1008 radv_translate_dbformat(VkFormat format)
1009 {
1010 switch (format) {
1011 case VK_FORMAT_D16_UNORM:
1012 case VK_FORMAT_D16_UNORM_S8_UINT:
1013 return V_028040_Z_16;
1014 case VK_FORMAT_D32_SFLOAT:
1015 case VK_FORMAT_D32_SFLOAT_S8_UINT:
1016 return V_028040_Z_32_FLOAT;
1017 default:
1018 return V_028040_Z_INVALID;
1019 }
1020 }
1021
1022 unsigned
radv_translate_colorswap(VkFormat format,bool do_endian_swap)1023 radv_translate_colorswap(VkFormat format, bool do_endian_swap)
1024 {
1025 const struct util_format_description *desc = vk_format_description(format);
1026
1027 #define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz)
1028
1029 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32)
1030 return V_028C70_SWAP_STD;
1031
1032 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32)
1033 return V_028C70_SWAP_STD;
1034
1035 if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN)
1036 return ~0U;
1037
1038 switch (desc->nr_channels) {
1039 case 1:
1040 if (HAS_SWIZZLE(0, X))
1041 return V_028C70_SWAP_STD; /* X___ */
1042 else if (HAS_SWIZZLE(3, X))
1043 return V_028C70_SWAP_ALT_REV; /* ___X */
1044 break;
1045 case 2:
1046 if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) ||
1047 (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y)))
1048 return V_028C70_SWAP_STD; /* XY__ */
1049 else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) ||
1050 (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) ||
1051 (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X)))
1052 /* YX__ */
1053 return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV);
1054 else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y))
1055 return V_028C70_SWAP_ALT; /* X__Y */
1056 else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X))
1057 return V_028C70_SWAP_ALT_REV; /* Y__X */
1058 break;
1059 case 3:
1060 if (HAS_SWIZZLE(0, X))
1061 return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD);
1062 else if (HAS_SWIZZLE(0, Z))
1063 return V_028C70_SWAP_STD_REV; /* ZYX */
1064 break;
1065 case 4:
1066 /* check the middle channels, the 1st and 4th channel can be NONE */
1067 if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) {
1068 return V_028C70_SWAP_STD; /* XYZW */
1069 } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) {
1070 return V_028C70_SWAP_STD_REV; /* WZYX */
1071 } else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) {
1072 return V_028C70_SWAP_ALT; /* ZYXW */
1073 } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) {
1074 /* YZWX */
1075 if (desc->is_array)
1076 return V_028C70_SWAP_ALT_REV;
1077 else
1078 return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV);
1079 }
1080 break;
1081 }
1082 return ~0U;
1083 }
1084
1085 bool
radv_format_pack_clear_color(VkFormat format,uint32_t clear_vals[2],VkClearColorValue * value)1086 radv_format_pack_clear_color(VkFormat format, uint32_t clear_vals[2], VkClearColorValue *value)
1087 {
1088 const struct util_format_description *desc = vk_format_description(format);
1089
1090 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) {
1091 clear_vals[0] = float3_to_r11g11b10f(value->float32);
1092 clear_vals[1] = 0;
1093 return true;
1094 } else if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) {
1095 clear_vals[0] = float3_to_rgb9e5(value->float32);
1096 clear_vals[1] = 0;
1097 return true;
1098 }
1099
1100 if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) {
1101 fprintf(stderr, "failed to fast clear for non-plain format %d\n", format);
1102 return false;
1103 }
1104
1105 if (!util_is_power_of_two_or_zero(desc->block.bits)) {
1106 fprintf(stderr, "failed to fast clear for NPOT format %d\n", format);
1107 return false;
1108 }
1109
1110 if (desc->block.bits > 64) {
1111 /*
1112 * We have a 128 bits format, check if the first 3 components are the same.
1113 * Every elements has to be 32 bits since we don't support 64-bit formats,
1114 * and we can skip swizzling checks as alpha always comes last for these and
1115 * we do not care about the rest as they have to be the same.
1116 */
1117 if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) {
1118 if (value->float32[0] != value->float32[1] || value->float32[0] != value->float32[2])
1119 return false;
1120 } else {
1121 if (value->uint32[0] != value->uint32[1] || value->uint32[0] != value->uint32[2])
1122 return false;
1123 }
1124 clear_vals[0] = value->uint32[0];
1125 clear_vals[1] = value->uint32[3];
1126 return true;
1127 }
1128 uint64_t clear_val = 0;
1129
1130 for (unsigned c = 0; c < 4; ++c) {
1131 if (desc->swizzle[c] >= 4)
1132 continue;
1133
1134 const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]];
1135 assert(channel->size);
1136
1137 uint64_t v = 0;
1138 if (channel->pure_integer) {
1139 v = value->uint32[c] & ((1ULL << channel->size) - 1);
1140 } else if (channel->normalized) {
1141 if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED && desc->swizzle[c] < 3 &&
1142 desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) {
1143 assert(channel->size == 8);
1144
1145 v = util_format_linear_float_to_srgb_8unorm(value->float32[c]);
1146 } else {
1147 float f = MIN2(value->float32[c], 1.0f);
1148
1149 if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED) {
1150 f = MAX2(f, 0.0f) * ((1ULL << channel->size) - 1);
1151 } else {
1152 f = MAX2(f, -1.0f) * ((1ULL << (channel->size - 1)) - 1);
1153 }
1154
1155 /* The hardware rounds before conversion. */
1156 if (f > 0)
1157 f += 0.5f;
1158 else
1159 f -= 0.5f;
1160
1161 v = (uint64_t)f;
1162 }
1163 } else if (channel->type == UTIL_FORMAT_TYPE_FLOAT) {
1164 if (channel->size == 32) {
1165 memcpy(&v, &value->float32[c], 4);
1166 } else if (channel->size == 16) {
1167 v = _mesa_float_to_float16_rtz(value->float32[c]);
1168 } else {
1169 fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format);
1170 return false;
1171 }
1172 } else {
1173 fprintf(stderr, "failed to fast clear for unhandled component type in format %d\n",
1174 format);
1175 return false;
1176 }
1177 clear_val |= (v & ((1ULL << channel->size) - 1)) << channel->shift;
1178 }
1179
1180 clear_vals[0] = clear_val;
1181 clear_vals[1] = clear_val >> 32;
1182
1183 return true;
1184 }
1185
1186 static const struct ac_modifier_options radv_modifier_options = {
1187 .dcc = true,
1188 .dcc_retile = true,
1189 };
1190
1191 static VkFormatFeatureFlags2KHR
radv_get_modifier_flags(struct radv_physical_device * dev,VkFormat format,uint64_t modifier,const VkFormatProperties3KHR * props)1192 radv_get_modifier_flags(struct radv_physical_device *dev, VkFormat format, uint64_t modifier,
1193 const VkFormatProperties3KHR *props)
1194 {
1195 VkFormatFeatureFlags2KHR features;
1196
1197 if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format))
1198 return 0;
1199
1200 if (modifier == DRM_FORMAT_MOD_LINEAR)
1201 features = props->linearTilingFeatures;
1202 else
1203 features = props->optimalTilingFeatures;
1204
1205 if (ac_modifier_has_dcc(modifier)) {
1206 /* Only disable support for STORAGE_IMAGE on modifiers that
1207 * do not support DCC image stores.
1208 */
1209 if (!ac_modifier_supports_dcc_image_stores(modifier) || radv_is_atomic_format_supported(format))
1210 features &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR;
1211
1212 if (dev->instance->debug_flags & (RADV_DEBUG_NO_DCC | RADV_DEBUG_NO_DISPLAY_DCC))
1213 return 0;
1214 }
1215
1216 return features;
1217 }
1218
1219 static VkFormatFeatureFlags
features2_to_features(VkFormatFeatureFlags2KHR features2)1220 features2_to_features(VkFormatFeatureFlags2KHR features2)
1221 {
1222 return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS;
1223 }
1224
1225 static void
radv_list_drm_format_modifiers(struct radv_physical_device * dev,VkFormat format,const VkFormatProperties3KHR * format_props,VkDrmFormatModifierPropertiesListEXT * mod_list)1226 radv_list_drm_format_modifiers(struct radv_physical_device *dev, VkFormat format,
1227 const VkFormatProperties3KHR *format_props,
1228 VkDrmFormatModifierPropertiesListEXT *mod_list)
1229 {
1230 unsigned mod_count;
1231
1232 if (!mod_list)
1233 return;
1234
1235 if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) {
1236 mod_list->drmFormatModifierCount = 0;
1237 return;
1238 }
1239
1240 ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1241 vk_format_to_pipe_format(format), &mod_count, NULL);
1242 if (!mod_list->pDrmFormatModifierProperties) {
1243 mod_list->drmFormatModifierCount = mod_count;
1244 return;
1245 }
1246
1247 mod_count = MIN2(mod_count, mod_list->drmFormatModifierCount);
1248
1249 uint64_t *mods = malloc(mod_count * sizeof(uint64_t));
1250 if (!mods) {
1251 /* We can't return an error here ... */
1252 mod_list->drmFormatModifierCount = 0;
1253 return;
1254 }
1255 ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1256 vk_format_to_pipe_format(format), &mod_count, mods);
1257
1258 mod_list->drmFormatModifierCount = 0;
1259 for (unsigned i = 0; i < mod_count; ++i) {
1260 VkFormatFeatureFlags2KHR features =
1261 radv_get_modifier_flags(dev, format, mods[i], format_props);
1262 unsigned planes = vk_format_get_plane_count(format);
1263 if (planes == 1) {
1264 if (ac_modifier_has_dcc_retile(mods[i]))
1265 planes = 3;
1266 else if (ac_modifier_has_dcc(mods[i]))
1267 planes = 2;
1268 }
1269
1270 if (!features)
1271 continue;
1272
1273 mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount].drmFormatModifier =
1274 mods[i];
1275 mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
1276 .drmFormatModifierPlaneCount = planes;
1277 mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
1278 .drmFormatModifierTilingFeatures = features2_to_features(features);
1279
1280 ++mod_list->drmFormatModifierCount;
1281 }
1282
1283 free(mods);
1284 }
1285
1286 static void
radv_list_drm_format_modifiers_2(struct radv_physical_device * dev,VkFormat format,const VkFormatProperties3KHR * format_props,VkDrmFormatModifierPropertiesList2EXT * mod_list)1287 radv_list_drm_format_modifiers_2(struct radv_physical_device *dev, VkFormat format,
1288 const VkFormatProperties3KHR *format_props,
1289 VkDrmFormatModifierPropertiesList2EXT *mod_list)
1290 {
1291 unsigned mod_count;
1292
1293 if (!mod_list)
1294 return;
1295
1296 if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) {
1297 mod_list->drmFormatModifierCount = 0;
1298 return;
1299 }
1300
1301 ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1302 vk_format_to_pipe_format(format), &mod_count, NULL);
1303 if (!mod_list->pDrmFormatModifierProperties) {
1304 mod_list->drmFormatModifierCount = mod_count;
1305 return;
1306 }
1307
1308 mod_count = MIN2(mod_count, mod_list->drmFormatModifierCount);
1309
1310 uint64_t *mods = malloc(mod_count * sizeof(uint64_t));
1311 if (!mods) {
1312 /* We can't return an error here ... */
1313 mod_list->drmFormatModifierCount = 0;
1314 return;
1315 }
1316 ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options,
1317 vk_format_to_pipe_format(format), &mod_count, mods);
1318
1319 mod_list->drmFormatModifierCount = 0;
1320 for (unsigned i = 0; i < mod_count; ++i) {
1321 VkFormatFeatureFlags2KHR features =
1322 radv_get_modifier_flags(dev, format, mods[i], format_props);
1323 unsigned planes = vk_format_get_plane_count(format);
1324 if (planes == 1) {
1325 if (ac_modifier_has_dcc_retile(mods[i]))
1326 planes = 3;
1327 else if (ac_modifier_has_dcc(mods[i]))
1328 planes = 2;
1329 }
1330
1331 if (!features)
1332 continue;
1333
1334 mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount].drmFormatModifier =
1335 mods[i];
1336 mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
1337 .drmFormatModifierPlaneCount = planes;
1338 mod_list->pDrmFormatModifierProperties[mod_list->drmFormatModifierCount]
1339 .drmFormatModifierTilingFeatures = features;
1340
1341 ++mod_list->drmFormatModifierCount;
1342 }
1343
1344 free(mods);
1345 }
1346
1347 static VkResult
radv_check_modifier_support(struct radv_physical_device * dev,const VkPhysicalDeviceImageFormatInfo2 * info,VkImageFormatProperties * props,VkFormat format,uint64_t modifier)1348 radv_check_modifier_support(struct radv_physical_device *dev,
1349 const VkPhysicalDeviceImageFormatInfo2 *info,
1350 VkImageFormatProperties *props, VkFormat format, uint64_t modifier)
1351 {
1352 uint32_t max_width, max_height;
1353
1354 if (info->type != VK_IMAGE_TYPE_2D)
1355 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1356
1357 /* We did not add modifiers for sparse textures. */
1358 if (info->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT |
1359 VK_IMAGE_CREATE_SPARSE_ALIASED_BIT))
1360 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1361
1362 /*
1363 * Need to check the modifier is supported in general:
1364 * "If the drmFormatModifier is incompatible with the parameters specified
1365 * in VkPhysicalDeviceImageFormatInfo2 and its pNext chain, then
1366 * vkGetPhysicalDeviceImageFormatProperties2 returns VK_ERROR_FORMAT_NOT_SUPPORTED.
1367 * The implementation must support the query of any drmFormatModifier,
1368 * including unknown and invalid modifier values."
1369 */
1370 VkDrmFormatModifierPropertiesListEXT mod_list = {
1371 .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT,
1372 };
1373
1374 VkFormatProperties2 format_props2 = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
1375 .pNext = &mod_list};
1376
1377 radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format,
1378 &format_props2);
1379
1380 if (!mod_list.drmFormatModifierCount)
1381 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1382
1383 mod_list.pDrmFormatModifierProperties =
1384 calloc(mod_list.drmFormatModifierCount, sizeof(*mod_list.pDrmFormatModifierProperties));
1385 if (!mod_list.pDrmFormatModifierProperties)
1386 return VK_ERROR_OUT_OF_HOST_MEMORY;
1387
1388 radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format,
1389 &format_props2);
1390
1391 bool found = false;
1392 for (uint32_t i = 0; i < mod_list.drmFormatModifierCount && !found; ++i)
1393 if (mod_list.pDrmFormatModifierProperties[i].drmFormatModifier == modifier)
1394 found = true;
1395
1396 free(mod_list.pDrmFormatModifierProperties);
1397
1398 if (!found)
1399 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1400
1401 bool need_dcc_sign_reinterpret = false;
1402 if (ac_modifier_has_dcc(modifier) &&
1403 !radv_are_formats_dcc_compatible(dev, info->pNext, format, info->flags,
1404 &need_dcc_sign_reinterpret) &&
1405 !need_dcc_sign_reinterpret)
1406 return VK_ERROR_FORMAT_NOT_SUPPORTED;
1407
1408 /* We can expand this as needed and implemented but there is not much demand
1409 * for more. */
1410 if (ac_modifier_has_dcc(modifier)) {
1411 props->maxMipLevels = 1;
1412 props->maxArrayLayers = 1;
1413 }
1414
1415 ac_modifier_max_extent(&dev->rad_info, modifier, &max_width, &max_height);
1416 props->maxExtent.width = MIN2(props->maxExtent.width, max_width);
1417 props->maxExtent.height = MIN2(props->maxExtent.width, max_height);
1418
1419 /* We don't support MSAA for modifiers */
1420 props->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
1421 return VK_SUCCESS;
1422 }
1423
1424 void
radv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,VkFormat format,VkFormatProperties2 * pFormatProperties)1425 radv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format,
1426 VkFormatProperties2 *pFormatProperties)
1427 {
1428 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1429 VkFormatProperties3KHR format_props;
1430
1431 radv_physical_device_get_format_properties(physical_device, format, &format_props);
1432
1433 pFormatProperties->formatProperties.linearTilingFeatures =
1434 features2_to_features(format_props.linearTilingFeatures);
1435 pFormatProperties->formatProperties.optimalTilingFeatures =
1436 features2_to_features(format_props.optimalTilingFeatures);
1437 pFormatProperties->formatProperties.bufferFeatures =
1438 features2_to_features(format_props.bufferFeatures);
1439
1440 VkFormatProperties3KHR *format_props_extended =
1441 vk_find_struct(pFormatProperties, FORMAT_PROPERTIES_3_KHR);
1442 if (format_props_extended) {
1443 format_props_extended->linearTilingFeatures = format_props.linearTilingFeatures;
1444 format_props_extended->optimalTilingFeatures = format_props.optimalTilingFeatures;
1445 format_props_extended->bufferFeatures = format_props.bufferFeatures;
1446 }
1447
1448 radv_list_drm_format_modifiers(
1449 physical_device, format, &format_props,
1450 vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT));
1451 radv_list_drm_format_modifiers_2(
1452 physical_device, format, &format_props,
1453 vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT));
1454 }
1455
1456 static VkResult
radv_get_image_format_properties(struct radv_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * info,VkFormat format,VkImageFormatProperties * pImageFormatProperties)1457 radv_get_image_format_properties(struct radv_physical_device *physical_device,
1458 const VkPhysicalDeviceImageFormatInfo2 *info, VkFormat format,
1459 VkImageFormatProperties *pImageFormatProperties)
1460
1461 {
1462 VkFormatProperties3KHR format_props;
1463 VkFormatFeatureFlags2KHR format_feature_flags;
1464 VkExtent3D maxExtent;
1465 uint32_t maxMipLevels;
1466 uint32_t maxArraySize;
1467 VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT;
1468 const struct util_format_description *desc = vk_format_description(format);
1469 enum chip_class chip_class = physical_device->rad_info.chip_class;
1470 VkImageTiling tiling = info->tiling;
1471 const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *mod_info =
1472 vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT);
1473 VkResult result = VK_ERROR_FORMAT_NOT_SUPPORTED;
1474
1475 radv_physical_device_get_format_properties(physical_device, format, &format_props);
1476 if (tiling == VK_IMAGE_TILING_LINEAR) {
1477 format_feature_flags = format_props.linearTilingFeatures;
1478 } else if (tiling == VK_IMAGE_TILING_OPTIMAL) {
1479 format_feature_flags = format_props.optimalTilingFeatures;
1480 } else if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
1481 format_feature_flags = radv_get_modifier_flags(physical_device, format,
1482 mod_info->drmFormatModifier, &format_props);
1483 } else {
1484 unreachable("bad VkImageTiling");
1485 }
1486
1487 if (format_feature_flags == 0)
1488 goto unsupported;
1489
1490 if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(format))
1491 goto unsupported;
1492
1493 switch (info->type) {
1494 default:
1495 unreachable("bad vkimage type\n");
1496 case VK_IMAGE_TYPE_1D:
1497 maxExtent.width = 16384;
1498 maxExtent.height = 1;
1499 maxExtent.depth = 1;
1500 maxMipLevels = 15; /* log2(maxWidth) + 1 */
1501 maxArraySize = chip_class >= GFX10 ? 8192 : 2048;
1502 break;
1503 case VK_IMAGE_TYPE_2D:
1504 maxExtent.width = 16384;
1505 maxExtent.height = 16384;
1506 maxExtent.depth = 1;
1507 maxMipLevels = 15; /* log2(maxWidth) + 1 */
1508 maxArraySize = chip_class >= GFX10 ? 8192 : 2048;
1509 break;
1510 case VK_IMAGE_TYPE_3D:
1511 if (chip_class >= GFX10) {
1512 maxExtent.width = 8192;
1513 maxExtent.height = 8192;
1514 maxExtent.depth = 8192;
1515 } else {
1516 maxExtent.width = 2048;
1517 maxExtent.height = 2048;
1518 maxExtent.depth = 2048;
1519 }
1520 maxMipLevels = util_logbase2(maxExtent.width) + 1;
1521 maxArraySize = 1;
1522 break;
1523 }
1524
1525 if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) {
1526 /* Might be able to support but the entire format support is
1527 * messy, so taking the lazy way out. */
1528 maxArraySize = 1;
1529 }
1530
1531 if (tiling == VK_IMAGE_TILING_OPTIMAL && info->type == VK_IMAGE_TYPE_2D &&
1532 (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR |
1533 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR)) &&
1534 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) &&
1535 !(info->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)) {
1536 sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT;
1537 }
1538
1539 if (tiling == VK_IMAGE_TILING_LINEAR &&
1540 (format == VK_FORMAT_R32G32B32_SFLOAT || format == VK_FORMAT_R32G32B32_SINT ||
1541 format == VK_FORMAT_R32G32B32_UINT)) {
1542 /* R32G32B32 is a weird format and the driver currently only
1543 * supports the barely minimum.
1544 * TODO: Implement more if we really need to.
1545 */
1546 if (info->type == VK_IMAGE_TYPE_3D)
1547 goto unsupported;
1548 maxArraySize = 1;
1549 maxMipLevels = 1;
1550 }
1551
1552 /* We can't create 3d compressed 128bpp images that can be rendered to on GFX9 */
1553 if (physical_device->rad_info.chip_class >= GFX9 && info->type == VK_IMAGE_TYPE_3D &&
1554 vk_format_get_blocksizebits(format) == 128 && vk_format_is_compressed(format) &&
1555 (info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
1556 ((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) ||
1557 (info->usage & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR))) {
1558 goto unsupported;
1559 }
1560
1561 if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
1562 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)) {
1563 goto unsupported;
1564 }
1565 }
1566
1567 if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
1568 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)) {
1569 goto unsupported;
1570 }
1571 }
1572
1573 if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
1574 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR)) {
1575 goto unsupported;
1576 }
1577 }
1578
1579 if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
1580 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR)) {
1581 goto unsupported;
1582 }
1583 }
1584
1585 if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
1586 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR)) {
1587 goto unsupported;
1588 }
1589 }
1590
1591 if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
1592 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR)) {
1593 goto unsupported;
1594 }
1595 }
1596
1597 if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
1598 if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR |
1599 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR))) {
1600 goto unsupported;
1601 }
1602 }
1603
1604 /* Sparse resources with multi-planar formats are unsupported. */
1605 if (info->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
1606 if (vk_format_get_plane_count(format) > 1)
1607 goto unsupported;
1608 }
1609
1610 if (info->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
1611 /* Sparse textures are only supported on GFX8+. */
1612 if (physical_device->rad_info.chip_class < GFX8)
1613 goto unsupported;
1614
1615 if (vk_format_get_plane_count(format) > 1 || info->type != VK_IMAGE_TYPE_2D ||
1616 info->tiling != VK_IMAGE_TILING_OPTIMAL || vk_format_is_depth_or_stencil(format))
1617 goto unsupported;
1618 }
1619
1620 *pImageFormatProperties = (VkImageFormatProperties){
1621 .maxExtent = maxExtent,
1622 .maxMipLevels = maxMipLevels,
1623 .maxArrayLayers = maxArraySize,
1624 .sampleCounts = sampleCounts,
1625
1626 /* FINISHME: Accurately calculate
1627 * VkImageFormatProperties::maxResourceSize.
1628 */
1629 .maxResourceSize = UINT32_MAX,
1630 };
1631
1632 if (mod_info) {
1633 result = radv_check_modifier_support(physical_device, info, pImageFormatProperties, format,
1634 mod_info->drmFormatModifier);
1635 if (result != VK_SUCCESS)
1636 goto unsupported;
1637 }
1638
1639 return VK_SUCCESS;
1640 unsupported:
1641 *pImageFormatProperties = (VkImageFormatProperties){
1642 .maxExtent = {0, 0, 0},
1643 .maxMipLevels = 0,
1644 .maxArrayLayers = 0,
1645 .sampleCounts = 0,
1646 .maxResourceSize = 0,
1647 };
1648
1649 return result;
1650 }
1651
1652 static void
get_external_image_format_properties(struct radv_physical_device * physical_device,const VkPhysicalDeviceImageFormatInfo2 * pImageFormatInfo,VkExternalMemoryHandleTypeFlagBits handleType,VkExternalMemoryProperties * external_properties,VkImageFormatProperties * format_properties)1653 get_external_image_format_properties(struct radv_physical_device *physical_device,
1654 const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo,
1655 VkExternalMemoryHandleTypeFlagBits handleType,
1656 VkExternalMemoryProperties *external_properties,
1657 VkImageFormatProperties *format_properties)
1658 {
1659 VkExternalMemoryFeatureFlagBits flags = 0;
1660 VkExternalMemoryHandleTypeFlags export_flags = 0;
1661 VkExternalMemoryHandleTypeFlags compat_flags = 0;
1662
1663 if (pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1664 return;
1665
1666 switch (handleType) {
1667 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1668 if (pImageFormatInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1669 break;
1670
1671 switch (pImageFormatInfo->type) {
1672 case VK_IMAGE_TYPE_2D:
1673 flags =
1674 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1675
1676 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1677 break;
1678 default:
1679 break;
1680 }
1681 break;
1682 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
1683 switch (pImageFormatInfo->type) {
1684 case VK_IMAGE_TYPE_2D:
1685 flags =
1686 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1687 if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
1688 flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
1689
1690 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
1691 break;
1692 default:
1693 break;
1694 }
1695 break;
1696 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID:
1697 if (!physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer)
1698 break;
1699
1700 if (!radv_android_gralloc_supports_format(pImageFormatInfo->format, pImageFormatInfo->usage))
1701 break;
1702
1703 if (pImageFormatInfo->type != VK_IMAGE_TYPE_2D)
1704 break;
1705
1706 format_properties->maxMipLevels = MIN2(1, format_properties->maxMipLevels);
1707 format_properties->maxArrayLayers = MIN2(1, format_properties->maxArrayLayers);
1708 format_properties->sampleCounts &= VK_SAMPLE_COUNT_1_BIT;
1709
1710 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1711 if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR)
1712 flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT;
1713
1714 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
1715 break;
1716 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
1717 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1718 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
1719 break;
1720 default:
1721 break;
1722 }
1723
1724 *external_properties = (VkExternalMemoryProperties){
1725 .externalMemoryFeatures = flags,
1726 .exportFromImportedHandleTypes = export_flags,
1727 .compatibleHandleTypes = compat_flags,
1728 };
1729 }
1730
1731 VkResult
radv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceImageFormatInfo2 * base_info,VkImageFormatProperties2 * base_props)1732 radv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice,
1733 const VkPhysicalDeviceImageFormatInfo2 *base_info,
1734 VkImageFormatProperties2 *base_props)
1735 {
1736 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice);
1737 const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL;
1738 VkExternalImageFormatProperties *external_props = NULL;
1739 struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL;
1740 VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL;
1741 VkTextureLODGatherFormatPropertiesAMD *texture_lod_props = NULL;
1742 VkResult result;
1743 VkFormat format = radv_select_android_external_format(base_info->pNext, base_info->format);
1744
1745 result = radv_get_image_format_properties(physical_device, base_info, format,
1746 &base_props->imageFormatProperties);
1747 if (result != VK_SUCCESS)
1748 return result;
1749
1750 /* Extract input structs */
1751 vk_foreach_struct_const(s, base_info->pNext)
1752 {
1753 switch (s->sType) {
1754 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO:
1755 external_info = (const void *)s;
1756 break;
1757 default:
1758 break;
1759 }
1760 }
1761
1762 /* Extract output structs */
1763 vk_foreach_struct(s, base_props->pNext)
1764 {
1765 switch (s->sType) {
1766 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES:
1767 external_props = (void *)s;
1768 break;
1769 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES:
1770 ycbcr_props = (void *)s;
1771 break;
1772 case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID:
1773 android_usage = (void *)s;
1774 break;
1775 case VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD:
1776 texture_lod_props = (void *)s;
1777 break;
1778 default:
1779 break;
1780 }
1781 }
1782
1783 bool ahb_supported =
1784 physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer;
1785 if (android_usage && ahb_supported) {
1786 #if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER
1787 android_usage->androidHardwareBufferUsage =
1788 radv_ahb_usage_from_vk_usage(base_info->flags, base_info->usage);
1789 #endif
1790 }
1791
1792 /* From the Vulkan 1.0.97 spec:
1793 *
1794 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will
1795 * behave as if VkPhysicalDeviceExternalImageFormatInfo was not
1796 * present and VkExternalImageFormatProperties will be ignored.
1797 */
1798 if (external_info && external_info->handleType != 0) {
1799 get_external_image_format_properties(physical_device, base_info, external_info->handleType,
1800 &external_props->externalMemoryProperties,
1801 &base_props->imageFormatProperties);
1802 if (!external_props->externalMemoryProperties.externalMemoryFeatures) {
1803 /* From the Vulkan 1.0.97 spec:
1804 *
1805 * If handleType is not compatible with the [parameters] specified
1806 * in VkPhysicalDeviceImageFormatInfo2, then
1807 * vkGetPhysicalDeviceImageFormatProperties2 returns
1808 * VK_ERROR_FORMAT_NOT_SUPPORTED.
1809 */
1810 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED,
1811 "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x",
1812 external_info->handleType);
1813 goto fail;
1814 }
1815 }
1816
1817 if (ycbcr_props) {
1818 ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format);
1819 }
1820
1821 if (texture_lod_props) {
1822 if (physical_device->rad_info.chip_class >= GFX9) {
1823 texture_lod_props->supportsTextureGatherLODBiasAMD = true;
1824 } else {
1825 texture_lod_props->supportsTextureGatherLODBiasAMD = !vk_format_is_int(format);
1826 }
1827 }
1828
1829 return VK_SUCCESS;
1830
1831 fail:
1832 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) {
1833 /* From the Vulkan 1.0.97 spec:
1834 *
1835 * If the combination of parameters to
1836 * vkGetPhysicalDeviceImageFormatProperties2 is not supported by
1837 * the implementation for use in vkCreateImage, then all members of
1838 * imageFormatProperties will be filled with zero.
1839 */
1840 base_props->imageFormatProperties = (VkImageFormatProperties){0};
1841 }
1842
1843 return result;
1844 }
1845
1846 static void
fill_sparse_image_format_properties(struct radv_physical_device * pdev,VkFormat format,VkSparseImageFormatProperties * prop)1847 fill_sparse_image_format_properties(struct radv_physical_device *pdev, VkFormat format,
1848 VkSparseImageFormatProperties *prop)
1849 {
1850 prop->aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
1851 prop->flags = 0;
1852
1853 /* On GFX8 we first subdivide by level and then layer, leading to a single
1854 * miptail. On GFX9+ we first subdivide by layer and then level which results
1855 * in a miptail per layer. */
1856 if (pdev->rad_info.chip_class < GFX9)
1857 prop->flags |= VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT;
1858
1859 /* This assumes the sparse image tile size is always 64 KiB (1 << 16) */
1860 unsigned l2_size = 16 - util_logbase2(vk_format_get_blocksize(format));
1861 unsigned w = (1u << ((l2_size + 1) / 2)) * vk_format_get_blockwidth(format);
1862 unsigned h = (1u << (l2_size / 2)) * vk_format_get_blockheight(format);
1863
1864 prop->imageGranularity = (VkExtent3D){w, h, 1};
1865 }
1866
1867 void
radv_GetPhysicalDeviceSparseImageFormatProperties2(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSparseImageFormatInfo2 * pFormatInfo,uint32_t * pPropertyCount,VkSparseImageFormatProperties2 * pProperties)1868 radv_GetPhysicalDeviceSparseImageFormatProperties2(
1869 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo,
1870 uint32_t *pPropertyCount, VkSparseImageFormatProperties2 *pProperties)
1871 {
1872 RADV_FROM_HANDLE(radv_physical_device, pdev, physicalDevice);
1873 VkResult result;
1874
1875 if (pFormatInfo->samples > VK_SAMPLE_COUNT_1_BIT) {
1876 *pPropertyCount = 0;
1877 return;
1878 }
1879
1880 const VkPhysicalDeviceImageFormatInfo2 fmt_info = {
1881 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
1882 .format = pFormatInfo->format,
1883 .type = pFormatInfo->type,
1884 .tiling = pFormatInfo->tiling,
1885 .usage = pFormatInfo->usage,
1886 .flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT};
1887
1888 VkImageFormatProperties fmt_props;
1889 result = radv_get_image_format_properties(pdev, &fmt_info, pFormatInfo->format, &fmt_props);
1890 if (result != VK_SUCCESS) {
1891 *pPropertyCount = 0;
1892 return;
1893 }
1894
1895 VK_OUTARRAY_MAKE_TYPED(VkSparseImageFormatProperties2, out, pProperties, pPropertyCount);
1896
1897 vk_outarray_append_typed(VkSparseImageFormatProperties2, &out, prop)
1898 {
1899 fill_sparse_image_format_properties(pdev, pFormatInfo->format, &prop->properties);
1900 };
1901 }
1902
1903 void
radv_GetImageSparseMemoryRequirements2(VkDevice _device,const VkImageSparseMemoryRequirementsInfo2 * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1904 radv_GetImageSparseMemoryRequirements2(VkDevice _device,
1905 const VkImageSparseMemoryRequirementsInfo2 *pInfo,
1906 uint32_t *pSparseMemoryRequirementCount,
1907 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1908 {
1909 RADV_FROM_HANDLE(radv_device, device, _device);
1910 RADV_FROM_HANDLE(radv_image, image, pInfo->image);
1911
1912 if (!(image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) {
1913 *pSparseMemoryRequirementCount = 0;
1914 return;
1915 }
1916
1917 VK_OUTARRAY_MAKE_TYPED(VkSparseImageMemoryRequirements2, out, pSparseMemoryRequirements,
1918 pSparseMemoryRequirementCount);
1919
1920 vk_outarray_append_typed(VkSparseImageMemoryRequirements2, &out, req)
1921 {
1922 fill_sparse_image_format_properties(device->physical_device, image->vk_format,
1923 &req->memoryRequirements.formatProperties);
1924 req->memoryRequirements.imageMipTailFirstLod = image->planes[0].surface.first_mip_tail_level;
1925
1926 if (req->memoryRequirements.imageMipTailFirstLod < image->info.levels) {
1927 if (device->physical_device->rad_info.chip_class >= GFX9) {
1928 /* The tail is always a single tile per layer. */
1929 req->memoryRequirements.imageMipTailSize = 65536;
1930 req->memoryRequirements.imageMipTailOffset =
1931 image->planes[0]
1932 .surface.u.gfx9.prt_level_offset[req->memoryRequirements.imageMipTailFirstLod] &
1933 ~65535;
1934 req->memoryRequirements.imageMipTailStride =
1935 image->planes[0].surface.u.gfx9.surf_slice_size;
1936 } else {
1937 req->memoryRequirements.imageMipTailOffset =
1938 (uint64_t)image->planes[0]
1939 .surface.u.legacy.level[req->memoryRequirements.imageMipTailFirstLod]
1940 .offset_256B * 256;
1941 req->memoryRequirements.imageMipTailSize =
1942 image->size - req->memoryRequirements.imageMipTailOffset;
1943 req->memoryRequirements.imageMipTailStride = 0;
1944 }
1945 } else {
1946 req->memoryRequirements.imageMipTailSize = 0;
1947 req->memoryRequirements.imageMipTailOffset = 0;
1948 req->memoryRequirements.imageMipTailStride = 0;
1949 }
1950 };
1951 }
1952
1953 void
radv_GetDeviceImageSparseMemoryRequirementsKHR(VkDevice device,const VkDeviceImageMemoryRequirementsKHR * pInfo,uint32_t * pSparseMemoryRequirementCount,VkSparseImageMemoryRequirements2 * pSparseMemoryRequirements)1954 radv_GetDeviceImageSparseMemoryRequirementsKHR(VkDevice device,
1955 const VkDeviceImageMemoryRequirementsKHR* pInfo,
1956 uint32_t *pSparseMemoryRequirementCount,
1957 VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements)
1958 {
1959 UNUSED VkResult result;
1960 VkImage image;
1961
1962 /* Determining the image size/alignment require to create a surface, which is complicated without
1963 * creating an image.
1964 * TODO: Avoid creating an image.
1965 */
1966 result = radv_CreateImage(device, pInfo->pCreateInfo, NULL, &image);
1967 assert(result == VK_SUCCESS);
1968
1969 VkImageSparseMemoryRequirementsInfo2 info2 = {
1970 .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
1971 .image = image,
1972 };
1973
1974 radv_GetImageSparseMemoryRequirements2(device, &info2, pSparseMemoryRequirementCount,
1975 pSparseMemoryRequirements);
1976
1977 radv_DestroyImage(device, image, NULL);
1978 }
1979
1980 void
radv_GetPhysicalDeviceExternalBufferProperties(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceExternalBufferInfo * pExternalBufferInfo,VkExternalBufferProperties * pExternalBufferProperties)1981 radv_GetPhysicalDeviceExternalBufferProperties(
1982 VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo,
1983 VkExternalBufferProperties *pExternalBufferProperties)
1984 {
1985 VkExternalMemoryFeatureFlagBits flags = 0;
1986 VkExternalMemoryHandleTypeFlags export_flags = 0;
1987 VkExternalMemoryHandleTypeFlags compat_flags = 0;
1988 switch (pExternalBufferInfo->handleType) {
1989 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT:
1990 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT:
1991 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1992 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT |
1993 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
1994 break;
1995 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT:
1996 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT;
1997 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
1998 break;
1999 default:
2000 break;
2001 }
2002 pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties){
2003 .externalMemoryFeatures = flags,
2004 .exportFromImportedHandleTypes = export_flags,
2005 .compatibleHandleTypes = compat_flags,
2006 };
2007 }
2008
2009 /* DCC channel type categories within which formats can be reinterpreted
2010 * while keeping the same DCC encoding. The swizzle must also match. */
2011 enum dcc_channel_type {
2012 dcc_channel_float,
2013 dcc_channel_uint,
2014 dcc_channel_sint,
2015 dcc_channel_incompatible,
2016 };
2017
2018 /* Return the type of DCC encoding. */
2019 static void
radv_get_dcc_channel_type(const struct util_format_description * desc,enum dcc_channel_type * type,unsigned * size)2020 radv_get_dcc_channel_type(const struct util_format_description *desc, enum dcc_channel_type *type,
2021 unsigned *size)
2022 {
2023 int i;
2024
2025 /* Find the first non-void channel. */
2026 for (i = 0; i < desc->nr_channels; i++)
2027 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID)
2028 break;
2029 if (i == desc->nr_channels) {
2030 *type = dcc_channel_incompatible;
2031 return;
2032 }
2033
2034 switch (desc->channel[i].size) {
2035 case 32:
2036 case 16:
2037 case 10:
2038 case 8:
2039 *size = desc->channel[i].size;
2040 if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT)
2041 *type = dcc_channel_float;
2042 else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
2043 *type = dcc_channel_uint;
2044 else
2045 *type = dcc_channel_sint;
2046 break;
2047 default:
2048 *type = dcc_channel_incompatible;
2049 break;
2050 }
2051 }
2052
2053 /* Return if it's allowed to reinterpret one format as another with DCC enabled. */
2054 bool
radv_dcc_formats_compatible(VkFormat format1,VkFormat format2,bool * sign_reinterpret)2055 radv_dcc_formats_compatible(VkFormat format1, VkFormat format2, bool *sign_reinterpret)
2056 {
2057 const struct util_format_description *desc1, *desc2;
2058 enum dcc_channel_type type1, type2;
2059 unsigned size1, size2;
2060 int i;
2061
2062 if (format1 == format2)
2063 return true;
2064
2065 desc1 = vk_format_description(format1);
2066 desc2 = vk_format_description(format2);
2067
2068 if (desc1->nr_channels != desc2->nr_channels)
2069 return false;
2070
2071 /* Swizzles must be the same. */
2072 for (i = 0; i < desc1->nr_channels; i++)
2073 if (desc1->swizzle[i] <= PIPE_SWIZZLE_W && desc2->swizzle[i] <= PIPE_SWIZZLE_W &&
2074 desc1->swizzle[i] != desc2->swizzle[i])
2075 return false;
2076
2077 radv_get_dcc_channel_type(desc1, &type1, &size1);
2078 radv_get_dcc_channel_type(desc2, &type2, &size2);
2079
2080 if (type1 == dcc_channel_incompatible || type2 == dcc_channel_incompatible ||
2081 (type1 == dcc_channel_float) != (type2 == dcc_channel_float) || size1 != size2)
2082 return false;
2083
2084 if (type1 != type2)
2085 *sign_reinterpret = true;
2086
2087 return true;
2088 }
2089