u_format.h revision e4069d07ddd8c2afa5378e54710e19e7517d43d6
1/************************************************************************** 2 * 3 * Copyright 2009 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 35#ifdef __cplusplus 36extern "C" { 37#endif 38 39 40/** 41 * Describe how to best pack/unpack pixels into/from the prescribed format. 42 * 43 * These are used for automatic code generation of pixel packing and unpacking 44 * routines (in compile time, e.g., u_format_access.py, or in runtime, like 45 * llvmpipe does). 46 * 47 * Thumb rule is: if you're not code generating pixel packing/unpacking then 48 * these are irrelevant for you. 49 * 50 * Note that this can be deduced from other values in util_format_description 51 * structure. This is by design, to make code generation of pixel 52 * packing/unpacking/sampling routines simple and efficient. 53 * 54 * XXX: This should be renamed to something like util_format_pack. 55 */ 56enum util_format_layout { 57 /** 58 * Single scalar component. 59 */ 60 UTIL_FORMAT_LAYOUT_SCALAR = 0, 61 62 /** 63 * One or more components of mixed integer formats, arithmetically encoded 64 * in a word up to 32bits. 65 */ 66 UTIL_FORMAT_LAYOUT_ARITH = 1, 67 68 /** 69 * One or more components, no mixed formats, each with equal power of two 70 * number of bytes. 71 */ 72 UTIL_FORMAT_LAYOUT_ARRAY = 2, 73 74 /** 75 * XXX: Not used yet. These might go away and be replaced by a single entry, 76 * for formats where multiple pixels have to be 77 * read in order to determine a single pixel value (i.e., block.width > 1 78 * || block.height > 1) 79 */ 80 UTIL_FORMAT_LAYOUT_YUV = 3, 81 UTIL_FORMAT_LAYOUT_DXT = 4 82}; 83 84 85struct util_format_block 86{ 87 /** Block width in pixels */ 88 unsigned width; 89 90 /** Block height in pixels */ 91 unsigned height; 92 93 /** Block size in bits */ 94 unsigned bits; 95}; 96 97 98enum util_format_type { 99 UTIL_FORMAT_TYPE_VOID = 0, 100 UTIL_FORMAT_TYPE_UNSIGNED = 1, 101 UTIL_FORMAT_TYPE_SIGNED = 2, 102 UTIL_FORMAT_TYPE_FIXED = 3, 103 UTIL_FORMAT_TYPE_FLOAT = 4 104}; 105 106 107enum util_format_swizzle { 108 UTIL_FORMAT_SWIZZLE_X = 0, 109 UTIL_FORMAT_SWIZZLE_Y = 1, 110 UTIL_FORMAT_SWIZZLE_Z = 2, 111 UTIL_FORMAT_SWIZZLE_W = 3, 112 UTIL_FORMAT_SWIZZLE_0 = 4, 113 UTIL_FORMAT_SWIZZLE_1 = 5, 114 UTIL_FORMAT_SWIZZLE_NONE = 6 115}; 116 117 118enum util_format_colorspace { 119 UTIL_FORMAT_COLORSPACE_RGB = 0, 120 UTIL_FORMAT_COLORSPACE_SRGB = 1, 121 UTIL_FORMAT_COLORSPACE_YUV = 2, 122 UTIL_FORMAT_COLORSPACE_ZS = 3 123}; 124 125 126struct util_format_channel_description 127{ 128 unsigned type:6; 129 unsigned normalized:1; 130 unsigned size:9; 131}; 132 133 134struct util_format_description 135{ 136 enum pipe_format format; 137 const char *name; 138 struct util_format_block block; 139 enum util_format_layout layout; 140 struct util_format_channel_description channel[4]; 141 unsigned char swizzle[4]; 142 enum util_format_colorspace colorspace; 143}; 144 145 146extern const struct util_format_description 147util_format_description_table[]; 148 149 150const struct util_format_description * 151util_format_description(enum pipe_format format); 152 153 154/* 155 * Format query functions. 156 */ 157 158static INLINE boolean 159util_format_is_compressed(enum pipe_format format) 160{ 161 const struct util_format_description *desc = util_format_description(format); 162 163 assert(format); 164 if (!format) { 165 return FALSE; 166 } 167 168 return desc->layout == UTIL_FORMAT_LAYOUT_DXT ? TRUE : FALSE; 169} 170 171static INLINE boolean 172util_format_is_depth_or_stencil(enum pipe_format format) 173{ 174 const struct util_format_description *desc = util_format_description(format); 175 176 assert(format); 177 if (!format) { 178 return FALSE; 179 } 180 181 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; 182} 183 184static INLINE boolean 185util_format_is_depth_and_stencil(enum pipe_format format) 186{ 187 const struct util_format_description *desc = util_format_description(format); 188 189 assert(format); 190 if (!format) { 191 return FALSE; 192 } 193 194 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { 195 return FALSE; 196 } 197 198 return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && 199 desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; 200} 201 202 203/** 204 * Return total bits needed for the pixel format per block. 205 */ 206static INLINE uint 207util_format_get_blocksizebits(enum pipe_format format) 208{ 209 const struct util_format_description *desc = util_format_description(format); 210 211 assert(format); 212 if (!format) { 213 return 0; 214 } 215 216 return desc->block.bits; 217} 218 219/** 220 * Return bytes per block (not pixel) for the given format. 221 */ 222static INLINE uint 223util_format_get_blocksize(enum pipe_format format) 224{ 225 uint bits = util_format_get_blocksizebits(format); 226 227 assert(bits % 8 == 0); 228 229 return bits / 8; 230} 231 232static INLINE uint 233util_format_get_blockwidth(enum pipe_format format) 234{ 235 const struct util_format_description *desc = util_format_description(format); 236 237 assert(format); 238 if (!format) { 239 return 1; 240 } 241 242 switch (desc->layout) { 243 case UTIL_FORMAT_LAYOUT_YUV: 244 return 2; 245 case UTIL_FORMAT_LAYOUT_DXT: 246 return 4; 247 default: 248 return 1; 249 } 250} 251 252static INLINE uint 253util_format_get_blockheight(enum pipe_format format) 254{ 255 const struct util_format_description *desc = util_format_description(format); 256 257 assert(format); 258 if (!format) { 259 return 1; 260 } 261 262 switch (desc->layout) { 263 case UTIL_FORMAT_LAYOUT_DXT: 264 return 4; 265 default: 266 return 1; 267 } 268} 269 270static INLINE unsigned 271util_format_get_nblocksx(enum pipe_format format, 272 unsigned x) 273{ 274 unsigned blockwidth = util_format_get_blockwidth(format); 275 return (x + blockwidth - 1) / blockwidth; 276} 277 278static INLINE unsigned 279util_format_get_nblocksy(enum pipe_format format, 280 unsigned y) 281{ 282 unsigned blockheight = util_format_get_blockheight(format); 283 return (y + blockheight - 1) / blockheight; 284} 285 286static INLINE unsigned 287util_format_get_nblocks(enum pipe_format format, 288 unsigned width, 289 unsigned height) 290{ 291 return util_format_get_nblocksx(format, width) * util_format_get_nblocksy(format, height); 292} 293 294static INLINE size_t 295util_format_get_stride(enum pipe_format format, 296 unsigned width) 297{ 298 return util_format_get_nblocksx(format, width) * util_format_get_blocksize(format); 299} 300 301static INLINE size_t 302util_format_get_2d_size(enum pipe_format format, 303 size_t stride, 304 unsigned height) 305{ 306 return util_format_get_nblocksy(format, height) * stride; 307} 308 309static INLINE uint 310util_format_get_component_bits(enum pipe_format format, 311 enum util_format_colorspace colorspace, 312 uint component) 313{ 314 const struct util_format_description *desc = util_format_description(format); 315 enum util_format_colorspace desc_colorspace; 316 317 assert(format); 318 if (!format) { 319 return 0; 320 } 321 322 assert(component < 4); 323 324 /* Treat RGB and SRGB as equivalent. */ 325 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 326 colorspace = UTIL_FORMAT_COLORSPACE_RGB; 327 } 328 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 329 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; 330 } else { 331 desc_colorspace = desc->colorspace; 332 } 333 334 if (desc_colorspace != colorspace) { 335 return 0; 336 } 337 338 switch (desc->swizzle[component]) { 339 case UTIL_FORMAT_SWIZZLE_X: 340 return desc->channel[0].size; 341 case UTIL_FORMAT_SWIZZLE_Y: 342 return desc->channel[1].size; 343 case UTIL_FORMAT_SWIZZLE_Z: 344 return desc->channel[2].size; 345 case UTIL_FORMAT_SWIZZLE_W: 346 return desc->channel[3].size; 347 default: 348 return 0; 349 } 350} 351 352static INLINE boolean 353util_format_has_alpha(enum pipe_format format) 354{ 355 const struct util_format_description *desc = util_format_description(format); 356 357 assert(format); 358 if (!format) { 359 return FALSE; 360 } 361 362 switch (desc->layout) { 363 case UTIL_FORMAT_LAYOUT_SCALAR: 364 case UTIL_FORMAT_LAYOUT_ARITH: 365 case UTIL_FORMAT_LAYOUT_ARRAY: 366 /* FIXME: pf_get_component_bits( PIPE_FORMAT_A8L8_UNORM, PIPE_FORMAT_COMP_A ) should not return 0 right? */ 367 if (format == PIPE_FORMAT_A8_UNORM || 368 format == PIPE_FORMAT_A8L8_UNORM || 369 format == PIPE_FORMAT_A8L8_SRGB) { 370 return TRUE; 371 } 372 return util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3) != 0; 373 case UTIL_FORMAT_LAYOUT_YUV: 374 return FALSE; 375 case UTIL_FORMAT_LAYOUT_DXT: 376 switch (format) { 377 case PIPE_FORMAT_DXT1_RGBA: 378 case PIPE_FORMAT_DXT3_RGBA: 379 case PIPE_FORMAT_DXT5_RGBA: 380 case PIPE_FORMAT_DXT1_SRGBA: 381 case PIPE_FORMAT_DXT3_SRGBA: 382 case PIPE_FORMAT_DXT5_SRGBA: 383 return TRUE; 384 default: 385 return FALSE; 386 } 387 default: 388 assert(0); 389 return FALSE; 390 } 391} 392 393 394/* 395 * Format access functions. 396 */ 397 398void 399util_format_read_4f(enum pipe_format format, 400 float *dst, unsigned dst_stride, 401 const void *src, unsigned src_stride, 402 unsigned x, unsigned y, unsigned w, unsigned h); 403 404void 405util_format_write_4f(enum pipe_format format, 406 const float *src, unsigned src_stride, 407 void *dst, unsigned dst_stride, 408 unsigned x, unsigned y, unsigned w, unsigned h); 409 410void 411util_format_read_4ub(enum pipe_format format, 412 uint8_t *dst, unsigned dst_stride, 413 const void *src, unsigned src_stride, 414 unsigned x, unsigned y, unsigned w, unsigned h); 415 416void 417util_format_write_4ub(enum pipe_format format, 418 const uint8_t *src, unsigned src_stride, 419 void *dst, unsigned dst_stride, 420 unsigned x, unsigned y, unsigned w, unsigned h); 421 422#ifdef __cplusplus 423} // extern "C" { 424#endif 425 426#endif /* ! U_FORMAT_H */ 427