u_format.h revision 4afae877e6914e311340e0b1d3490ec2fed9422f
1/************************************************************************** 2 * 3 * Copyright 2009-2010 Vmware, Inc. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 29#ifndef U_FORMAT_H 30#define U_FORMAT_H 31 32 33#include "pipe/p_format.h" 34#include "util/u_debug.h" 35 36#ifdef __cplusplus 37extern "C" { 38#endif 39 40 41/** 42 * Describe how to pack/unpack pixels into/from the prescribed format. 43 * 44 * XXX: This could be renamed to something like util_format_pack, or broke down 45 * in flags inside util_format_block that said exactly what we want. 46 */ 47enum util_format_layout { 48 /** 49 * Formats with util_format_block::width == util_format_block::height == 1 50 * that can be described as an ordinary data structure. 51 */ 52 UTIL_FORMAT_LAYOUT_PLAIN = 0, 53 54 /** 55 * Formats with sub-sampled channels. 56 * 57 * This is for formats like YV12 where there is less than one sample per 58 * pixel. 59 * 60 * XXX: This could actually b 61 */ 62 UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, 63 64 /** 65 * An unspecified compression algorithm. 66 */ 67 UTIL_FORMAT_LAYOUT_COMPRESSED = 4 68}; 69 70 71struct util_format_block 72{ 73 /** Block width in pixels */ 74 unsigned width; 75 76 /** Block height in pixels */ 77 unsigned height; 78 79 /** Block size in bits */ 80 unsigned bits; 81}; 82 83 84enum util_format_type { 85 UTIL_FORMAT_TYPE_VOID = 0, 86 UTIL_FORMAT_TYPE_UNSIGNED = 1, 87 UTIL_FORMAT_TYPE_SIGNED = 2, 88 UTIL_FORMAT_TYPE_FIXED = 3, 89 UTIL_FORMAT_TYPE_FLOAT = 4 90}; 91 92 93enum util_format_swizzle { 94 UTIL_FORMAT_SWIZZLE_X = 0, 95 UTIL_FORMAT_SWIZZLE_Y = 1, 96 UTIL_FORMAT_SWIZZLE_Z = 2, 97 UTIL_FORMAT_SWIZZLE_W = 3, 98 UTIL_FORMAT_SWIZZLE_0 = 4, 99 UTIL_FORMAT_SWIZZLE_1 = 5, 100 UTIL_FORMAT_SWIZZLE_NONE = 6 101}; 102 103 104enum util_format_colorspace { 105 UTIL_FORMAT_COLORSPACE_RGB = 0, 106 UTIL_FORMAT_COLORSPACE_SRGB = 1, 107 UTIL_FORMAT_COLORSPACE_YUV = 2, 108 UTIL_FORMAT_COLORSPACE_ZS = 3 109}; 110 111 112struct util_format_channel_description 113{ 114 unsigned type:6; 115 unsigned normalized:1; 116 unsigned size:9; 117}; 118 119 120struct util_format_description 121{ 122 enum pipe_format format; 123 124 const char *name; 125 126 /** 127 * Short name, striped of the prefix, lower case. 128 */ 129 const char *short_name; 130 131 /** 132 * Pixel block dimensions. 133 */ 134 struct util_format_block block; 135 136 enum util_format_layout layout; 137 138 /** 139 * The number of channels. 140 */ 141 unsigned nr_channels:3; 142 143 /** 144 * Whether all channels have the same number of (whole) bytes. 145 */ 146 unsigned is_array:1; 147 148 /** 149 * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID). 150 */ 151 unsigned is_mixed:1; 152 153 /** 154 * Input channel description. 155 * 156 * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. 157 */ 158 struct util_format_channel_description channel[4]; 159 160 /** 161 * Output channel swizzle. 162 * 163 * The order is either: 164 * - RGBA 165 * - YUV(A) 166 * - ZS 167 * depending on the colorspace. 168 */ 169 unsigned char swizzle[4]; 170 171 /** 172 * Colorspace transformation. 173 */ 174 enum util_format_colorspace colorspace; 175}; 176 177 178extern const struct util_format_description 179util_format_description_table[]; 180 181 182const struct util_format_description * 183util_format_description(enum pipe_format format); 184 185 186/* 187 * Format query functions. 188 */ 189 190static INLINE const char * 191util_format_name(enum pipe_format format) 192{ 193 const struct util_format_description *desc = util_format_description(format); 194 195 assert(format); 196 if (!format) { 197 return "???"; 198 } 199 200 return desc->name; 201} 202 203static INLINE boolean 204util_format_is_compressed(enum pipe_format format) 205{ 206 const struct util_format_description *desc = util_format_description(format); 207 208 assert(format); 209 if (!format) { 210 return FALSE; 211 } 212 213 return desc->layout == UTIL_FORMAT_LAYOUT_COMPRESSED ? TRUE : FALSE; 214} 215 216static INLINE boolean 217util_format_is_depth_or_stencil(enum pipe_format format) 218{ 219 const struct util_format_description *desc = util_format_description(format); 220 221 assert(format); 222 if (!format) { 223 return FALSE; 224 } 225 226 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; 227} 228 229static INLINE boolean 230util_format_is_depth_and_stencil(enum pipe_format format) 231{ 232 const struct util_format_description *desc = util_format_description(format); 233 234 assert(format); 235 if (!format) { 236 return FALSE; 237 } 238 239 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { 240 return FALSE; 241 } 242 243 return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && 244 desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; 245} 246 247 248/** 249 * Return total bits needed for the pixel format per block. 250 */ 251static INLINE uint 252util_format_get_blocksizebits(enum pipe_format format) 253{ 254 const struct util_format_description *desc = util_format_description(format); 255 256 assert(format); 257 if (!format) { 258 return 0; 259 } 260 261 return desc->block.bits; 262} 263 264/** 265 * Return bytes per block (not pixel) for the given format. 266 */ 267static INLINE uint 268util_format_get_blocksize(enum pipe_format format) 269{ 270 uint bits = util_format_get_blocksizebits(format); 271 272 assert(bits % 8 == 0); 273 274 return bits / 8; 275} 276 277static INLINE uint 278util_format_get_blockwidth(enum pipe_format format) 279{ 280 const struct util_format_description *desc = util_format_description(format); 281 282 assert(format); 283 if (!format) { 284 return 1; 285 } 286 287 return desc->block.width; 288} 289 290static INLINE uint 291util_format_get_blockheight(enum pipe_format format) 292{ 293 const struct util_format_description *desc = util_format_description(format); 294 295 assert(format); 296 if (!format) { 297 return 1; 298 } 299 300 return desc->block.height; 301} 302 303static INLINE unsigned 304util_format_get_nblocksx(enum pipe_format format, 305 unsigned x) 306{ 307 unsigned blockwidth = util_format_get_blockwidth(format); 308 return (x + blockwidth - 1) / blockwidth; 309} 310 311static INLINE unsigned 312util_format_get_nblocksy(enum pipe_format format, 313 unsigned y) 314{ 315 unsigned blockheight = util_format_get_blockheight(format); 316 return (y + blockheight - 1) / blockheight; 317} 318 319static INLINE unsigned 320util_format_get_nblocks(enum pipe_format format, 321 unsigned width, 322 unsigned height) 323{ 324 return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); 325} 326 327static INLINE size_t 328util_format_get_stride(enum pipe_format format, 329 unsigned width) 330{ 331 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); 332} 333 334static INLINE size_t 335util_format_get_2d_size(enum pipe_format format, 336 size_t stride, 337 unsigned height) 338{ 339 return util_format_get_nblocksy(format, height) * stride; 340} 341 342static INLINE uint 343util_format_get_component_bits(enum pipe_format format, 344 enum util_format_colorspace colorspace, 345 uint component) 346{ 347 const struct util_format_description *desc = util_format_description(format); 348 enum util_format_colorspace desc_colorspace; 349 350 assert(format); 351 if (!format) { 352 return 0; 353 } 354 355 assert(component < 4); 356 357 /* Treat RGB and SRGB as equivalent. */ 358 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 359 colorspace = UTIL_FORMAT_COLORSPACE_RGB; 360 } 361 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 362 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; 363 } else { 364 desc_colorspace = desc->colorspace; 365 } 366 367 if (desc_colorspace != colorspace) { 368 return 0; 369 } 370 371 switch (desc->swizzle[component]) { 372 case UTIL_FORMAT_SWIZZLE_X: 373 return desc->channel[0].size; 374 case UTIL_FORMAT_SWIZZLE_Y: 375 return desc->channel[1].size; 376 case UTIL_FORMAT_SWIZZLE_Z: 377 return desc->channel[2].size; 378 case UTIL_FORMAT_SWIZZLE_W: 379 return desc->channel[3].size; 380 default: 381 return 0; 382 } 383} 384 385static INLINE boolean 386util_format_has_alpha(enum pipe_format format) 387{ 388 const struct util_format_description *desc = util_format_description(format); 389 390 assert(format); 391 if (!format) { 392 return FALSE; 393 } 394 395 switch (desc->colorspace) { 396 case UTIL_FORMAT_COLORSPACE_RGB: 397 case UTIL_FORMAT_COLORSPACE_SRGB: 398 return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1; 399 case UTIL_FORMAT_COLORSPACE_YUV: 400 return FALSE; 401 case UTIL_FORMAT_COLORSPACE_ZS: 402 return FALSE; 403 default: 404 assert(0); 405 return FALSE; 406 } 407} 408 409 410/* 411 * Format access functions. 412 */ 413 414void 415util_format_read_4f(enum pipe_format format, 416 float *dst, unsigned dst_stride, 417 const void *src, unsigned src_stride, 418 unsigned x, unsigned y, unsigned w, unsigned h); 419 420void 421util_format_write_4f(enum pipe_format format, 422 const float *src, unsigned src_stride, 423 void *dst, unsigned dst_stride, 424 unsigned x, unsigned y, unsigned w, unsigned h); 425 426void 427util_format_read_4ub(enum pipe_format format, 428 uint8_t *dst, unsigned dst_stride, 429 const void *src, unsigned src_stride, 430 unsigned x, unsigned y, unsigned w, unsigned h); 431 432void 433util_format_write_4ub(enum pipe_format format, 434 const uint8_t *src, unsigned src_stride, 435 void *dst, unsigned dst_stride, 436 unsigned x, unsigned y, unsigned w, unsigned h); 437 438#ifdef __cplusplus 439} // extern "C" { 440#endif 441 442#endif /* ! U_FORMAT_H */ 443