1 /* 2 * Copyright 2016 Red Hat. 3 * Copyright 2016 Bas Nieuwenhuizen 4 * 5 * Based on u_format.h which is: 6 * Copyright 2009-2010 Vmware, Inc. 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without limitation 10 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11 * and/or sell copies of the Software, and to permit persons to whom the 12 * Software is furnished to do so, subject to the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the next 15 * paragraph) shall be included in all copies or substantial portions of the 16 * Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 24 * IN THE SOFTWARE. 25 */ 26 27 #pragma once 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #include <assert.h> 34 #include <vulkan/vulkan.h> 35 #include <util/macros.h> 36 enum vk_format_layout { 37 /** 38 * Formats with vk_format_block::width == vk_format_block::height == 1 39 * that can be described as an ordinary data structure. 40 */ 41 VK_FORMAT_LAYOUT_PLAIN = 0, 42 43 /** 44 * Formats with sub-sampled channels. 45 * 46 * This is for formats like YVYU where there is less than one sample per 47 * pixel. 48 */ 49 VK_FORMAT_LAYOUT_SUBSAMPLED = 3, 50 51 /** 52 * S3 Texture Compression formats. 53 */ 54 VK_FORMAT_LAYOUT_S3TC = 4, 55 56 /** 57 * Red-Green Texture Compression formats. 58 */ 59 VK_FORMAT_LAYOUT_RGTC = 5, 60 61 /** 62 * Ericsson Texture Compression 63 */ 64 VK_FORMAT_LAYOUT_ETC = 6, 65 66 /** 67 * BC6/7 Texture Compression 68 */ 69 VK_FORMAT_LAYOUT_BPTC = 7, 70 71 /** 72 * ASTC 73 */ 74 VK_FORMAT_LAYOUT_ASTC = 8, 75 76 /** 77 * Everything else that doesn't fit in any of the above layouts. 78 */ 79 VK_FORMAT_LAYOUT_OTHER = 9 80 }; 81 82 struct vk_format_block 83 { 84 /** Block width in pixels */ 85 unsigned width; 86 87 /** Block height in pixels */ 88 unsigned height; 89 90 /** Block size in bits */ 91 unsigned bits; 92 }; 93 94 enum vk_format_type { 95 VK_FORMAT_TYPE_VOID = 0, 96 VK_FORMAT_TYPE_UNSIGNED = 1, 97 VK_FORMAT_TYPE_SIGNED = 2, 98 VK_FORMAT_TYPE_FIXED = 3, 99 VK_FORMAT_TYPE_FLOAT = 4 100 }; 101 102 103 enum vk_format_colorspace { 104 VK_FORMAT_COLORSPACE_RGB = 0, 105 VK_FORMAT_COLORSPACE_SRGB = 1, 106 VK_FORMAT_COLORSPACE_YUV = 2, 107 VK_FORMAT_COLORSPACE_ZS = 3 108 }; 109 110 struct vk_format_channel_description { 111 unsigned type:5; 112 unsigned normalized:1; 113 unsigned pure_integer:1; 114 unsigned scaled:1; 115 unsigned size:8; 116 unsigned shift:16; 117 }; 118 119 struct vk_format_description 120 { 121 VkFormat format; 122 const char *name; 123 const char *short_name; 124 125 struct vk_format_block block; 126 enum vk_format_layout layout; 127 128 unsigned nr_channels:3; 129 unsigned is_array:1; 130 unsigned is_bitmask:1; 131 unsigned is_mixed:1; 132 133 struct vk_format_channel_description channel[4]; 134 135 unsigned char swizzle[4]; 136 137 enum vk_format_colorspace colorspace; 138 }; 139 140 extern const struct vk_format_description vk_format_description_table[]; 141 142 const struct vk_format_description *vk_format_description(VkFormat format); 143 144 /** 145 * Return total bits needed for the pixel format per block. 146 */ 147 static inline unsigned 148 vk_format_get_blocksizebits(VkFormat format) 149 { 150 const struct vk_format_description *desc = vk_format_description(format); 151 152 assert(desc); 153 if (!desc) { 154 return 0; 155 } 156 157 return desc->block.bits; 158 } 159 160 /** 161 * Return bytes per block (not pixel) for the given format. 162 */ 163 static inline unsigned 164 vk_format_get_blocksize(VkFormat format) 165 { 166 unsigned bits = vk_format_get_blocksizebits(format); 167 unsigned bytes = bits / 8; 168 169 assert(bits % 8 == 0); 170 assert(bytes > 0); 171 if (bytes == 0) { 172 bytes = 1; 173 } 174 175 return bytes; 176 } 177 178 static inline unsigned 179 vk_format_get_blockwidth(VkFormat format) 180 { 181 const struct vk_format_description *desc = vk_format_description(format); 182 183 assert(desc); 184 if (!desc) { 185 return 1; 186 } 187 188 return desc->block.width; 189 } 190 191 static inline unsigned 192 vk_format_get_blockheight(VkFormat format) 193 { 194 const struct vk_format_description *desc = vk_format_description(format); 195 196 assert(desc); 197 if (!desc) { 198 return 1; 199 } 200 201 return desc->block.height; 202 } 203 204 /** 205 * Return the index of the first non-void channel 206 * -1 if no non-void channels 207 */ 208 static inline int 209 vk_format_get_first_non_void_channel(VkFormat format) 210 { 211 const struct vk_format_description *desc = vk_format_description(format); 212 int i; 213 214 for (i = 0; i < 4; i++) 215 if (desc->channel[i].type != VK_FORMAT_TYPE_VOID) 216 break; 217 218 if (i == 4) 219 return -1; 220 221 return i; 222 } 223 224 enum vk_swizzle { 225 VK_SWIZZLE_X, 226 VK_SWIZZLE_Y, 227 VK_SWIZZLE_Z, 228 VK_SWIZZLE_W, 229 VK_SWIZZLE_0, 230 VK_SWIZZLE_1, 231 VK_SWIZZLE_NONE, 232 VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */ 233 }; 234 235 static inline VkImageAspectFlags 236 vk_format_aspects(VkFormat format) 237 { 238 switch (format) { 239 case VK_FORMAT_UNDEFINED: 240 return 0; 241 242 case VK_FORMAT_S8_UINT: 243 return VK_IMAGE_ASPECT_STENCIL_BIT; 244 245 case VK_FORMAT_D16_UNORM_S8_UINT: 246 case VK_FORMAT_D24_UNORM_S8_UINT: 247 case VK_FORMAT_D32_SFLOAT_S8_UINT: 248 return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 249 250 case VK_FORMAT_D16_UNORM: 251 case VK_FORMAT_X8_D24_UNORM_PACK32: 252 case VK_FORMAT_D32_SFLOAT: 253 return VK_IMAGE_ASPECT_DEPTH_BIT; 254 255 default: 256 return VK_IMAGE_ASPECT_COLOR_BIT; 257 } 258 } 259 260 static inline enum vk_swizzle 261 radv_swizzle_conv(VkComponentSwizzle component, const unsigned char chan[4], VkComponentSwizzle vk_swiz) 262 { 263 int x; 264 265 if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY) 266 vk_swiz = component; 267 switch (vk_swiz) { 268 case VK_COMPONENT_SWIZZLE_ZERO: 269 return VK_SWIZZLE_0; 270 case VK_COMPONENT_SWIZZLE_ONE: 271 return VK_SWIZZLE_1; 272 case VK_COMPONENT_SWIZZLE_R: 273 for (x = 0; x < 4; x++) 274 if (chan[x] == 0) 275 return x; 276 return VK_SWIZZLE_0; 277 case VK_COMPONENT_SWIZZLE_G: 278 for (x = 0; x < 4; x++) 279 if (chan[x] == 1) 280 return x; 281 return VK_SWIZZLE_0; 282 case VK_COMPONENT_SWIZZLE_B: 283 for (x = 0; x < 4; x++) 284 if (chan[x] == 2) 285 return x; 286 return VK_SWIZZLE_0; 287 case VK_COMPONENT_SWIZZLE_A: 288 for (x = 0; x < 4; x++) 289 if (chan[x] == 3) 290 return x; 291 return VK_SWIZZLE_1; 292 default: 293 unreachable("Illegal swizzle"); 294 } 295 } 296 297 static inline void vk_format_compose_swizzles(const VkComponentMapping *mapping, 298 const unsigned char swz[4], 299 enum vk_swizzle dst[4]) 300 { 301 dst[0] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r); 302 dst[1] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g); 303 dst[2] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b); 304 dst[3] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a); 305 } 306 307 static inline bool 308 vk_format_is_compressed(VkFormat format) 309 { 310 const struct vk_format_description *desc = vk_format_description(format); 311 312 assert(desc); 313 if (!desc) { 314 return false; 315 } 316 317 switch (desc->layout) { 318 case VK_FORMAT_LAYOUT_S3TC: 319 case VK_FORMAT_LAYOUT_RGTC: 320 case VK_FORMAT_LAYOUT_ETC: 321 case VK_FORMAT_LAYOUT_BPTC: 322 case VK_FORMAT_LAYOUT_ASTC: 323 /* XXX add other formats in the future */ 324 return true; 325 default: 326 return false; 327 } 328 } 329 330 static inline bool 331 vk_format_has_depth(const struct vk_format_description *desc) 332 { 333 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS && 334 desc->swizzle[0] != VK_SWIZZLE_NONE; 335 } 336 337 static inline bool 338 vk_format_has_stencil(const struct vk_format_description *desc) 339 { 340 return desc->colorspace == VK_FORMAT_COLORSPACE_ZS && 341 desc->swizzle[1] != VK_SWIZZLE_NONE; 342 } 343 344 static inline bool 345 vk_format_is_depth_or_stencil(VkFormat format) 346 { 347 const struct vk_format_description *desc = vk_format_description(format); 348 349 assert(desc); 350 if (!desc) { 351 return false; 352 } 353 354 return vk_format_has_depth(desc) || 355 vk_format_has_stencil(desc); 356 } 357 358 static inline bool 359 vk_format_is_depth(VkFormat format) 360 { 361 const struct vk_format_description *desc = vk_format_description(format); 362 363 assert(desc); 364 if (!desc) { 365 return false; 366 } 367 368 return vk_format_has_depth(desc); 369 } 370 371 static inline bool 372 vk_format_is_color(VkFormat format) 373 { 374 return !vk_format_is_depth_or_stencil(format); 375 } 376 377 static inline VkFormat 378 vk_format_depth_only(VkFormat format) 379 { 380 switch (format) { 381 case VK_FORMAT_D16_UNORM_S8_UINT: 382 return VK_FORMAT_D16_UNORM; 383 case VK_FORMAT_D24_UNORM_S8_UINT: 384 return VK_FORMAT_X8_D24_UNORM_PACK32; 385 case VK_FORMAT_D32_SFLOAT_S8_UINT: 386 return VK_FORMAT_D32_SFLOAT; 387 default: 388 return format; 389 } 390 } 391 392 static inline bool 393 vk_format_is_int(VkFormat format) 394 { 395 const struct vk_format_description *desc = vk_format_description(format); 396 int channel = vk_format_get_first_non_void_channel(format); 397 398 return channel >= 0 && desc->channel[channel].pure_integer; 399 } 400 401 static inline VkFormat 402 vk_format_stencil_only(VkFormat format) 403 { 404 return VK_FORMAT_S8_UINT; 405 } 406 407 static inline unsigned 408 vk_format_get_component_bits(VkFormat format, 409 enum vk_format_colorspace colorspace, 410 unsigned component) 411 { 412 const struct vk_format_description *desc = vk_format_description(format); 413 enum vk_format_colorspace desc_colorspace; 414 415 assert(format); 416 if (!format) { 417 return 0; 418 } 419 420 assert(component < 4); 421 422 /* Treat RGB and SRGB as equivalent. */ 423 if (colorspace == VK_FORMAT_COLORSPACE_SRGB) { 424 colorspace = VK_FORMAT_COLORSPACE_RGB; 425 } 426 if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) { 427 desc_colorspace = VK_FORMAT_COLORSPACE_RGB; 428 } else { 429 desc_colorspace = desc->colorspace; 430 } 431 432 if (desc_colorspace != colorspace) { 433 return 0; 434 } 435 436 switch (desc->swizzle[component]) { 437 case VK_SWIZZLE_X: 438 return desc->channel[0].size; 439 case VK_SWIZZLE_Y: 440 return desc->channel[1].size; 441 case VK_SWIZZLE_Z: 442 return desc->channel[2].size; 443 case VK_SWIZZLE_W: 444 return desc->channel[3].size; 445 default: 446 return 0; 447 } 448 } 449 #ifdef __cplusplus 450 } // extern "C" { 451 #endif 452