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