1 /* 2 * Copyright (C) 2009 Francisco Jerez. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #ifndef __NOUVEAU_UTIL_H__ 28 #define __NOUVEAU_UTIL_H__ 29 30 #include "main/formats.h" 31 #include "main/colormac.h" 32 33 static inline unsigned 34 pack_rgba_i(gl_format f, uint8_t c[]) 35 { 36 switch (f) { 37 case MESA_FORMAT_ARGB8888: 38 return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]); 39 case MESA_FORMAT_ARGB8888_REV: 40 return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]); 41 case MESA_FORMAT_XRGB8888: 42 return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]); 43 case MESA_FORMAT_XRGB8888_REV: 44 return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0); 45 case MESA_FORMAT_RGBA8888: 46 return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]); 47 case MESA_FORMAT_RGBA8888_REV: 48 return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]); 49 case MESA_FORMAT_RGB565: 50 return PACK_COLOR_565(c[RCOMP], c[GCOMP], c[BCOMP]); 51 default: 52 assert(0); 53 } 54 } 55 56 static inline unsigned 57 pack_zs_i(gl_format f, uint32_t z, uint8_t s) 58 { 59 switch (f) { 60 case MESA_FORMAT_Z24_S8: 61 return (z & 0xffffff00) | (s & 0xff); 62 case MESA_FORMAT_Z24_X8: 63 return (z & 0xffffff00); 64 case MESA_FORMAT_Z16: 65 return (z & 0xffff0000) >> 16; 66 default: 67 assert(0); 68 } 69 } 70 71 static inline unsigned 72 pack_rgba_f(gl_format f, float c[]) 73 { 74 return pack_rgba_i(f, (uint8_t []) { 75 FLOAT_TO_UBYTE(c[RCOMP]), 76 FLOAT_TO_UBYTE(c[GCOMP]), 77 FLOAT_TO_UBYTE(c[BCOMP]), 78 FLOAT_TO_UBYTE(c[ACOMP]) }); 79 } 80 81 static inline unsigned 82 pack_rgba_clamp_f(gl_format f, float c[]) 83 { 84 GLubyte bytes[4]; 85 _mesa_unclamped_float_rgba_to_ubyte(bytes, c); 86 return pack_rgba_i(f, bytes); 87 } 88 89 static inline unsigned 90 pack_zs_f(gl_format f, float z, uint8_t s) 91 { 92 return pack_zs_i(f, FLOAT_TO_UINT(z), s); 93 } 94 95 /* Integer base-2 logarithm, rounded towards zero. */ 96 static inline unsigned 97 log2i(unsigned i) 98 { 99 unsigned r = 0; 100 101 if (i & 0xffff0000) { 102 i >>= 16; 103 r += 16; 104 } 105 if (i & 0x0000ff00) { 106 i >>= 8; 107 r += 8; 108 } 109 if (i & 0x000000f0) { 110 i >>= 4; 111 r += 4; 112 } 113 if (i & 0x0000000c) { 114 i >>= 2; 115 r += 2; 116 } 117 if (i & 0x00000002) { 118 r += 1; 119 } 120 return r; 121 } 122 123 static inline unsigned 124 align(unsigned x, unsigned m) 125 { 126 return (x + m - 1) & ~(m - 1); 127 } 128 129 static inline void 130 get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h) 131 { 132 *w = fb->_Xmax - fb->_Xmin; 133 *h = fb->_Ymax - fb->_Ymin; 134 *x = fb->_Xmin; 135 *y = (fb->Name ? fb->_Ymin : 136 /* Window system FBO: Flip the Y coordinate. */ 137 fb->Height - fb->_Ymax); 138 } 139 140 static inline void 141 get_viewport_scale(struct gl_context *ctx, float a[16]) 142 { 143 struct gl_viewport_attrib *vp = &ctx->Viewport; 144 struct gl_framebuffer *fb = ctx->DrawBuffer; 145 146 a[MAT_SX] = (float)vp->Width / 2; 147 148 if (fb->Name) 149 a[MAT_SY] = (float)vp->Height / 2; 150 else 151 /* Window system FBO: Flip the Y coordinate. */ 152 a[MAT_SY] = - (float)vp->Height / 2; 153 154 a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2; 155 } 156 157 static inline void 158 get_viewport_translate(struct gl_context *ctx, float a[4]) 159 { 160 struct gl_viewport_attrib *vp = &ctx->Viewport; 161 struct gl_framebuffer *fb = ctx->DrawBuffer; 162 163 a[0] = (float)vp->Width / 2 + vp->X; 164 165 if (fb->Name) 166 a[1] = (float)vp->Height / 2 + vp->Y; 167 else 168 /* Window system FBO: Flip the Y coordinate. */ 169 a[1] = fb->Height - (float)vp->Height / 2 - vp->Y; 170 171 a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2; 172 } 173 174 static inline GLboolean 175 is_color_operand(int op) 176 { 177 return op == GL_SRC_COLOR || op == GL_ONE_MINUS_SRC_COLOR; 178 } 179 180 static inline GLboolean 181 is_negative_operand(int op) 182 { 183 return op == GL_ONE_MINUS_SRC_COLOR || op == GL_ONE_MINUS_SRC_ALPHA; 184 } 185 186 static inline GLboolean 187 is_texture_source(int s) 188 { 189 return s == GL_TEXTURE || (s >= GL_TEXTURE0 && s <= GL_TEXTURE31); 190 } 191 192 static inline struct gl_texgen * 193 get_texgen_coord(struct gl_texture_unit *u, int i) 194 { 195 return ((struct gl_texgen *[]) 196 { &u->GenS, &u->GenT, &u->GenR, &u->GenQ }) [i]; 197 } 198 199 static inline float * 200 get_texgen_coeff(struct gl_texgen *c) 201 { 202 if (c->Mode == GL_OBJECT_LINEAR) 203 return c->ObjectPlane; 204 else if (c->Mode == GL_EYE_LINEAR) 205 return c->EyePlane; 206 else 207 return NULL; 208 } 209 210 static inline unsigned 211 get_format_blocksx(gl_format format, 212 unsigned x) 213 { 214 GLuint blockwidth; 215 GLuint blockheight; 216 _mesa_get_format_block_size(format, &blockwidth, &blockheight); 217 return (x + blockwidth - 1) / blockwidth; 218 } 219 220 static inline unsigned 221 get_format_blocksy(gl_format format, 222 unsigned y) 223 { 224 GLuint blockwidth; 225 GLuint blockheight; 226 _mesa_get_format_block_size(format, &blockwidth, &blockheight); 227 return (y + blockheight - 1) / blockheight; 228 } 229 230 #endif 231