u_format.h revision b8684b2458bc9bdcfd6b43dc7c2b8c2d485105fd
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 UTIL_FORMAT_LAYOUT_SUBSAMPLED = 3, 61 62 /** 63 * S3 Texture Compression formats. 64 */ 65 UTIL_FORMAT_LAYOUT_S3TC = 4, 66 67 /** 68 * Red-Green Texture Compression formats. 69 */ 70 UTIL_FORMAT_LAYOUT_RGTC = 5, 71 72 /** 73 * Everything else that doesn't fit in any of the above layouts. 74 */ 75 UTIL_FORMAT_LAYOUT_OTHER = 6 76}; 77 78 79struct util_format_block 80{ 81 /** Block width in pixels */ 82 unsigned width; 83 84 /** Block height in pixels */ 85 unsigned height; 86 87 /** Block size in bits */ 88 unsigned bits; 89}; 90 91 92enum util_format_type { 93 UTIL_FORMAT_TYPE_VOID = 0, 94 UTIL_FORMAT_TYPE_UNSIGNED = 1, 95 UTIL_FORMAT_TYPE_SIGNED = 2, 96 UTIL_FORMAT_TYPE_FIXED = 3, 97 UTIL_FORMAT_TYPE_FLOAT = 4 98}; 99 100 101enum util_format_swizzle { 102 UTIL_FORMAT_SWIZZLE_X = 0, 103 UTIL_FORMAT_SWIZZLE_Y = 1, 104 UTIL_FORMAT_SWIZZLE_Z = 2, 105 UTIL_FORMAT_SWIZZLE_W = 3, 106 UTIL_FORMAT_SWIZZLE_0 = 4, 107 UTIL_FORMAT_SWIZZLE_1 = 5, 108 UTIL_FORMAT_SWIZZLE_NONE = 6 109}; 110 111 112enum util_format_colorspace { 113 UTIL_FORMAT_COLORSPACE_RGB = 0, 114 UTIL_FORMAT_COLORSPACE_SRGB = 1, 115 UTIL_FORMAT_COLORSPACE_YUV = 2, 116 UTIL_FORMAT_COLORSPACE_ZS = 3 117}; 118 119 120struct util_format_channel_description 121{ 122 unsigned type:6; 123 unsigned normalized:1; 124 unsigned size:9; 125}; 126 127 128struct util_format_description 129{ 130 enum pipe_format format; 131 132 const char *name; 133 134 /** 135 * Short name, striped of the prefix, lower case. 136 */ 137 const char *short_name; 138 139 /** 140 * Pixel block dimensions. 141 */ 142 struct util_format_block block; 143 144 enum util_format_layout layout; 145 146 /** 147 * The number of channels. 148 */ 149 unsigned nr_channels:3; 150 151 /** 152 * Whether all channels have the same number of (whole) bytes. 153 */ 154 unsigned is_array:1; 155 156 /** 157 * Whether the pixel format can be described as a bitfield structure. 158 * 159 * In particular: 160 * - pixel depth must be 8, 16, or 32 bits; 161 * - all channels must be unsigned, signed, or void 162 */ 163 unsigned is_bitmask:1; 164 165 /** 166 * Whether channels have mixed types (ignoring UTIL_FORMAT_TYPE_VOID). 167 */ 168 unsigned is_mixed:1; 169 170 /** 171 * Input channel description. 172 * 173 * Only valid for UTIL_FORMAT_LAYOUT_PLAIN formats. 174 */ 175 struct util_format_channel_description channel[4]; 176 177 /** 178 * Output channel swizzle. 179 * 180 * The order is either: 181 * - RGBA 182 * - YUV(A) 183 * - ZS 184 * depending on the colorspace. 185 */ 186 unsigned char swizzle[4]; 187 188 /** 189 * Colorspace transformation. 190 */ 191 enum util_format_colorspace colorspace; 192 193 /** 194 * Unpack pixel blocks to R8G8B8A8_UNORM. 195 * Note: strides are in bytes. 196 * 197 * Only defined for non-depth-stencil formats. 198 */ 199 void 200 (*unpack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, 201 const uint8_t *src, unsigned src_stride, 202 unsigned width, unsigned height); 203 204 /** 205 * Pack pixel blocks from R8G8B8A8_UNORM. 206 * Note: strides are in bytes. 207 * 208 * Only defined for non-depth-stencil formats. 209 */ 210 void 211 (*pack_rgba_8unorm)(uint8_t *dst, unsigned dst_stride, 212 const uint8_t *src, unsigned src_stride, 213 unsigned width, unsigned height); 214 215 /** 216 * Fetch a single pixel (i, j) from a block. 217 * 218 * XXX: Only defined for a very few select formats. 219 */ 220 void 221 (*fetch_rgba_8unorm)(uint8_t *dst, 222 const uint8_t *src, 223 unsigned i, unsigned j); 224 225 /** 226 * Unpack pixel blocks to R32G32B32A32_FLOAT. 227 * Note: strides are in bytes. 228 * 229 * Only defined for non-depth-stencil formats. 230 */ 231 void 232 (*unpack_rgba_float)(float *dst, unsigned dst_stride, 233 const uint8_t *src, unsigned src_stride, 234 unsigned width, unsigned height); 235 236 /** 237 * Pack pixel blocks from R32G32B32A32_FLOAT. 238 * Note: strides are in bytes. 239 * 240 * Only defined for non-depth-stencil formats. 241 */ 242 void 243 (*pack_rgba_float)(uint8_t *dst, unsigned dst_stride, 244 const float *src, unsigned src_stride, 245 unsigned width, unsigned height); 246 247 /** 248 * Fetch a single pixel (i, j) from a block. 249 * 250 * Only defined for non-depth-stencil formats. 251 */ 252 void 253 (*fetch_rgba_float)(float *dst, 254 const uint8_t *src, 255 unsigned i, unsigned j); 256 257 /** 258 * Unpack pixels to Z32_UNORM. 259 * Note: strides are in bytes. 260 * 261 * Only defined for depth formats. 262 */ 263 void 264 (*unpack_z_32unorm)(uint32_t *dst, unsigned dst_stride, 265 const uint8_t *src, unsigned src_stride, 266 unsigned width, unsigned height); 267 268 /** 269 * Pack pixels from Z32_FLOAT. 270 * Note: strides are in bytes. 271 * 272 * Only defined for depth formats. 273 */ 274 void 275 (*pack_z_32unorm)(uint8_t *dst, unsigned dst_stride, 276 const uint32_t *src, unsigned src_stride, 277 unsigned width, unsigned height); 278 279 /** 280 * Unpack pixels to Z32_FLOAT. 281 * Note: strides are in bytes. 282 * 283 * Only defined for depth formats. 284 */ 285 void 286 (*unpack_z_float)(float *dst, unsigned dst_stride, 287 const uint8_t *src, unsigned src_stride, 288 unsigned width, unsigned height); 289 290 /** 291 * Pack pixels from Z32_FLOAT. 292 * Note: strides are in bytes. 293 * 294 * Only defined for depth formats. 295 */ 296 void 297 (*pack_z_float)(uint8_t *dst, unsigned dst_stride, 298 const float *src, unsigned src_stride, 299 unsigned width, unsigned height); 300 301 /** 302 * Unpack pixels to S8_USCALED. 303 * Note: strides are in bytes. 304 * 305 * Only defined for stencil formats. 306 */ 307 void 308 (*unpack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, 309 const uint8_t *src, unsigned src_stride, 310 unsigned width, unsigned height); 311 312 /** 313 * Pack pixels from S8_USCALED. 314 * Note: strides are in bytes. 315 * 316 * Only defined for stencil formats. 317 */ 318 void 319 (*pack_s_8uscaled)(uint8_t *dst, unsigned dst_stride, 320 const uint8_t *src, unsigned src_stride, 321 unsigned width, unsigned height); 322 323}; 324 325 326extern const struct util_format_description 327util_format_description_table[]; 328 329 330const struct util_format_description * 331util_format_description(enum pipe_format format); 332 333 334/* 335 * Format query functions. 336 */ 337 338static INLINE const char * 339util_format_name(enum pipe_format format) 340{ 341 const struct util_format_description *desc = util_format_description(format); 342 343 assert(desc); 344 if (!desc) { 345 return "PIPE_FORMAT_???"; 346 } 347 348 return desc->name; 349} 350 351static INLINE const char * 352util_format_short_name(enum pipe_format format) 353{ 354 const struct util_format_description *desc = util_format_description(format); 355 356 assert(desc); 357 if (!desc) { 358 return "???"; 359 } 360 361 return desc->short_name; 362} 363 364/** 365 * Whether this format is plain, see UTIL_FORMAT_LAYOUT_PLAIN for more info. 366 */ 367static INLINE boolean 368util_format_is_plain(enum pipe_format format) 369{ 370 const struct util_format_description *desc = util_format_description(format); 371 372 if (!format) { 373 return FALSE; 374 } 375 376 return desc->layout == UTIL_FORMAT_LAYOUT_PLAIN ? TRUE : FALSE; 377} 378 379static INLINE boolean 380util_format_is_compressed(enum pipe_format format) 381{ 382 const struct util_format_description *desc = util_format_description(format); 383 384 assert(desc); 385 if (!desc) { 386 return FALSE; 387 } 388 389 switch (desc->layout) { 390 case UTIL_FORMAT_LAYOUT_S3TC: 391 case UTIL_FORMAT_LAYOUT_RGTC: 392 /* XXX add other formats in the future */ 393 return TRUE; 394 default: 395 return FALSE; 396 } 397} 398 399static INLINE boolean 400util_format_is_s3tc(enum pipe_format format) 401{ 402 const struct util_format_description *desc = util_format_description(format); 403 404 assert(desc); 405 if (!desc) { 406 return FALSE; 407 } 408 409 return desc->layout == UTIL_FORMAT_LAYOUT_S3TC ? TRUE : FALSE; 410} 411 412static INLINE boolean 413util_format_is_depth_or_stencil(enum pipe_format format) 414{ 415 const struct util_format_description *desc = util_format_description(format); 416 417 assert(desc); 418 if (!desc) { 419 return FALSE; 420 } 421 422 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; 423} 424 425static INLINE boolean 426util_format_is_depth_and_stencil(enum pipe_format format) 427{ 428 const struct util_format_description *desc = util_format_description(format); 429 430 assert(desc); 431 if (!desc) { 432 return FALSE; 433 } 434 435 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { 436 return FALSE; 437 } 438 439 return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && 440 desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; 441} 442 443 444/** 445 * Give the RGBA colormask of the channels that can be represented in this 446 * format. 447 * 448 * That is, the channels whose values are preserved. 449 */ 450static INLINE unsigned 451util_format_colormask(const struct util_format_description *desc) 452{ 453 unsigned colormask; 454 unsigned chan; 455 456 switch (desc->colorspace) { 457 case UTIL_FORMAT_COLORSPACE_RGB: 458 case UTIL_FORMAT_COLORSPACE_SRGB: 459 case UTIL_FORMAT_COLORSPACE_YUV: 460 colormask = 0; 461 for (chan = 0; chan < 4; ++chan) { 462 if (desc->swizzle[chan] < 4) { 463 colormask |= (1 << chan); 464 } 465 } 466 return colormask; 467 case UTIL_FORMAT_COLORSPACE_ZS: 468 return 0; 469 default: 470 assert(0); 471 return 0; 472 } 473} 474 475 476/** 477 * Whether the src format can be blitted to destation format with a simple 478 * memcpy. 479 */ 480boolean 481util_is_format_compatible(const struct util_format_description *src_desc, 482 const struct util_format_description *dst_desc); 483 484 485/** 486 * Whether this format is a rgab8 variant. 487 * 488 * That is, any format that matches the 489 * 490 * PIPE_FORMAT_?8?8?8?8_UNORM 491 */ 492static INLINE boolean 493util_format_is_rgba8_variant(const struct util_format_description *desc) 494{ 495 unsigned chan; 496 497 if(desc->block.width != 1 || 498 desc->block.height != 1 || 499 desc->block.bits != 32) 500 return FALSE; 501 502 for(chan = 0; chan < 4; ++chan) { 503 if(desc->channel[chan].type != UTIL_FORMAT_TYPE_UNSIGNED && 504 desc->channel[chan].type != UTIL_FORMAT_TYPE_VOID) 505 return FALSE; 506 if(desc->channel[chan].size != 8) 507 return FALSE; 508 } 509 510 return TRUE; 511} 512 513 514/** 515 * Return total bits needed for the pixel format per block. 516 */ 517static INLINE uint 518util_format_get_blocksizebits(enum pipe_format format) 519{ 520 const struct util_format_description *desc = util_format_description(format); 521 522 assert(desc); 523 if (!desc) { 524 return 0; 525 } 526 527 return desc->block.bits; 528} 529 530/** 531 * Return bytes per block (not pixel) for the given format. 532 */ 533static INLINE uint 534util_format_get_blocksize(enum pipe_format format) 535{ 536 uint bits = util_format_get_blocksizebits(format); 537 538 assert(bits % 8 == 0); 539 540 return bits / 8; 541} 542 543static INLINE uint 544util_format_get_blockwidth(enum pipe_format format) 545{ 546 const struct util_format_description *desc = util_format_description(format); 547 548 assert(desc); 549 if (!desc) { 550 return 1; 551 } 552 553 return desc->block.width; 554} 555 556static INLINE uint 557util_format_get_blockheight(enum pipe_format format) 558{ 559 const struct util_format_description *desc = util_format_description(format); 560 561 assert(desc); 562 if (!desc) { 563 return 1; 564 } 565 566 return desc->block.height; 567} 568 569static INLINE unsigned 570util_format_get_nblocksx(enum pipe_format format, 571 unsigned x) 572{ 573 unsigned blockwidth = util_format_get_blockwidth(format); 574 return (x + blockwidth - 1) / blockwidth; 575} 576 577static INLINE unsigned 578util_format_get_nblocksy(enum pipe_format format, 579 unsigned y) 580{ 581 unsigned blockheight = util_format_get_blockheight(format); 582 return (y + blockheight - 1) / blockheight; 583} 584 585static INLINE unsigned 586util_format_get_nblocks(enum pipe_format format, 587 unsigned width, 588 unsigned height) 589{ 590 return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); 591} 592 593static INLINE size_t 594util_format_get_stride(enum pipe_format format, 595 unsigned width) 596{ 597 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); 598} 599 600static INLINE size_t 601util_format_get_2d_size(enum pipe_format format, 602 size_t stride, 603 unsigned height) 604{ 605 return util_format_get_nblocksy(format, height) * stride; 606} 607 608static INLINE uint 609util_format_get_component_bits(enum pipe_format format, 610 enum util_format_colorspace colorspace, 611 uint component) 612{ 613 const struct util_format_description *desc = util_format_description(format); 614 enum util_format_colorspace desc_colorspace; 615 616 assert(format); 617 if (!format) { 618 return 0; 619 } 620 621 assert(component < 4); 622 623 /* Treat RGB and SRGB as equivalent. */ 624 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 625 colorspace = UTIL_FORMAT_COLORSPACE_RGB; 626 } 627 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 628 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; 629 } else { 630 desc_colorspace = desc->colorspace; 631 } 632 633 if (desc_colorspace != colorspace) { 634 return 0; 635 } 636 637 switch (desc->swizzle[component]) { 638 case UTIL_FORMAT_SWIZZLE_X: 639 return desc->channel[0].size; 640 case UTIL_FORMAT_SWIZZLE_Y: 641 return desc->channel[1].size; 642 case UTIL_FORMAT_SWIZZLE_Z: 643 return desc->channel[2].size; 644 case UTIL_FORMAT_SWIZZLE_W: 645 return desc->channel[3].size; 646 default: 647 return 0; 648 } 649} 650 651static INLINE boolean 652util_format_has_alpha(enum pipe_format format) 653{ 654 const struct util_format_description *desc = util_format_description(format); 655 656 assert(format); 657 if (!format) { 658 return FALSE; 659 } 660 661 switch (desc->colorspace) { 662 case UTIL_FORMAT_COLORSPACE_RGB: 663 case UTIL_FORMAT_COLORSPACE_SRGB: 664 return desc->swizzle[3] != UTIL_FORMAT_SWIZZLE_1; 665 case UTIL_FORMAT_COLORSPACE_YUV: 666 return FALSE; 667 case UTIL_FORMAT_COLORSPACE_ZS: 668 return FALSE; 669 default: 670 assert(0); 671 return FALSE; 672 } 673} 674 675/** 676 * Return the matching SRGB format, or PIPE_FORMAT_NONE if none. 677 */ 678static INLINE enum pipe_format 679util_format_srgb(enum pipe_format format) 680{ 681 switch (format) { 682 case PIPE_FORMAT_L8_UNORM: 683 return PIPE_FORMAT_L8_SRGB; 684 case PIPE_FORMAT_L8A8_UNORM: 685 return PIPE_FORMAT_L8A8_SRGB; 686 case PIPE_FORMAT_R8G8B8_UNORM: 687 return PIPE_FORMAT_R8G8B8_SRGB; 688 case PIPE_FORMAT_A8B8G8R8_UNORM: 689 return PIPE_FORMAT_A8B8G8R8_SRGB; 690 case PIPE_FORMAT_X8B8G8R8_UNORM: 691 return PIPE_FORMAT_X8B8G8R8_SRGB; 692 case PIPE_FORMAT_B8G8R8A8_UNORM: 693 return PIPE_FORMAT_B8G8R8A8_SRGB; 694 case PIPE_FORMAT_B8G8R8X8_UNORM: 695 return PIPE_FORMAT_B8G8R8X8_SRGB; 696 case PIPE_FORMAT_A8R8G8B8_UNORM: 697 return PIPE_FORMAT_A8R8G8B8_SRGB; 698 case PIPE_FORMAT_X8R8G8B8_UNORM: 699 return PIPE_FORMAT_X8R8G8B8_SRGB; 700 case PIPE_FORMAT_DXT1_RGB: 701 return PIPE_FORMAT_DXT1_SRGB; 702 case PIPE_FORMAT_DXT1_RGBA: 703 return PIPE_FORMAT_DXT1_SRGBA; 704 case PIPE_FORMAT_DXT3_RGBA: 705 return PIPE_FORMAT_DXT3_SRGBA; 706 case PIPE_FORMAT_DXT5_RGBA: 707 return PIPE_FORMAT_DXT5_SRGBA; 708 default: 709 return PIPE_FORMAT_NONE; 710 } 711} 712 713/** 714 * Return the number of components stored. 715 * Formats with block size != 1x1 will always have 1 component (the block). 716 */ 717static INLINE unsigned 718util_format_get_nr_components(enum pipe_format format) 719{ 720 const struct util_format_description *desc = util_format_description(format); 721 return desc->nr_channels; 722} 723 724/* 725 * Format access functions. 726 */ 727 728void 729util_format_read_4f(enum pipe_format format, 730 float *dst, unsigned dst_stride, 731 const void *src, unsigned src_stride, 732 unsigned x, unsigned y, unsigned w, unsigned h); 733 734void 735util_format_write_4f(enum pipe_format format, 736 const float *src, unsigned src_stride, 737 void *dst, unsigned dst_stride, 738 unsigned x, unsigned y, unsigned w, unsigned h); 739 740void 741util_format_read_4ub(enum pipe_format format, 742 uint8_t *dst, unsigned dst_stride, 743 const void *src, unsigned src_stride, 744 unsigned x, unsigned y, unsigned w, unsigned h); 745 746void 747util_format_write_4ub(enum pipe_format format, 748 const uint8_t *src, unsigned src_stride, 749 void *dst, unsigned dst_stride, 750 unsigned x, unsigned y, unsigned w, unsigned h); 751 752/* 753 * Generic format conversion; 754 */ 755 756boolean 757util_format_fits_8unorm(const struct util_format_description *format_desc); 758 759void 760util_format_translate(enum pipe_format dst_format, 761 void *dst, unsigned dst_stride, 762 unsigned dst_x, unsigned dst_y, 763 enum pipe_format src_format, 764 const void *src, unsigned src_stride, 765 unsigned src_x, unsigned src_y, 766 unsigned width, unsigned height); 767 768#ifdef __cplusplus 769} // extern "C" { 770#endif 771 772#endif /* ! U_FORMAT_H */ 773