Home | History | Annotate | Download | only in vulkan
      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 #ifndef VK_FORMAT_H
     28 #define VK_FORMAT_H
     29 
     30 #include <assert.h>
     31 #include <vulkan/vulkan.h>
     32 #include <util/macros.h>
     33 
     34 enum vk_format_layout {
     35 	/**
     36 	 * Formats with vk_format_block::width == vk_format_block::height == 1
     37 	 * that can be described as an ordinary data structure.
     38 	 */
     39 	VK_FORMAT_LAYOUT_PLAIN = 0,
     40 
     41 	/**
     42 	 * Formats with sub-sampled channels.
     43 	 *
     44 	 * This is for formats like YVYU where there is less than one sample per
     45 	 * pixel.
     46 	 */
     47 	VK_FORMAT_LAYOUT_SUBSAMPLED = 3,
     48 
     49 	/**
     50 	 * S3 Texture Compression formats.
     51 	 */
     52 	VK_FORMAT_LAYOUT_S3TC = 4,
     53 
     54 	/**
     55 	 * Red-Green Texture Compression formats.
     56 	 */
     57 	VK_FORMAT_LAYOUT_RGTC = 5,
     58 
     59 	/**
     60 	 * Ericsson Texture Compression
     61 	 */
     62 	VK_FORMAT_LAYOUT_ETC = 6,
     63 
     64 	/**
     65 	 * BC6/7 Texture Compression
     66 	 */
     67 	VK_FORMAT_LAYOUT_BPTC = 7,
     68 
     69 	/**
     70 	 * ASTC
     71 	 */
     72 	VK_FORMAT_LAYOUT_ASTC = 8,
     73 
     74 	/**
     75 	 * Everything else that doesn't fit in any of the above layouts.
     76 	 */
     77 	VK_FORMAT_LAYOUT_OTHER = 9
     78 };
     79 
     80 struct vk_format_block
     81 {
     82 	/** Block width in pixels */
     83 	unsigned width;
     84 
     85 	/** Block height in pixels */
     86 	unsigned height;
     87 
     88 	/** Block size in bits */
     89 	unsigned bits;
     90 };
     91 
     92 enum vk_format_type {
     93 	VK_FORMAT_TYPE_VOID = 0,
     94 	VK_FORMAT_TYPE_UNSIGNED = 1,
     95 	VK_FORMAT_TYPE_SIGNED = 2,
     96 	VK_FORMAT_TYPE_FIXED = 3,
     97 	VK_FORMAT_TYPE_FLOAT = 4
     98 };
     99 
    100 
    101 enum vk_format_colorspace {
    102 	VK_FORMAT_COLORSPACE_RGB = 0,
    103 	VK_FORMAT_COLORSPACE_SRGB = 1,
    104 	VK_FORMAT_COLORSPACE_YUV = 2,
    105 	VK_FORMAT_COLORSPACE_ZS = 3
    106 };
    107 
    108 struct vk_format_channel_description {
    109 	unsigned type:5;
    110 	unsigned normalized:1;
    111 	unsigned pure_integer:1;
    112 	unsigned scaled:1;
    113 	unsigned size:8;
    114 	unsigned shift:16;
    115 };
    116 
    117 struct vk_format_description
    118 {
    119 	VkFormat format;
    120 	const char *name;
    121 	const char *short_name;
    122 
    123 	struct vk_format_block block;
    124 	enum vk_format_layout layout;
    125 
    126 	unsigned nr_channels:3;
    127 	unsigned is_array:1;
    128 	unsigned is_bitmask:1;
    129 	unsigned is_mixed:1;
    130 
    131 	struct vk_format_channel_description channel[4];
    132 
    133 	unsigned char swizzle[4];
    134 
    135 	enum vk_format_colorspace colorspace;
    136 };
    137 
    138 extern const struct vk_format_description vk_format_description_table[];
    139 
    140 const struct vk_format_description *vk_format_description(VkFormat format);
    141 
    142 /**
    143  * Return total bits needed for the pixel format per block.
    144  */
    145 static inline unsigned
    146 vk_format_get_blocksizebits(VkFormat format)
    147 {
    148 	const struct vk_format_description *desc = vk_format_description(format);
    149 
    150 	assert(desc);
    151 	if (!desc) {
    152 		return 0;
    153 	}
    154 
    155 	return desc->block.bits;
    156 }
    157 
    158 /**
    159  * Return bytes per block (not pixel) for the given format.
    160  */
    161 static inline unsigned
    162 vk_format_get_blocksize(VkFormat format)
    163 {
    164 	unsigned bits = vk_format_get_blocksizebits(format);
    165 	unsigned bytes = bits / 8;
    166 
    167 	assert(bits % 8 == 0);
    168 	assert(bytes > 0);
    169 	if (bytes == 0) {
    170 		bytes = 1;
    171 	}
    172 
    173 	return bytes;
    174 }
    175 
    176 static inline unsigned
    177 vk_format_get_blockwidth(VkFormat format)
    178 {
    179 	const struct vk_format_description *desc = vk_format_description(format);
    180 
    181 	assert(desc);
    182 	if (!desc) {
    183 		return 1;
    184 	}
    185 
    186 	return desc->block.width;
    187 }
    188 
    189 static inline unsigned
    190 vk_format_get_blockheight(VkFormat format)
    191 {
    192 	const struct vk_format_description *desc = vk_format_description(format);
    193 
    194 	assert(desc);
    195 	if (!desc) {
    196 		return 1;
    197 	}
    198 
    199 	return desc->block.height;
    200 }
    201 
    202 /**
    203  * Return the index of the first non-void channel
    204  * -1 if no non-void channels
    205  */
    206 static inline int
    207 vk_format_get_first_non_void_channel(VkFormat format)
    208 {
    209 	const struct vk_format_description *desc = vk_format_description(format);
    210 	int i;
    211 
    212 	for (i = 0; i < 4; i++)
    213 		if (desc->channel[i].type != VK_FORMAT_TYPE_VOID)
    214 			break;
    215 
    216 	if (i == 4)
    217 		return -1;
    218 
    219 	return i;
    220 }
    221 
    222 enum vk_swizzle {
    223 	VK_SWIZZLE_X,
    224 	VK_SWIZZLE_Y,
    225 	VK_SWIZZLE_Z,
    226 	VK_SWIZZLE_W,
    227 	VK_SWIZZLE_0,
    228 	VK_SWIZZLE_1,
    229 	VK_SWIZZLE_NONE,
    230 	VK_SWIZZLE_MAX, /**< Number of enums counter (must be last) */
    231 };
    232 
    233 static inline VkImageAspectFlags
    234 vk_format_aspects(VkFormat format)
    235 {
    236 	switch (format) {
    237 	case VK_FORMAT_UNDEFINED:
    238 		return 0;
    239 
    240 	case VK_FORMAT_S8_UINT:
    241 		return VK_IMAGE_ASPECT_STENCIL_BIT;
    242 
    243 	case VK_FORMAT_D16_UNORM_S8_UINT:
    244 	case VK_FORMAT_D24_UNORM_S8_UINT:
    245 	case VK_FORMAT_D32_SFLOAT_S8_UINT:
    246 		return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
    247 
    248 	case VK_FORMAT_D16_UNORM:
    249 	case VK_FORMAT_X8_D24_UNORM_PACK32:
    250 	case VK_FORMAT_D32_SFLOAT:
    251 		return VK_IMAGE_ASPECT_DEPTH_BIT;
    252 
    253 	default:
    254 		return VK_IMAGE_ASPECT_COLOR_BIT;
    255 	}
    256 }
    257 
    258 static inline enum vk_swizzle
    259 radv_swizzle_conv(VkComponentSwizzle component, const unsigned char chan[4], VkComponentSwizzle vk_swiz)
    260 {
    261 	int x;
    262 
    263 	if (vk_swiz == VK_COMPONENT_SWIZZLE_IDENTITY)
    264 		vk_swiz = component;
    265 	switch (vk_swiz) {
    266 	case VK_COMPONENT_SWIZZLE_ZERO:
    267 		return VK_SWIZZLE_0;
    268 	case VK_COMPONENT_SWIZZLE_ONE:
    269 		return VK_SWIZZLE_1;
    270 	case VK_COMPONENT_SWIZZLE_R:
    271 		for (x = 0; x < 4; x++)
    272 			if (chan[x] == 0)
    273 				return x;
    274 		return VK_SWIZZLE_0;
    275 	case VK_COMPONENT_SWIZZLE_G:
    276 		for (x = 0; x < 4; x++)
    277 			if (chan[x] == 1)
    278 				return x;
    279 		return VK_SWIZZLE_0;
    280 	case VK_COMPONENT_SWIZZLE_B:
    281 		for (x = 0; x < 4; x++)
    282 			if (chan[x] == 2)
    283 				return x;
    284 		return VK_SWIZZLE_0;
    285 	case VK_COMPONENT_SWIZZLE_A:
    286 		for (x = 0; x < 4; x++)
    287 			if (chan[x] == 3)
    288 				return x;
    289 		return VK_SWIZZLE_1;
    290 	default:
    291 		unreachable("Illegal swizzle");
    292 	}
    293 }
    294 
    295 static inline void vk_format_compose_swizzles(const VkComponentMapping *mapping,
    296 					      const unsigned char swz[4],
    297 					      enum vk_swizzle dst[4])
    298 {
    299 	dst[0] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_R, swz, mapping->r);
    300 	dst[1] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_G, swz, mapping->g);
    301 	dst[2] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_B, swz, mapping->b);
    302 	dst[3] = radv_swizzle_conv(VK_COMPONENT_SWIZZLE_A, swz, mapping->a);
    303 }
    304 
    305 static inline bool
    306 vk_format_is_compressed(VkFormat format)
    307 {
    308 	const struct vk_format_description *desc = vk_format_description(format);
    309 
    310 	assert(desc);
    311 	if (!desc) {
    312 		return false;
    313 	}
    314 
    315 	switch (desc->layout) {
    316 	case VK_FORMAT_LAYOUT_S3TC:
    317 	case VK_FORMAT_LAYOUT_RGTC:
    318 	case VK_FORMAT_LAYOUT_ETC:
    319 	case VK_FORMAT_LAYOUT_BPTC:
    320 	case VK_FORMAT_LAYOUT_ASTC:
    321 		/* XXX add other formats in the future */
    322 		return true;
    323 	default:
    324 		return false;
    325 	}
    326 }
    327 
    328 static inline bool
    329 vk_format_has_depth(const struct vk_format_description *desc)
    330 {
    331 	return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
    332 		desc->swizzle[0] != VK_SWIZZLE_NONE;
    333 }
    334 
    335 static inline bool
    336 vk_format_has_stencil(const struct vk_format_description *desc)
    337 {
    338 	return desc->colorspace == VK_FORMAT_COLORSPACE_ZS &&
    339 		desc->swizzle[1] != VK_SWIZZLE_NONE;
    340 }
    341 
    342 static inline bool
    343 vk_format_is_depth_or_stencil(VkFormat format)
    344 {
    345 	const struct vk_format_description *desc = vk_format_description(format);
    346 
    347 	assert(desc);
    348 	if (!desc) {
    349 		return false;
    350 	}
    351 
    352 	return vk_format_has_depth(desc) ||
    353 		vk_format_has_stencil(desc);
    354 }
    355 
    356 static inline bool
    357 vk_format_is_depth(VkFormat format)
    358 {
    359 	const struct vk_format_description *desc = vk_format_description(format);
    360 
    361 	assert(desc);
    362 	if (!desc) {
    363 		return false;
    364 	}
    365 
    366 	return vk_format_has_depth(desc);
    367 }
    368 
    369 static inline bool
    370 vk_format_is_stencil(VkFormat format)
    371 {
    372 	const struct vk_format_description *desc = vk_format_description(format);
    373 
    374 	assert(desc);
    375 	if (!desc) {
    376 		return false;
    377 	}
    378 
    379 	return vk_format_has_stencil(desc);
    380 }
    381 
    382 static inline bool
    383 vk_format_is_color(VkFormat format)
    384 {
    385 	return !vk_format_is_depth_or_stencil(format);
    386 }
    387 
    388 static inline VkFormat
    389 vk_format_depth_only(VkFormat format)
    390 {
    391 	switch (format) {
    392 	case VK_FORMAT_D16_UNORM_S8_UINT:
    393 		return VK_FORMAT_D16_UNORM;
    394 	case VK_FORMAT_D24_UNORM_S8_UINT:
    395 		return VK_FORMAT_X8_D24_UNORM_PACK32;
    396 	case VK_FORMAT_D32_SFLOAT_S8_UINT:
    397 		return VK_FORMAT_D32_SFLOAT;
    398 	default:
    399 		return format;
    400 	}
    401 }
    402 
    403 static inline bool
    404 vk_format_is_int(VkFormat format)
    405 {
    406 	const struct vk_format_description *desc = vk_format_description(format);
    407 	int channel =  vk_format_get_first_non_void_channel(format);
    408 
    409 	return channel >= 0 && desc->channel[channel].pure_integer;
    410 }
    411 
    412 static inline bool
    413 vk_format_is_srgb(VkFormat format)
    414 {
    415 	const struct vk_format_description *desc = vk_format_description(format);
    416 	return desc->colorspace == VK_FORMAT_COLORSPACE_SRGB;
    417 }
    418 
    419 static inline VkFormat
    420 vk_format_stencil_only(VkFormat format)
    421 {
    422 	return VK_FORMAT_S8_UINT;
    423 }
    424 
    425 static inline unsigned
    426 vk_format_get_component_bits(VkFormat format,
    427 			     enum vk_format_colorspace colorspace,
    428 			     unsigned component)
    429 {
    430 	const struct vk_format_description *desc = vk_format_description(format);
    431 	enum vk_format_colorspace desc_colorspace;
    432 
    433 	assert(format);
    434 	if (!format) {
    435 		return 0;
    436 	}
    437 
    438 	assert(component < 4);
    439 
    440 	/* Treat RGB and SRGB as equivalent. */
    441 	if (colorspace == VK_FORMAT_COLORSPACE_SRGB) {
    442 		colorspace = VK_FORMAT_COLORSPACE_RGB;
    443 	}
    444 	if (desc->colorspace == VK_FORMAT_COLORSPACE_SRGB) {
    445 		desc_colorspace = VK_FORMAT_COLORSPACE_RGB;
    446 	} else {
    447 		desc_colorspace = desc->colorspace;
    448 	}
    449 
    450 	if (desc_colorspace != colorspace) {
    451 		return 0;
    452 	}
    453 
    454 	switch (desc->swizzle[component]) {
    455 	case VK_SWIZZLE_X:
    456 		return desc->channel[0].size;
    457 	case VK_SWIZZLE_Y:
    458 		return desc->channel[1].size;
    459 	case VK_SWIZZLE_Z:
    460 		return desc->channel[2].size;
    461 	case VK_SWIZZLE_W:
    462 		return desc->channel[3].size;
    463 	default:
    464 		return 0;
    465 	}
    466 }
    467 
    468 static inline VkFormat
    469 vk_to_non_srgb_format(VkFormat format)
    470 {
    471 	switch(format) {
    472 	case VK_FORMAT_R8_SRGB :
    473 		return VK_FORMAT_R8_UNORM;
    474 	case VK_FORMAT_R8G8_SRGB:
    475 		return VK_FORMAT_R8G8_UNORM;
    476 	case VK_FORMAT_R8G8B8_SRGB:
    477 		return VK_FORMAT_R8G8B8_UNORM;
    478 	case VK_FORMAT_B8G8R8_SRGB:
    479 		return VK_FORMAT_B8G8R8_UNORM;
    480 	case VK_FORMAT_R8G8B8A8_SRGB :
    481 		return VK_FORMAT_R8G8B8A8_UNORM;
    482 	case VK_FORMAT_B8G8R8A8_SRGB:
    483 		return VK_FORMAT_B8G8R8A8_UNORM;
    484 	case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
    485 		return VK_FORMAT_A8B8G8R8_UNORM_PACK32;
    486 	default:
    487 		return format;
    488 	}
    489 }
    490 
    491 #endif /* VK_FORMAT_H */
    492