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