u_format.h revision ec5577a83da18890a4f334af2241aca41b6ed31b
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 36/** 37 * Describe how to best pack/unpack pixels into/from the prescribed format. 38 * 39 * These are used for automatic code generation of pixel packing and unpacking 40 * routines (in compile time, e.g., u_format_access.py, or in runtime, like 41 * llvmpipe does). 42 * 43 * Thumb rule is: if you're not code generating pixel packing/unpacking then 44 * these are irrelevant for you. 45 * 46 * Note that this can be deduced from other values in util_format_description 47 * structure. This is by design, to make code generation of pixel 48 * packing/unpacking/sampling routines simple and efficient. 49 * 50 * XXX: This should be renamed to something like util_format_pack. 51 */ 52enum util_format_layout { 53 /** 54 * Single scalar component. 55 */ 56 UTIL_FORMAT_LAYOUT_SCALAR = 0, 57 58 /** 59 * One or more components of mixed integer formats, arithmetically encoded 60 * in a word up to 32bits. 61 */ 62 UTIL_FORMAT_LAYOUT_ARITH = 1, 63 64 /** 65 * One or more components, no mixed formats, each with equal power of two 66 * number of bytes. 67 */ 68 UTIL_FORMAT_LAYOUT_ARRAY = 2, 69 70 /** 71 * XXX: Not used yet. These might go away and be replaced by a single entry, 72 * for formats where multiple pixels have to be 73 * read in order to determine a single pixel value (i.e., block.width > 1 74 * || block.height > 1) 75 */ 76 UTIL_FORMAT_LAYOUT_YUV = 3, 77 UTIL_FORMAT_LAYOUT_DXT = 4 78}; 79 80 81struct util_format_block 82{ 83 /** Block width in pixels */ 84 unsigned width; 85 86 /** Block height in pixels */ 87 unsigned height; 88 89 /** Block size in bits */ 90 unsigned bits; 91}; 92 93 94enum util_format_type { 95 UTIL_FORMAT_TYPE_VOID = 0, 96 UTIL_FORMAT_TYPE_UNSIGNED = 1, 97 UTIL_FORMAT_TYPE_SIGNED = 2, 98 UTIL_FORMAT_TYPE_FIXED = 3, 99 UTIL_FORMAT_TYPE_FLOAT = 4 100}; 101 102 103enum util_format_swizzle { 104 UTIL_FORMAT_SWIZZLE_X = 0, 105 UTIL_FORMAT_SWIZZLE_Y = 1, 106 UTIL_FORMAT_SWIZZLE_Z = 2, 107 UTIL_FORMAT_SWIZZLE_W = 3, 108 UTIL_FORMAT_SWIZZLE_0 = 4, 109 UTIL_FORMAT_SWIZZLE_1 = 5, 110 UTIL_FORMAT_SWIZZLE_NONE = 6 111}; 112 113 114enum util_format_colorspace { 115 UTIL_FORMAT_COLORSPACE_RGB = 0, 116 UTIL_FORMAT_COLORSPACE_SRGB = 1, 117 UTIL_FORMAT_COLORSPACE_YUV = 2, 118 UTIL_FORMAT_COLORSPACE_ZS = 3, 119}; 120 121 122struct util_format_channel_description 123{ 124 unsigned type:6; 125 unsigned normalized:1; 126 unsigned size:9; 127}; 128 129 130struct util_format_description 131{ 132 enum pipe_format format; 133 const char *name; 134 struct util_format_block block; 135 enum util_format_layout layout; 136 struct util_format_channel_description channel[4]; 137 unsigned char swizzle[4]; 138 enum util_format_colorspace colorspace; 139}; 140 141 142extern const struct util_format_description 143util_format_description_table[]; 144 145 146const struct util_format_description * 147util_format_description(enum pipe_format format); 148 149 150/* 151 * Format query functions. 152 */ 153 154static INLINE boolean 155util_format_is_compressed(enum pipe_format format) 156{ 157 const struct util_format_description *desc = util_format_description(format); 158 159 assert(format); 160 if (!format) { 161 return FALSE; 162 } 163 164 return desc->layout == UTIL_FORMAT_LAYOUT_DXT ? TRUE : FALSE; 165} 166 167static INLINE boolean 168util_format_is_depth_or_stencil(enum pipe_format format) 169{ 170 const struct util_format_description *desc = util_format_description(format); 171 172 assert(format); 173 if (!format) { 174 return FALSE; 175 } 176 177 return desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS ? TRUE : FALSE; 178} 179 180static INLINE boolean 181util_format_is_depth_and_stencil(enum pipe_format format) 182{ 183 const struct util_format_description *desc = util_format_description(format); 184 185 assert(format); 186 if (!format) { 187 return FALSE; 188 } 189 190 if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) { 191 return FALSE; 192 } 193 194 return (desc->swizzle[0] != UTIL_FORMAT_SWIZZLE_NONE && 195 desc->swizzle[1] != UTIL_FORMAT_SWIZZLE_NONE) ? TRUE : FALSE; 196} 197 198 199/** 200 * Return total bits needed for the pixel format. 201 */ 202static INLINE uint 203util_format_get_bits(enum pipe_format format) 204{ 205 const struct util_format_description *desc = util_format_description(format); 206 207 assert(format); 208 if (!format) { 209 return 0; 210 } 211 212 return desc->block.bits / (desc->block.width * desc->block.height); 213} 214 215/** 216 * Return bytes per pixel for the given format. 217 */ 218static INLINE uint 219util_format_get_size(enum pipe_format format) 220{ 221 uint bits = util_format_get_bits(format); 222 223 assert(bits % 8 == 0); 224 225 return bits / 8; 226} 227 228static INLINE uint 229util_format_get_component_bits(enum pipe_format format, 230 enum util_format_colorspace colorspace, 231 uint component) 232{ 233 const struct util_format_description *desc = util_format_description(format); 234 enum util_format_colorspace desc_colorspace; 235 236 assert(format); 237 if (!format) { 238 return 0; 239 } 240 241 assert(component < 4); 242 243 /* Treat RGB and SRGB as equivalent. */ 244 if (colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 245 colorspace = UTIL_FORMAT_COLORSPACE_RGB; 246 } 247 if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 248 desc_colorspace = UTIL_FORMAT_COLORSPACE_RGB; 249 } else { 250 desc_colorspace = desc->colorspace; 251 } 252 253 if (desc_colorspace != colorspace) { 254 return 0; 255 } 256 257 switch (desc->swizzle[component]) { 258 case UTIL_FORMAT_SWIZZLE_X: 259 return desc->channel[0].size; 260 case UTIL_FORMAT_SWIZZLE_Y: 261 return desc->channel[1].size; 262 case UTIL_FORMAT_SWIZZLE_Z: 263 return desc->channel[2].size; 264 case UTIL_FORMAT_SWIZZLE_W: 265 return desc->channel[3].size; 266 default: 267 return 0; 268 } 269} 270 271 272/* 273 * Format access functions. 274 */ 275 276void 277util_format_read_4f(enum pipe_format format, 278 float *dst, unsigned dst_stride, 279 const void *src, unsigned src_stride, 280 unsigned x, unsigned y, unsigned w, unsigned h); 281 282void 283util_format_write_4f(enum pipe_format format, 284 const float *src, unsigned src_stride, 285 void *dst, unsigned dst_stride, 286 unsigned x, unsigned y, unsigned w, unsigned h); 287 288void 289util_format_read_4ub(enum pipe_format format, 290 uint8_t *dst, unsigned dst_stride, 291 const void *src, unsigned src_stride, 292 unsigned x, unsigned y, unsigned w, unsigned h); 293 294void 295util_format_write_4ub(enum pipe_format format, 296 const uint8_t *src, unsigned src_stride, 297 void *dst, unsigned dst_stride, 298 unsigned x, unsigned y, unsigned w, unsigned h); 299 300#endif /* ! U_FORMAT_H */ 301