radv_formats.c revision 01e04c3f
1/* 2 * Copyright © 2016 Red Hat. 3 * Copyright © 2016 Bas Nieuwenhuizen 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 */ 24 25#include "radv_private.h" 26 27#include "vk_format.h" 28#include "sid.h" 29 30#include "vk_util.h" 31 32#include "util/u_half.h" 33#include "util/format_srgb.h" 34#include "util/format_r11g11b10f.h" 35 36uint32_t radv_translate_buffer_dataformat(const struct vk_format_description *desc, 37 int first_non_void) 38{ 39 unsigned type; 40 int i; 41 42 if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) 43 return V_008F0C_BUF_DATA_FORMAT_10_11_11; 44 45 if (first_non_void < 0) 46 return V_008F0C_BUF_DATA_FORMAT_INVALID; 47 type = desc->channel[first_non_void].type; 48 49 if (type == VK_FORMAT_TYPE_FIXED) 50 return V_008F0C_BUF_DATA_FORMAT_INVALID; 51 if (desc->nr_channels == 4 && 52 desc->channel[0].size == 10 && 53 desc->channel[1].size == 10 && 54 desc->channel[2].size == 10 && 55 desc->channel[3].size == 2) 56 return V_008F0C_BUF_DATA_FORMAT_2_10_10_10; 57 58 /* See whether the components are of the same size. */ 59 for (i = 0; i < desc->nr_channels; i++) { 60 if (desc->channel[first_non_void].size != desc->channel[i].size) 61 return V_008F0C_BUF_DATA_FORMAT_INVALID; 62 } 63 64 switch (desc->channel[first_non_void].size) { 65 case 8: 66 switch (desc->nr_channels) { 67 case 1: 68 return V_008F0C_BUF_DATA_FORMAT_8; 69 case 2: 70 return V_008F0C_BUF_DATA_FORMAT_8_8; 71 case 4: 72 return V_008F0C_BUF_DATA_FORMAT_8_8_8_8; 73 } 74 break; 75 case 16: 76 switch (desc->nr_channels) { 77 case 1: 78 return V_008F0C_BUF_DATA_FORMAT_16; 79 case 2: 80 return V_008F0C_BUF_DATA_FORMAT_16_16; 81 case 4: 82 return V_008F0C_BUF_DATA_FORMAT_16_16_16_16; 83 } 84 break; 85 case 32: 86 /* From the Southern Islands ISA documentation about MTBUF: 87 * 'Memory reads of data in memory that is 32 or 64 bits do not 88 * undergo any format conversion.' 89 */ 90 if (type != VK_FORMAT_TYPE_FLOAT && 91 !desc->channel[first_non_void].pure_integer) 92 return V_008F0C_BUF_DATA_FORMAT_INVALID; 93 94 switch (desc->nr_channels) { 95 case 1: 96 return V_008F0C_BUF_DATA_FORMAT_32; 97 case 2: 98 return V_008F0C_BUF_DATA_FORMAT_32_32; 99 case 3: 100 return V_008F0C_BUF_DATA_FORMAT_32_32_32; 101 case 4: 102 return V_008F0C_BUF_DATA_FORMAT_32_32_32_32; 103 } 104 break; 105 } 106 107 return V_008F0C_BUF_DATA_FORMAT_INVALID; 108} 109 110uint32_t radv_translate_buffer_numformat(const struct vk_format_description *desc, 111 int first_non_void) 112{ 113 if (desc->format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) 114 return V_008F0C_BUF_NUM_FORMAT_FLOAT; 115 116 if (first_non_void < 0) 117 return ~0; 118 119 switch (desc->channel[first_non_void].type) { 120 case VK_FORMAT_TYPE_SIGNED: 121 if (desc->channel[first_non_void].normalized) 122 return V_008F0C_BUF_NUM_FORMAT_SNORM; 123 else if (desc->channel[first_non_void].pure_integer) 124 return V_008F0C_BUF_NUM_FORMAT_SINT; 125 else 126 return V_008F0C_BUF_NUM_FORMAT_SSCALED; 127 break; 128 case VK_FORMAT_TYPE_UNSIGNED: 129 if (desc->channel[first_non_void].normalized) 130 return V_008F0C_BUF_NUM_FORMAT_UNORM; 131 else if (desc->channel[first_non_void].pure_integer) 132 return V_008F0C_BUF_NUM_FORMAT_UINT; 133 else 134 return V_008F0C_BUF_NUM_FORMAT_USCALED; 135 break; 136 case VK_FORMAT_TYPE_FLOAT: 137 default: 138 return V_008F0C_BUF_NUM_FORMAT_FLOAT; 139 } 140} 141 142uint32_t radv_translate_tex_dataformat(VkFormat format, 143 const struct vk_format_description *desc, 144 int first_non_void) 145{ 146 bool uniform = true; 147 int i; 148 149 if (!desc) 150 return ~0; 151 /* Colorspace (return non-RGB formats directly). */ 152 switch (desc->colorspace) { 153 /* Depth stencil formats */ 154 case VK_FORMAT_COLORSPACE_ZS: 155 switch (format) { 156 case VK_FORMAT_D16_UNORM: 157 return V_008F14_IMG_DATA_FORMAT_16; 158 case VK_FORMAT_D24_UNORM_S8_UINT: 159 case VK_FORMAT_X8_D24_UNORM_PACK32: 160 return V_008F14_IMG_DATA_FORMAT_8_24; 161 case VK_FORMAT_S8_UINT: 162 return V_008F14_IMG_DATA_FORMAT_8; 163 case VK_FORMAT_D32_SFLOAT: 164 return V_008F14_IMG_DATA_FORMAT_32; 165 case VK_FORMAT_D32_SFLOAT_S8_UINT: 166 return V_008F14_IMG_DATA_FORMAT_X24_8_32; 167 default: 168 goto out_unknown; 169 } 170 171 case VK_FORMAT_COLORSPACE_YUV: 172 goto out_unknown; /* TODO */ 173 174 case VK_FORMAT_COLORSPACE_SRGB: 175 if (desc->nr_channels != 4 && desc->nr_channels != 1) 176 goto out_unknown; 177 break; 178 179 default: 180 break; 181 } 182 183 if (desc->layout == VK_FORMAT_LAYOUT_RGTC) { 184 switch(format) { 185 case VK_FORMAT_BC4_UNORM_BLOCK: 186 case VK_FORMAT_BC4_SNORM_BLOCK: 187 return V_008F14_IMG_DATA_FORMAT_BC4; 188 case VK_FORMAT_BC5_UNORM_BLOCK: 189 case VK_FORMAT_BC5_SNORM_BLOCK: 190 return V_008F14_IMG_DATA_FORMAT_BC5; 191 default: 192 break; 193 } 194 } 195 196 if (desc->layout == VK_FORMAT_LAYOUT_S3TC) { 197 switch(format) { 198 case VK_FORMAT_BC1_RGB_UNORM_BLOCK: 199 case VK_FORMAT_BC1_RGB_SRGB_BLOCK: 200 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: 201 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 202 return V_008F14_IMG_DATA_FORMAT_BC1; 203 case VK_FORMAT_BC2_UNORM_BLOCK: 204 case VK_FORMAT_BC2_SRGB_BLOCK: 205 return V_008F14_IMG_DATA_FORMAT_BC2; 206 case VK_FORMAT_BC3_UNORM_BLOCK: 207 case VK_FORMAT_BC3_SRGB_BLOCK: 208 return V_008F14_IMG_DATA_FORMAT_BC3; 209 default: 210 break; 211 } 212 } 213 214 if (desc->layout == VK_FORMAT_LAYOUT_BPTC) { 215 switch(format) { 216 case VK_FORMAT_BC6H_UFLOAT_BLOCK: 217 case VK_FORMAT_BC6H_SFLOAT_BLOCK: 218 return V_008F14_IMG_DATA_FORMAT_BC6; 219 case VK_FORMAT_BC7_UNORM_BLOCK: 220 case VK_FORMAT_BC7_SRGB_BLOCK: 221 return V_008F14_IMG_DATA_FORMAT_BC7; 222 default: 223 break; 224 } 225 } 226 227 if (desc->layout == VK_FORMAT_LAYOUT_ETC) { 228 switch (format) { 229 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: 230 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 231 return V_008F14_IMG_DATA_FORMAT_ETC2_RGB; 232 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: 233 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 234 return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA1; 235 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: 236 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 237 return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA; 238 case VK_FORMAT_EAC_R11_UNORM_BLOCK: 239 case VK_FORMAT_EAC_R11_SNORM_BLOCK: 240 return V_008F14_IMG_DATA_FORMAT_ETC2_R; 241 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 242 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 243 return V_008F14_IMG_DATA_FORMAT_ETC2_RG; 244 default: 245 break; 246 } 247 } 248 249 if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 250 return V_008F14_IMG_DATA_FORMAT_5_9_9_9; 251 } else if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { 252 return V_008F14_IMG_DATA_FORMAT_10_11_11; 253 } 254 255 /* R8G8Bx_SNORM - TODO CxV8U8 */ 256 257 /* hw cannot support mixed formats (except depth/stencil, since only 258 * depth is read).*/ 259 if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS) 260 goto out_unknown; 261 262 /* See whether the components are of the same size. */ 263 for (i = 1; i < desc->nr_channels; i++) { 264 uniform = uniform && desc->channel[0].size == desc->channel[i].size; 265 } 266 267 /* Non-uniform formats. */ 268 if (!uniform) { 269 switch(desc->nr_channels) { 270 case 3: 271 if (desc->channel[0].size == 5 && 272 desc->channel[1].size == 6 && 273 desc->channel[2].size == 5) { 274 return V_008F14_IMG_DATA_FORMAT_5_6_5; 275 } 276 goto out_unknown; 277 case 4: 278 if (desc->channel[0].size == 5 && 279 desc->channel[1].size == 5 && 280 desc->channel[2].size == 5 && 281 desc->channel[3].size == 1) { 282 return V_008F14_IMG_DATA_FORMAT_1_5_5_5; 283 } 284 if (desc->channel[0].size == 1 && 285 desc->channel[1].size == 5 && 286 desc->channel[2].size == 5 && 287 desc->channel[3].size == 5) { 288 return V_008F14_IMG_DATA_FORMAT_5_5_5_1; 289 } 290 if (desc->channel[0].size == 10 && 291 desc->channel[1].size == 10 && 292 desc->channel[2].size == 10 && 293 desc->channel[3].size == 2) { 294 /* Closed VK driver does this also no 2/10/10/10 snorm */ 295 if (desc->channel[0].type == VK_FORMAT_TYPE_SIGNED && 296 desc->channel[0].normalized) 297 goto out_unknown; 298 return V_008F14_IMG_DATA_FORMAT_2_10_10_10; 299 } 300 goto out_unknown; 301 } 302 goto out_unknown; 303 } 304 305 if (first_non_void < 0 || first_non_void > 3) 306 goto out_unknown; 307 308 /* uniform formats */ 309 switch (desc->channel[first_non_void].size) { 310 case 4: 311 switch (desc->nr_channels) { 312#if 0 /* Not supported for render targets */ 313 case 2: 314 return V_008F14_IMG_DATA_FORMAT_4_4; 315#endif 316 case 4: 317 return V_008F14_IMG_DATA_FORMAT_4_4_4_4; 318 } 319 break; 320 case 8: 321 switch (desc->nr_channels) { 322 case 1: 323 return V_008F14_IMG_DATA_FORMAT_8; 324 case 2: 325 return V_008F14_IMG_DATA_FORMAT_8_8; 326 case 4: 327 return V_008F14_IMG_DATA_FORMAT_8_8_8_8; 328 } 329 break; 330 case 16: 331 switch (desc->nr_channels) { 332 case 1: 333 return V_008F14_IMG_DATA_FORMAT_16; 334 case 2: 335 return V_008F14_IMG_DATA_FORMAT_16_16; 336 case 4: 337 return V_008F14_IMG_DATA_FORMAT_16_16_16_16; 338 } 339 break; 340 case 32: 341 switch (desc->nr_channels) { 342 case 1: 343 return V_008F14_IMG_DATA_FORMAT_32; 344 case 2: 345 return V_008F14_IMG_DATA_FORMAT_32_32; 346 case 3: 347 return V_008F14_IMG_DATA_FORMAT_32_32_32; 348 case 4: 349 return V_008F14_IMG_DATA_FORMAT_32_32_32_32; 350 } 351 } 352 353out_unknown: 354 /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */ 355 return ~0; 356} 357 358uint32_t radv_translate_tex_numformat(VkFormat format, 359 const struct vk_format_description *desc, 360 int first_non_void) 361{ 362 switch (format) { 363 case VK_FORMAT_D24_UNORM_S8_UINT: 364 return V_008F14_IMG_NUM_FORMAT_UNORM; 365 default: 366 if (first_non_void < 0) { 367 if (vk_format_is_compressed(format)) { 368 switch (format) { 369 case VK_FORMAT_BC1_RGB_SRGB_BLOCK: 370 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 371 case VK_FORMAT_BC2_SRGB_BLOCK: 372 case VK_FORMAT_BC3_SRGB_BLOCK: 373 case VK_FORMAT_BC7_SRGB_BLOCK: 374 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 375 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 376 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 377 return V_008F14_IMG_NUM_FORMAT_SRGB; 378 case VK_FORMAT_BC4_SNORM_BLOCK: 379 case VK_FORMAT_BC5_SNORM_BLOCK: 380 case VK_FORMAT_BC6H_SFLOAT_BLOCK: 381 case VK_FORMAT_EAC_R11_SNORM_BLOCK: 382 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 383 return V_008F14_IMG_NUM_FORMAT_SNORM; 384 default: 385 return V_008F14_IMG_NUM_FORMAT_UNORM; 386 } 387 } else if (desc->layout == VK_FORMAT_LAYOUT_SUBSAMPLED) { 388 return V_008F14_IMG_NUM_FORMAT_UNORM; 389 } else { 390 return V_008F14_IMG_NUM_FORMAT_FLOAT; 391 } 392 } else if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) { 393 return V_008F14_IMG_NUM_FORMAT_SRGB; 394 } else { 395 switch (desc->channel[first_non_void].type) { 396 case VK_FORMAT_TYPE_FLOAT: 397 return V_008F14_IMG_NUM_FORMAT_FLOAT; 398 case VK_FORMAT_TYPE_SIGNED: 399 if (desc->channel[first_non_void].normalized) 400 return V_008F14_IMG_NUM_FORMAT_SNORM; 401 else if (desc->channel[first_non_void].pure_integer) 402 return V_008F14_IMG_NUM_FORMAT_SINT; 403 else 404 return V_008F14_IMG_NUM_FORMAT_SSCALED; 405 case VK_FORMAT_TYPE_UNSIGNED: 406 if (desc->channel[first_non_void].normalized) 407 return V_008F14_IMG_NUM_FORMAT_UNORM; 408 else if (desc->channel[first_non_void].pure_integer) 409 return V_008F14_IMG_NUM_FORMAT_UINT; 410 else 411 return V_008F14_IMG_NUM_FORMAT_USCALED; 412 default: 413 return V_008F14_IMG_NUM_FORMAT_UNORM; 414 } 415 } 416 } 417} 418 419uint32_t radv_translate_color_numformat(VkFormat format, 420 const struct vk_format_description *desc, 421 int first_non_void) 422{ 423 unsigned ntype; 424 if (first_non_void == -1 || desc->channel[first_non_void].type == VK_FORMAT_TYPE_FLOAT) 425 ntype = V_028C70_NUMBER_FLOAT; 426 else { 427 ntype = V_028C70_NUMBER_UNORM; 428 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) 429 ntype = V_028C70_NUMBER_SRGB; 430 else if (desc->channel[first_non_void].type == VK_FORMAT_TYPE_SIGNED) { 431 if (desc->channel[first_non_void].pure_integer) { 432 ntype = V_028C70_NUMBER_SINT; 433 } else if (desc->channel[first_non_void].normalized) { 434 ntype = V_028C70_NUMBER_SNORM; 435 } else 436 ntype = ~0u; 437 } else if (desc->channel[first_non_void].type == VK_FORMAT_TYPE_UNSIGNED) { 438 if (desc->channel[first_non_void].pure_integer) { 439 ntype = V_028C70_NUMBER_UINT; 440 } else if (desc->channel[first_non_void].normalized) { 441 ntype = V_028C70_NUMBER_UNORM; 442 } else 443 ntype = ~0u; 444 } 445 } 446 return ntype; 447} 448 449static bool radv_is_sampler_format_supported(VkFormat format, bool *linear_sampling) 450{ 451 const struct vk_format_description *desc = vk_format_description(format); 452 uint32_t num_format; 453 if (!desc || format == VK_FORMAT_UNDEFINED) 454 return false; 455 num_format = radv_translate_tex_numformat(format, desc, 456 vk_format_get_first_non_void_channel(format)); 457 458 if (num_format == V_008F14_IMG_NUM_FORMAT_USCALED || 459 num_format == V_008F14_IMG_NUM_FORMAT_SSCALED) 460 return false; 461 462 if (num_format == V_008F14_IMG_NUM_FORMAT_UNORM || 463 num_format == V_008F14_IMG_NUM_FORMAT_SNORM || 464 num_format == V_008F14_IMG_NUM_FORMAT_FLOAT || 465 num_format == V_008F14_IMG_NUM_FORMAT_SRGB) 466 *linear_sampling = true; 467 else 468 *linear_sampling = false; 469 return radv_translate_tex_dataformat(format, vk_format_description(format), 470 vk_format_get_first_non_void_channel(format)) != ~0U; 471} 472 473 474static bool radv_is_storage_image_format_supported(struct radv_physical_device *physical_device, 475 VkFormat format) 476{ 477 const struct vk_format_description *desc = vk_format_description(format); 478 unsigned data_format, num_format; 479 if (!desc || format == VK_FORMAT_UNDEFINED) 480 return false; 481 482 data_format = radv_translate_tex_dataformat(format, desc, 483 vk_format_get_first_non_void_channel(format)); 484 num_format = radv_translate_tex_numformat(format, desc, 485 vk_format_get_first_non_void_channel(format)); 486 487 if(data_format == ~0 || num_format == ~0) 488 return false; 489 490 /* Extracted from the GCN3 ISA document. */ 491 switch(num_format) { 492 case V_008F14_IMG_NUM_FORMAT_UNORM: 493 case V_008F14_IMG_NUM_FORMAT_SNORM: 494 case V_008F14_IMG_NUM_FORMAT_UINT: 495 case V_008F14_IMG_NUM_FORMAT_SINT: 496 case V_008F14_IMG_NUM_FORMAT_FLOAT: 497 break; 498 default: 499 return false; 500 } 501 502 switch(data_format) { 503 case V_008F14_IMG_DATA_FORMAT_8: 504 case V_008F14_IMG_DATA_FORMAT_16: 505 case V_008F14_IMG_DATA_FORMAT_8_8: 506 case V_008F14_IMG_DATA_FORMAT_32: 507 case V_008F14_IMG_DATA_FORMAT_16_16: 508 case V_008F14_IMG_DATA_FORMAT_10_11_11: 509 case V_008F14_IMG_DATA_FORMAT_11_11_10: 510 case V_008F14_IMG_DATA_FORMAT_10_10_10_2: 511 case V_008F14_IMG_DATA_FORMAT_2_10_10_10: 512 case V_008F14_IMG_DATA_FORMAT_8_8_8_8: 513 case V_008F14_IMG_DATA_FORMAT_32_32: 514 case V_008F14_IMG_DATA_FORMAT_16_16_16_16: 515 case V_008F14_IMG_DATA_FORMAT_32_32_32_32: 516 case V_008F14_IMG_DATA_FORMAT_5_6_5: 517 case V_008F14_IMG_DATA_FORMAT_1_5_5_5: 518 case V_008F14_IMG_DATA_FORMAT_5_5_5_1: 519 case V_008F14_IMG_DATA_FORMAT_4_4_4_4: 520 /* TODO: FMASK formats. */ 521 return true; 522 default: 523 return false; 524 } 525} 526 527static bool radv_is_buffer_format_supported(VkFormat format, bool *scaled) 528{ 529 const struct vk_format_description *desc = vk_format_description(format); 530 unsigned data_format, num_format; 531 if (!desc || format == VK_FORMAT_UNDEFINED) 532 return false; 533 534 data_format = radv_translate_buffer_dataformat(desc, 535 vk_format_get_first_non_void_channel(format)); 536 num_format = radv_translate_buffer_numformat(desc, 537 vk_format_get_first_non_void_channel(format)); 538 539 *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) || (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED); 540 return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID && 541 num_format != ~0; 542} 543 544bool radv_is_colorbuffer_format_supported(VkFormat format, bool *blendable) 545{ 546 const struct vk_format_description *desc = vk_format_description(format); 547 uint32_t color_format = radv_translate_colorformat(format); 548 uint32_t color_swap = radv_translate_colorswap(format, false); 549 uint32_t color_num_format = radv_translate_color_numformat(format, 550 desc, 551 vk_format_get_first_non_void_channel(format)); 552 553 if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT || 554 color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 || 555 color_format == V_028C70_COLOR_X24_8_32_FLOAT) { 556 *blendable = false; 557 } else 558 *blendable = true; 559 return color_format != V_028C70_COLOR_INVALID && 560 color_swap != ~0U && 561 color_num_format != ~0; 562} 563 564static bool radv_is_zs_format_supported(VkFormat format) 565{ 566 return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT; 567} 568 569static bool radv_is_filter_minmax_format_supported(VkFormat format) 570{ 571 /* From the Vulkan spec 1.1.71: 572 * 573 * "The following formats must support the 574 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT feature with 575 * VK_IMAGE_TILING_OPTIMAL, if they support 576 * VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT." 577 */ 578 /* TODO: enable more formats. */ 579 switch (format) { 580 case VK_FORMAT_R8_UNORM: 581 case VK_FORMAT_R8_SNORM: 582 case VK_FORMAT_R16_UNORM: 583 case VK_FORMAT_R16_SNORM: 584 case VK_FORMAT_R16_SFLOAT: 585 case VK_FORMAT_R32_SFLOAT: 586 case VK_FORMAT_D16_UNORM: 587 case VK_FORMAT_X8_D24_UNORM_PACK32: 588 case VK_FORMAT_D32_SFLOAT: 589 case VK_FORMAT_D16_UNORM_S8_UINT: 590 case VK_FORMAT_D24_UNORM_S8_UINT: 591 case VK_FORMAT_D32_SFLOAT_S8_UINT: 592 return true; 593 default: 594 return false; 595 } 596} 597 598static void 599radv_physical_device_get_format_properties(struct radv_physical_device *physical_device, 600 VkFormat format, 601 VkFormatProperties *out_properties) 602{ 603 VkFormatFeatureFlags linear = 0, tiled = 0, buffer = 0; 604 const struct vk_format_description *desc = vk_format_description(format); 605 bool blendable; 606 bool scaled = false; 607 if (!desc) { 608 out_properties->linearTilingFeatures = linear; 609 out_properties->optimalTilingFeatures = tiled; 610 out_properties->bufferFeatures = buffer; 611 return; 612 } 613 614 if (desc->layout == VK_FORMAT_LAYOUT_ETC && 615 physical_device->rad_info.family != CHIP_VEGA10 && 616 physical_device->rad_info.family != CHIP_RAVEN && 617 physical_device->rad_info.family != CHIP_STONEY) { 618 out_properties->linearTilingFeatures = linear; 619 out_properties->optimalTilingFeatures = tiled; 620 out_properties->bufferFeatures = buffer; 621 return; 622 } 623 624 if (radv_is_storage_image_format_supported(physical_device, format)) { 625 tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 626 linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT; 627 } 628 629 if (radv_is_buffer_format_supported(format, &scaled)) { 630 buffer |= VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT; 631 if (!scaled) 632 buffer |= VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | 633 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT; 634 } 635 636 if (vk_format_is_depth_or_stencil(format)) { 637 if (radv_is_zs_format_supported(format)) { 638 tiled |= VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT; 639 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; 640 tiled |= VK_FORMAT_FEATURE_BLIT_SRC_BIT | 641 VK_FORMAT_FEATURE_BLIT_DST_BIT; 642 tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | 643 VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR; 644 645 if (radv_is_filter_minmax_format_supported(format)) 646 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT; 647 648 /* Don't support blitting surfaces with depth/stencil. */ 649 if (vk_format_is_depth(format) && vk_format_is_stencil(format)) 650 tiled &= ~VK_FORMAT_FEATURE_BLIT_DST_BIT; 651 652 /* Don't support linear depth surfaces */ 653 linear = 0; 654 } 655 } else { 656 bool linear_sampling; 657 if (radv_is_sampler_format_supported(format, &linear_sampling)) { 658 linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | 659 VK_FORMAT_FEATURE_BLIT_SRC_BIT; 660 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | 661 VK_FORMAT_FEATURE_BLIT_SRC_BIT; 662 663 if (radv_is_filter_minmax_format_supported(format)) 664 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT_EXT; 665 666 if (linear_sampling) { 667 linear |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 668 tiled |= VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 669 } 670 671 /* Don't support blitting for R32G32B32 formats. */ 672 if (format == VK_FORMAT_R32G32B32_SFLOAT || 673 format == VK_FORMAT_R32G32B32_UINT || 674 format == VK_FORMAT_R32G32B32_SINT) { 675 linear &= ~VK_FORMAT_FEATURE_BLIT_SRC_BIT; 676 } 677 } 678 if (radv_is_colorbuffer_format_supported(format, &blendable)) { 679 linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; 680 tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_BLIT_DST_BIT; 681 if (blendable) { 682 linear |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; 683 tiled |= VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT; 684 } 685 } 686 if (tiled && !scaled) { 687 tiled |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | 688 VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR; 689 } 690 691 /* Tiled formatting does not support NPOT pixel sizes */ 692 if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format))) 693 tiled = 0; 694 } 695 696 if (linear && !scaled) { 697 linear |= VK_FORMAT_FEATURE_TRANSFER_SRC_BIT_KHR | 698 VK_FORMAT_FEATURE_TRANSFER_DST_BIT_KHR; 699 } 700 701 if (format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT) { 702 buffer |= VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; 703 linear |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; 704 tiled |= VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT; 705 } 706 707 switch(format) { 708 case VK_FORMAT_A2R10G10B10_SNORM_PACK32: 709 case VK_FORMAT_A2B10G10R10_SNORM_PACK32: 710 case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: 711 case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: 712 case VK_FORMAT_A2R10G10B10_SINT_PACK32: 713 case VK_FORMAT_A2B10G10R10_SINT_PACK32: 714 if (physical_device->rad_info.chip_class <= VI && 715 physical_device->rad_info.family != CHIP_STONEY) { 716 buffer &= ~(VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT | 717 VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT); 718 linear = 0; 719 tiled = 0; 720 } 721 break; 722 default: 723 break; 724 } 725 726 out_properties->linearTilingFeatures = linear; 727 out_properties->optimalTilingFeatures = tiled; 728 out_properties->bufferFeatures = buffer; 729} 730 731uint32_t radv_translate_colorformat(VkFormat format) 732{ 733 const struct vk_format_description *desc = vk_format_description(format); 734 735#define HAS_SIZE(x,y,z,w) \ 736 (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \ 737 desc->channel[2].size == (z) && desc->channel[3].size == (w)) 738 739 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */ 740 return V_028C70_COLOR_10_11_11; 741 742 if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) 743 return V_028C70_COLOR_INVALID; 744 745 /* hw cannot support mixed formats (except depth/stencil, since 746 * stencil is not written to). */ 747 if (desc->is_mixed && desc->colorspace != VK_FORMAT_COLORSPACE_ZS) 748 return V_028C70_COLOR_INVALID; 749 750 switch (desc->nr_channels) { 751 case 1: 752 switch (desc->channel[0].size) { 753 case 8: 754 return V_028C70_COLOR_8; 755 case 16: 756 return V_028C70_COLOR_16; 757 case 32: 758 return V_028C70_COLOR_32; 759 } 760 break; 761 case 2: 762 if (desc->channel[0].size == desc->channel[1].size) { 763 switch (desc->channel[0].size) { 764 case 8: 765 return V_028C70_COLOR_8_8; 766 case 16: 767 return V_028C70_COLOR_16_16; 768 case 32: 769 return V_028C70_COLOR_32_32; 770 } 771 } else if (HAS_SIZE(8,24,0,0)) { 772 return V_028C70_COLOR_24_8; 773 } else if (HAS_SIZE(24,8,0,0)) { 774 return V_028C70_COLOR_8_24; 775 } 776 break; 777 case 3: 778 if (HAS_SIZE(5,6,5,0)) { 779 return V_028C70_COLOR_5_6_5; 780 } else if (HAS_SIZE(32,8,24,0)) { 781 return V_028C70_COLOR_X24_8_32_FLOAT; 782 } 783 break; 784 case 4: 785 if (desc->channel[0].size == desc->channel[1].size && 786 desc->channel[0].size == desc->channel[2].size && 787 desc->channel[0].size == desc->channel[3].size) { 788 switch (desc->channel[0].size) { 789 case 4: 790 return V_028C70_COLOR_4_4_4_4; 791 case 8: 792 return V_028C70_COLOR_8_8_8_8; 793 case 16: 794 return V_028C70_COLOR_16_16_16_16; 795 case 32: 796 return V_028C70_COLOR_32_32_32_32; 797 } 798 } else if (HAS_SIZE(5,5,5,1)) { 799 return V_028C70_COLOR_1_5_5_5; 800 } else if (HAS_SIZE(1,5,5,5)) { 801 return V_028C70_COLOR_5_5_5_1; 802 } else if (HAS_SIZE(10,10,10,2)) { 803 return V_028C70_COLOR_2_10_10_10; 804 } 805 break; 806 } 807 return V_028C70_COLOR_INVALID; 808} 809 810uint32_t radv_colorformat_endian_swap(uint32_t colorformat) 811{ 812 if (0/*SI_BIG_ENDIAN*/) { 813 switch(colorformat) { 814 /* 8-bit buffers. */ 815 case V_028C70_COLOR_8: 816 return V_028C70_ENDIAN_NONE; 817 818 /* 16-bit buffers. */ 819 case V_028C70_COLOR_5_6_5: 820 case V_028C70_COLOR_1_5_5_5: 821 case V_028C70_COLOR_4_4_4_4: 822 case V_028C70_COLOR_16: 823 case V_028C70_COLOR_8_8: 824 return V_028C70_ENDIAN_8IN16; 825 826 /* 32-bit buffers. */ 827 case V_028C70_COLOR_8_8_8_8: 828 case V_028C70_COLOR_2_10_10_10: 829 case V_028C70_COLOR_8_24: 830 case V_028C70_COLOR_24_8: 831 case V_028C70_COLOR_16_16: 832 return V_028C70_ENDIAN_8IN32; 833 834 /* 64-bit buffers. */ 835 case V_028C70_COLOR_16_16_16_16: 836 return V_028C70_ENDIAN_8IN16; 837 838 case V_028C70_COLOR_32_32: 839 return V_028C70_ENDIAN_8IN32; 840 841 /* 128-bit buffers. */ 842 case V_028C70_COLOR_32_32_32_32: 843 return V_028C70_ENDIAN_8IN32; 844 default: 845 return V_028C70_ENDIAN_NONE; /* Unsupported. */ 846 } 847 } else { 848 return V_028C70_ENDIAN_NONE; 849 } 850} 851 852uint32_t radv_translate_dbformat(VkFormat format) 853{ 854 switch (format) { 855 case VK_FORMAT_D16_UNORM: 856 case VK_FORMAT_D16_UNORM_S8_UINT: 857 return V_028040_Z_16; 858 case VK_FORMAT_D32_SFLOAT: 859 case VK_FORMAT_D32_SFLOAT_S8_UINT: 860 return V_028040_Z_32_FLOAT; 861 default: 862 return V_028040_Z_INVALID; 863 } 864} 865 866unsigned radv_translate_colorswap(VkFormat format, bool do_endian_swap) 867{ 868 const struct vk_format_description *desc = vk_format_description(format); 869 870#define HAS_SWIZZLE(chan,swz) (desc->swizzle[chan] == VK_SWIZZLE_##swz) 871 872 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) 873 return V_028C70_SWAP_STD; 874 875 if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) 876 return ~0U; 877 878 switch (desc->nr_channels) { 879 case 1: 880 if (HAS_SWIZZLE(0,X)) 881 return V_028C70_SWAP_STD; /* X___ */ 882 else if (HAS_SWIZZLE(3,X)) 883 return V_028C70_SWAP_ALT_REV; /* ___X */ 884 break; 885 case 2: 886 if ((HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,Y)) || 887 (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(1,NONE)) || 888 (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,Y))) 889 return V_028C70_SWAP_STD; /* XY__ */ 890 else if ((HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,X)) || 891 (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(1,NONE)) || 892 (HAS_SWIZZLE(0,NONE) && HAS_SWIZZLE(1,X))) 893 /* YX__ */ 894 return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV); 895 else if (HAS_SWIZZLE(0,X) && HAS_SWIZZLE(3,Y)) 896 return V_028C70_SWAP_ALT; /* X__Y */ 897 else if (HAS_SWIZZLE(0,Y) && HAS_SWIZZLE(3,X)) 898 return V_028C70_SWAP_ALT_REV; /* Y__X */ 899 break; 900 case 3: 901 if (HAS_SWIZZLE(0,X)) 902 return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD); 903 else if (HAS_SWIZZLE(0,Z)) 904 return V_028C70_SWAP_STD_REV; /* ZYX */ 905 break; 906 case 4: 907 /* check the middle channels, the 1st and 4th channel can be NONE */ 908 if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,Z)) { 909 return V_028C70_SWAP_STD; /* XYZW */ 910 } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,Y)) { 911 return V_028C70_SWAP_STD_REV; /* WZYX */ 912 } else if (HAS_SWIZZLE(1,Y) && HAS_SWIZZLE(2,X)) { 913 return V_028C70_SWAP_ALT; /* ZYXW */ 914 } else if (HAS_SWIZZLE(1,Z) && HAS_SWIZZLE(2,W)) { 915 /* YZWX */ 916 if (desc->is_array) 917 return V_028C70_SWAP_ALT_REV; 918 else 919 return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV); 920 } 921 break; 922 } 923 return ~0U; 924} 925 926bool radv_format_pack_clear_color(VkFormat format, 927 uint32_t clear_vals[2], 928 VkClearColorValue *value) 929{ 930 const struct vk_format_description *desc = vk_format_description(format); 931 932 if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { 933 clear_vals[0] = float3_to_r11g11b10f(value->float32); 934 clear_vals[1] = 0; 935 return true; 936 } 937 938 if (desc->layout != VK_FORMAT_LAYOUT_PLAIN) { 939 fprintf(stderr, "failed to fast clear for non-plain format %d\n", format); 940 return false; 941 } 942 943 if (!util_is_power_of_two_or_zero(desc->block.bits)) { 944 fprintf(stderr, "failed to fast clear for NPOT format %d\n", format); 945 return false; 946 } 947 948 if (desc->block.bits > 64) { 949 /* 950 * We have a 128 bits format, check if the first 3 components are the same. 951 * Every elements has to be 32 bits since we don't support 64-bit formats, 952 * and we can skip swizzling checks as alpha always comes last for these and 953 * we do not care about the rest as they have to be the same. 954 */ 955 if (desc->channel[0].type == VK_FORMAT_TYPE_FLOAT) { 956 if (value->float32[0] != value->float32[1] || 957 value->float32[0] != value->float32[2]) 958 return false; 959 } else { 960 if (value->uint32[0] != value->uint32[1] || 961 value->uint32[0] != value->uint32[2]) 962 return false; 963 } 964 clear_vals[0] = value->uint32[0]; 965 clear_vals[1] = value->uint32[3]; 966 return true; 967 } 968 uint64_t clear_val = 0; 969 970 for (unsigned c = 0; c < 4; ++c) { 971 if (desc->swizzle[c] >= 4) 972 continue; 973 974 const struct vk_format_channel_description *channel = &desc->channel[desc->swizzle[c]]; 975 assert(channel->size); 976 977 uint64_t v = 0; 978 if (channel->pure_integer) { 979 v = value->uint32[c] & ((1ULL << channel->size) - 1); 980 } else if (channel->normalized) { 981 if (channel->type == VK_FORMAT_TYPE_UNSIGNED && 982 desc->swizzle[c] < 3 && 983 desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) { 984 assert(channel->size == 8); 985 986 v = util_format_linear_float_to_srgb_8unorm(value->float32[c]); 987 } else if (channel->type == VK_FORMAT_TYPE_UNSIGNED) { 988 v = MAX2(MIN2(value->float32[c], 1.0f), 0.0f) * ((1ULL << channel->size) - 1); 989 } else { 990 v = MAX2(MIN2(value->float32[c], 1.0f), -1.0f) * ((1ULL << (channel->size - 1)) - 1); 991 } 992 } else if (channel->type == VK_FORMAT_TYPE_FLOAT) { 993 if (channel->size == 32) { 994 memcpy(&v, &value->float32[c], 4); 995 } else if(channel->size == 16) { 996 v = util_float_to_half(value->float32[c]); 997 } else { 998 fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format); 999 return false; 1000 } 1001 } else { 1002 fprintf(stderr, "failed to fast clear for unhandled component type in format %d\n", format); 1003 return false; 1004 } 1005 clear_val |= (v & ((1ULL << channel->size) - 1)) << channel->shift; 1006 } 1007 1008 clear_vals[0] = clear_val; 1009 clear_vals[1] = clear_val >> 32; 1010 1011 return true; 1012} 1013 1014void radv_GetPhysicalDeviceFormatProperties( 1015 VkPhysicalDevice physicalDevice, 1016 VkFormat format, 1017 VkFormatProperties* pFormatProperties) 1018{ 1019 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); 1020 1021 radv_physical_device_get_format_properties(physical_device, 1022 format, 1023 pFormatProperties); 1024} 1025 1026void radv_GetPhysicalDeviceFormatProperties2( 1027 VkPhysicalDevice physicalDevice, 1028 VkFormat format, 1029 VkFormatProperties2KHR* pFormatProperties) 1030{ 1031 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); 1032 1033 radv_physical_device_get_format_properties(physical_device, 1034 format, 1035 &pFormatProperties->formatProperties); 1036} 1037 1038static VkResult radv_get_image_format_properties(struct radv_physical_device *physical_device, 1039 const VkPhysicalDeviceImageFormatInfo2KHR *info, 1040 VkImageFormatProperties *pImageFormatProperties) 1041 1042{ 1043 VkFormatProperties format_props; 1044 VkFormatFeatureFlags format_feature_flags; 1045 VkExtent3D maxExtent; 1046 uint32_t maxMipLevels; 1047 uint32_t maxArraySize; 1048 VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1049 1050 radv_physical_device_get_format_properties(physical_device, info->format, 1051 &format_props); 1052 if (info->tiling == VK_IMAGE_TILING_LINEAR) { 1053 format_feature_flags = format_props.linearTilingFeatures; 1054 } else if (info->tiling == VK_IMAGE_TILING_OPTIMAL) { 1055 format_feature_flags = format_props.optimalTilingFeatures; 1056 } else { 1057 unreachable("bad VkImageTiling"); 1058 } 1059 1060 if (format_feature_flags == 0) 1061 goto unsupported; 1062 1063 if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(info->format)) 1064 goto unsupported; 1065 1066 switch (info->type) { 1067 default: 1068 unreachable("bad vkimage type\n"); 1069 case VK_IMAGE_TYPE_1D: 1070 maxExtent.width = 16384; 1071 maxExtent.height = 1; 1072 maxExtent.depth = 1; 1073 maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1074 maxArraySize = 2048; 1075 break; 1076 case VK_IMAGE_TYPE_2D: 1077 maxExtent.width = 16384; 1078 maxExtent.height = 16384; 1079 maxExtent.depth = 1; 1080 maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1081 maxArraySize = 2048; 1082 break; 1083 case VK_IMAGE_TYPE_3D: 1084 maxExtent.width = 2048; 1085 maxExtent.height = 2048; 1086 maxExtent.depth = 2048; 1087 maxMipLevels = 12; /* log2(maxWidth) + 1 */ 1088 maxArraySize = 1; 1089 break; 1090 } 1091 1092 if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 1093 info->type == VK_IMAGE_TYPE_2D && 1094 (format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 1095 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) && 1096 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 1097 !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) { 1098 sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT; 1099 } 1100 1101 if (info->tiling == VK_IMAGE_TILING_LINEAR && 1102 (info->format == VK_FORMAT_R32G32B32_SFLOAT || 1103 info->format == VK_FORMAT_R32G32B32_SINT || 1104 info->format == VK_FORMAT_R32G32B32_UINT)) { 1105 /* R32G32B32 is a weird format and the driver currently only 1106 * supports the barely minimum. 1107 * TODO: Implement more if we really need to. 1108 */ 1109 if (info->type == VK_IMAGE_TYPE_3D) 1110 goto unsupported; 1111 maxArraySize = 1; 1112 maxMipLevels = 1; 1113 } 1114 1115 if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 1116 if (!(format_feature_flags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT)) { 1117 goto unsupported; 1118 } 1119 } 1120 1121 if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) { 1122 if (!(format_feature_flags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT)) { 1123 goto unsupported; 1124 } 1125 } 1126 1127 if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 1128 if (!(format_feature_flags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT)) { 1129 goto unsupported; 1130 } 1131 } 1132 1133 if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 1134 if (!(format_feature_flags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 1135 goto unsupported; 1136 } 1137 } 1138 1139 if (info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 1140 if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT)) { 1141 goto unsupported; 1142 } 1143 } 1144 1145 if (info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { 1146 if (!(format_feature_flags & VK_FORMAT_FEATURE_TRANSFER_DST_BIT)) { 1147 goto unsupported; 1148 } 1149 } 1150 1151 if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 1152 if (!(format_feature_flags & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | 1153 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))) { 1154 goto unsupported; 1155 } 1156 } 1157 1158 *pImageFormatProperties = (VkImageFormatProperties) { 1159 .maxExtent = maxExtent, 1160 .maxMipLevels = maxMipLevels, 1161 .maxArrayLayers = maxArraySize, 1162 .sampleCounts = sampleCounts, 1163 1164 /* FINISHME: Accurately calculate 1165 * VkImageFormatProperties::maxResourceSize. 1166 */ 1167 .maxResourceSize = UINT32_MAX, 1168 }; 1169 1170 return VK_SUCCESS; 1171unsupported: 1172 *pImageFormatProperties = (VkImageFormatProperties) { 1173 .maxExtent = { 0, 0, 0 }, 1174 .maxMipLevels = 0, 1175 .maxArrayLayers = 0, 1176 .sampleCounts = 0, 1177 .maxResourceSize = 0, 1178 }; 1179 1180 return VK_ERROR_FORMAT_NOT_SUPPORTED; 1181} 1182 1183VkResult radv_GetPhysicalDeviceImageFormatProperties( 1184 VkPhysicalDevice physicalDevice, 1185 VkFormat format, 1186 VkImageType type, 1187 VkImageTiling tiling, 1188 VkImageUsageFlags usage, 1189 VkImageCreateFlags createFlags, 1190 VkImageFormatProperties* pImageFormatProperties) 1191{ 1192 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); 1193 1194 const VkPhysicalDeviceImageFormatInfo2KHR info = { 1195 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR, 1196 .pNext = NULL, 1197 .format = format, 1198 .type = type, 1199 .tiling = tiling, 1200 .usage = usage, 1201 .flags = createFlags, 1202 }; 1203 1204 return radv_get_image_format_properties(physical_device, &info, 1205 pImageFormatProperties); 1206} 1207 1208static void 1209get_external_image_format_properties(const VkPhysicalDeviceImageFormatInfo2KHR *pImageFormatInfo, 1210 VkExternalMemoryHandleTypeFlagBitsKHR handleType, 1211 VkExternalMemoryPropertiesKHR *external_properties) 1212{ 1213 VkExternalMemoryFeatureFlagBitsKHR flags = 0; 1214 VkExternalMemoryHandleTypeFlagsKHR export_flags = 0; 1215 VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0; 1216 switch (handleType) { 1217 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: 1218 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1219 switch (pImageFormatInfo->type) { 1220 case VK_IMAGE_TYPE_2D: 1221 flags = VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR|VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; 1222 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | 1223 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 1224 break; 1225 default: 1226 break; 1227 } 1228 break; 1229 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1230 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; 1231 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 1232 break; 1233 default: 1234 break; 1235 } 1236 1237 *external_properties = (VkExternalMemoryPropertiesKHR) { 1238 .externalMemoryFeatures = flags, 1239 .exportFromImportedHandleTypes = export_flags, 1240 .compatibleHandleTypes = compat_flags, 1241 }; 1242} 1243 1244VkResult radv_GetPhysicalDeviceImageFormatProperties2( 1245 VkPhysicalDevice physicalDevice, 1246 const VkPhysicalDeviceImageFormatInfo2KHR *base_info, 1247 VkImageFormatProperties2KHR *base_props) 1248{ 1249 RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); 1250 const VkPhysicalDeviceExternalImageFormatInfoKHR *external_info = NULL; 1251 VkExternalImageFormatPropertiesKHR *external_props = NULL; 1252 VkResult result; 1253 1254 result = radv_get_image_format_properties(physical_device, base_info, 1255 &base_props->imageFormatProperties); 1256 if (result != VK_SUCCESS) 1257 return result; 1258 1259 /* Extract input structs */ 1260 vk_foreach_struct_const(s, base_info->pNext) { 1261 switch (s->sType) { 1262 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR: 1263 external_info = (const void *) s; 1264 break; 1265 default: 1266 break; 1267 } 1268 } 1269 1270 /* Extract output structs */ 1271 vk_foreach_struct(s, base_props->pNext) { 1272 switch (s->sType) { 1273 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR: 1274 external_props = (void *) s; 1275 break; 1276 default: 1277 break; 1278 } 1279 } 1280 1281 /* From the Vulkan 1.0.42 spec: 1282 * 1283 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2KHR will 1284 * behave as if VkPhysicalDeviceExternalImageFormatInfoKHR was not 1285 * present and VkExternalImageFormatPropertiesKHR will be ignored. 1286 */ 1287 if (external_info && external_info->handleType != 0) { 1288 switch (external_info->handleType) { 1289 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: 1290 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1291 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1292 get_external_image_format_properties(base_info, external_info->handleType, 1293 &external_props->externalMemoryProperties); 1294 break; 1295 default: 1296 /* From the Vulkan 1.0.42 spec: 1297 * 1298 * If handleType is not compatible with the [parameters] specified 1299 * in VkPhysicalDeviceImageFormatInfo2KHR, then 1300 * vkGetPhysicalDeviceImageFormatProperties2KHR returns 1301 * VK_ERROR_FORMAT_NOT_SUPPORTED. 1302 */ 1303 result = vk_errorf(physical_device->instance, VK_ERROR_FORMAT_NOT_SUPPORTED, 1304 "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x", 1305 external_info->handleType); 1306 goto fail; 1307 } 1308 } 1309 1310 return VK_SUCCESS; 1311 1312fail: 1313 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 1314 /* From the Vulkan 1.0.42 spec: 1315 * 1316 * If the combination of parameters to 1317 * vkGetPhysicalDeviceImageFormatProperties2KHR is not supported by 1318 * the implementation for use in vkCreateImage, then all members of 1319 * imageFormatProperties will be filled with zero. 1320 */ 1321 base_props->imageFormatProperties = (VkImageFormatProperties) {0}; 1322 } 1323 1324 return result; 1325} 1326 1327void radv_GetPhysicalDeviceSparseImageFormatProperties( 1328 VkPhysicalDevice physicalDevice, 1329 VkFormat format, 1330 VkImageType type, 1331 uint32_t samples, 1332 VkImageUsageFlags usage, 1333 VkImageTiling tiling, 1334 uint32_t* pNumProperties, 1335 VkSparseImageFormatProperties* pProperties) 1336{ 1337 /* Sparse images are not yet supported. */ 1338 *pNumProperties = 0; 1339} 1340 1341void radv_GetPhysicalDeviceSparseImageFormatProperties2( 1342 VkPhysicalDevice physicalDevice, 1343 const VkPhysicalDeviceSparseImageFormatInfo2KHR* pFormatInfo, 1344 uint32_t *pPropertyCount, 1345 VkSparseImageFormatProperties2KHR* pProperties) 1346{ 1347 /* Sparse images are not yet supported. */ 1348 *pPropertyCount = 0; 1349} 1350 1351void radv_GetPhysicalDeviceExternalBufferProperties( 1352 VkPhysicalDevice physicalDevice, 1353 const VkPhysicalDeviceExternalBufferInfoKHR *pExternalBufferInfo, 1354 VkExternalBufferPropertiesKHR *pExternalBufferProperties) 1355{ 1356 VkExternalMemoryFeatureFlagBitsKHR flags = 0; 1357 VkExternalMemoryHandleTypeFlagsKHR export_flags = 0; 1358 VkExternalMemoryHandleTypeFlagsKHR compat_flags = 0; 1359 switch(pExternalBufferInfo->handleType) { 1360 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR: 1361 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1362 flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR | 1363 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; 1364 compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR | 1365 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 1366 break; 1367 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1368 flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT_KHR; 1369 compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 1370 break; 1371 default: 1372 break; 1373 } 1374 pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryPropertiesKHR) { 1375 .externalMemoryFeatures = flags, 1376 .exportFromImportedHandleTypes = export_flags, 1377 .compatibleHandleTypes = compat_flags, 1378 }; 1379} 1380 1381/* DCC channel type categories within which formats can be reinterpreted 1382 * while keeping the same DCC encoding. The swizzle must also match. */ 1383enum dcc_channel_type { 1384 dcc_channel_float32, 1385 dcc_channel_uint32, 1386 dcc_channel_sint32, 1387 dcc_channel_float16, 1388 dcc_channel_uint16, 1389 dcc_channel_sint16, 1390 dcc_channel_uint_10_10_10_2, 1391 dcc_channel_uint8, 1392 dcc_channel_sint8, 1393 dcc_channel_incompatible, 1394}; 1395 1396/* Return the type of DCC encoding. */ 1397static enum dcc_channel_type 1398radv_get_dcc_channel_type(const struct vk_format_description *desc) 1399{ 1400 int i; 1401 1402 /* Find the first non-void channel. */ 1403 for (i = 0; i < desc->nr_channels; i++) 1404 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID) 1405 break; 1406 if (i == desc->nr_channels) 1407 return dcc_channel_incompatible; 1408 1409 switch (desc->channel[i].size) { 1410 case 32: 1411 if (desc->channel[i].type == VK_FORMAT_TYPE_FLOAT) 1412 return dcc_channel_float32; 1413 if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) 1414 return dcc_channel_uint32; 1415 return dcc_channel_sint32; 1416 case 16: 1417 if (desc->channel[i].type == VK_FORMAT_TYPE_FLOAT) 1418 return dcc_channel_float16; 1419 if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) 1420 return dcc_channel_uint16; 1421 return dcc_channel_sint16; 1422 case 10: 1423 return dcc_channel_uint_10_10_10_2; 1424 case 8: 1425 if (desc->channel[i].type == VK_FORMAT_TYPE_UNSIGNED) 1426 return dcc_channel_uint8; 1427 return dcc_channel_sint8; 1428 default: 1429 return dcc_channel_incompatible; 1430 } 1431} 1432 1433/* Return if it's allowed to reinterpret one format as another with DCC enabled. */ 1434bool radv_dcc_formats_compatible(VkFormat format1, 1435 VkFormat format2) 1436{ 1437 const struct vk_format_description *desc1, *desc2; 1438 enum dcc_channel_type type1, type2; 1439 int i; 1440 1441 if (format1 == format2) 1442 return true; 1443 1444 desc1 = vk_format_description(format1); 1445 desc2 = vk_format_description(format2); 1446 1447 if (desc1->nr_channels != desc2->nr_channels) 1448 return false; 1449 1450 /* Swizzles must be the same. */ 1451 for (i = 0; i < desc1->nr_channels; i++) 1452 if (desc1->swizzle[i] <= VK_SWIZZLE_W && 1453 desc2->swizzle[i] <= VK_SWIZZLE_W && 1454 desc1->swizzle[i] != desc2->swizzle[i]) 1455 return false; 1456 1457 type1 = radv_get_dcc_channel_type(desc1); 1458 type2 = radv_get_dcc_channel_type(desc2); 1459 1460 return type1 != dcc_channel_incompatible && 1461 type2 != dcc_channel_incompatible && 1462 type1 == type2; 1463} 1464 1465