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 41uint32_t 42radv_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 116uint32_t 117radv_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 150void 151radv_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 202uint32_t 203radv_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 417out_unknown: 418 /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */ 419 return ~0; 420} 421 422uint32_t 423radv_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 485uint32_t 486radv_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 518static bool 519radv_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 542bool 543radv_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 550bool 551radv_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 606bool 607radv_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 624bool 625radv_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 647static bool 648radv_is_zs_format_supported(VkFormat format) 649{ 650 return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT; 651} 652 653static bool 654radv_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 683bool 684radv_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 692static void 693radv_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 892uint32_t 893radv_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 975uint32_t 976radv_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 1018uint32_t 1019radv_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 1033unsigned 1034radv_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 1096bool 1097radv_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 1197static const struct ac_modifier_options radv_modifier_options = { 1198 .dcc = true, 1199 .dcc_retile = true, 1200}; 1201 1202static VkFormatFeatureFlags2 1203radv_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 1233static VkFormatFeatureFlags 1234features2_to_features(VkFormatFeatureFlags2 features2) 1235{ 1236 return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; 1237} 1238 1239static void 1240radv_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 1296static void 1297radv_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 1353static VkResult 1354radv_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 1434VKAPI_ATTR void VKAPI_CALL 1435radv_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 1466static VkResult 1467radv_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; 1666unsupported: 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 1678static void 1679get_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 1761VKAPI_ATTR VkResult VKAPI_CALL 1762radv_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 1868fail: 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 1883static void 1884fill_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 1904VKAPI_ATTR void VKAPI_CALL 1905radv_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 1940VKAPI_ATTR void VKAPI_CALL 1941radv_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 1990VKAPI_ATTR void VKAPI_CALL 1991radv_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 2017VKAPI_ATTR void VKAPI_CALL 2018radv_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. */ 2048enum 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. */ 2056static void 2057radv_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. */ 2091bool 2092radv_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