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(mesa_format f, const uint8_t c[]) 35 { 36 switch (f) { 37 case MESA_FORMAT_B8G8R8A8_UNORM: 38 return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]); 39 case MESA_FORMAT_A8R8G8B8_UNORM: 40 return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]); 41 case MESA_FORMAT_B8G8R8X8_UNORM: 42 return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]); 43 case MESA_FORMAT_X8R8G8B8_UNORM: 44 return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0); 45 case MESA_FORMAT_A8B8G8R8_UNORM: 46 return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]); 47 case MESA_FORMAT_R8G8B8A8_UNORM: 48 return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]); 49 case MESA_FORMAT_B5G6R5_UNORM: 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(mesa_format f, uint32_t z, uint8_t s) 58 { 59 switch (f) { 60 case MESA_FORMAT_S8_UINT_Z24_UNORM: 61 return (z & 0xffffff00) | (s & 0xff); 62 case MESA_FORMAT_X8_UINT_Z24_UNORM: 63 return (z & 0xffffff00); 64 case MESA_FORMAT_Z_UNORM16: 65 return (z & 0xffff0000) >> 16; 66 default: 67 assert(0); 68 } 69 } 70 71 static inline unsigned 72 pack_rgba_f(mesa_format f, const 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(mesa_format f, const 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(mesa_format f, float z, uint8_t s) 91 { 92 return pack_zs_i(f, FLOAT_TO_UINT(z), s); 93 } 94 95 static inline unsigned 96 pack_la_clamp_f(mesa_format f, float l, float a) 97 { 98 GLubyte lb, ab; 99 UNCLAMPED_FLOAT_TO_UBYTE(lb, l); 100 UNCLAMPED_FLOAT_TO_UBYTE(ab, a); 101 return pack_rgba_i(f, (uint8_t []) { lb, lb, lb, ab }); 102 } 103 104 /* Integer base-2 logarithm, rounded towards zero. */ 105 static inline unsigned 106 log2i(unsigned i) 107 { 108 unsigned r = 0; 109 110 if (i & 0xffff0000) { 111 i >>= 16; 112 r += 16; 113 } 114 if (i & 0x0000ff00) { 115 i >>= 8; 116 r += 8; 117 } 118 if (i & 0x000000f0) { 119 i >>= 4; 120 r += 4; 121 } 122 if (i & 0x0000000c) { 123 i >>= 2; 124 r += 2; 125 } 126 if (i & 0x00000002) { 127 r += 1; 128 } 129 return r; 130 } 131 132 static inline void 133 get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h) 134 { 135 *w = fb->_Xmax - fb->_Xmin; 136 *h = fb->_Ymax - fb->_Ymin; 137 *x = fb->_Xmin; 138 *y = (fb->Name ? fb->_Ymin : 139 /* Window system FBO: Flip the Y coordinate. */ 140 fb->Height - fb->_Ymax); 141 } 142 143 static inline void 144 get_viewport_scale(struct gl_context *ctx, float a[16]) 145 { 146 struct gl_viewport_attrib *vp = &ctx->ViewportArray[0]; 147 struct gl_framebuffer *fb = ctx->DrawBuffer; 148 149 a[MAT_SX] = (float)vp->Width / 2; 150 151 if (fb->Name) 152 a[MAT_SY] = (float)vp->Height / 2; 153 else 154 /* Window system FBO: Flip the Y coordinate. */ 155 a[MAT_SY] = - (float)vp->Height / 2; 156 157 a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2; 158 } 159 160 static inline void 161 get_viewport_translate(struct gl_context *ctx, float a[4]) 162 { 163 struct gl_viewport_attrib *vp = &ctx->ViewportArray[0]; 164 struct gl_framebuffer *fb = ctx->DrawBuffer; 165 166 a[0] = (float)vp->Width / 2 + vp->X; 167 168 if (fb->Name) 169 a[1] = (float)vp->Height / 2 + vp->Y; 170 else 171 /* Window system FBO: Flip the Y coordinate. */ 172 a[1] = fb->Height - (float)vp->Height / 2 - vp->Y; 173 174 a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2; 175 } 176 177 static inline GLboolean 178 is_color_operand(int op) 179 { 180 return op == GL_SRC_COLOR || op == GL_ONE_MINUS_SRC_COLOR; 181 } 182 183 static inline GLboolean 184 is_negative_operand(int op) 185 { 186 return op == GL_ONE_MINUS_SRC_COLOR || op == GL_ONE_MINUS_SRC_ALPHA; 187 } 188 189 static inline GLboolean 190 is_texture_source(int s) 191 { 192 return s == GL_TEXTURE || (s >= GL_TEXTURE0 && s <= GL_TEXTURE31); 193 } 194 195 static inline struct gl_texgen * 196 get_texgen_coord(struct gl_texture_unit *u, int i) 197 { 198 return ((struct gl_texgen *[]) 199 { &u->GenS, &u->GenT, &u->GenR, &u->GenQ }) [i]; 200 } 201 202 static inline float * 203 get_texgen_coeff(struct gl_texgen *c) 204 { 205 if (c->Mode == GL_OBJECT_LINEAR) 206 return c->ObjectPlane; 207 else if (c->Mode == GL_EYE_LINEAR) 208 return c->EyePlane; 209 else 210 return NULL; 211 } 212 213 static inline unsigned 214 get_format_blocksx(mesa_format format, 215 unsigned x) 216 { 217 GLuint blockwidth; 218 GLuint blockheight; 219 _mesa_get_format_block_size(format, &blockwidth, &blockheight); 220 return (x + blockwidth - 1) / blockwidth; 221 } 222 223 static inline unsigned 224 get_format_blocksy(mesa_format format, 225 unsigned y) 226 { 227 GLuint blockwidth; 228 GLuint blockheight; 229 _mesa_get_format_block_size(format, &blockwidth, &blockheight); 230 return (y + blockheight - 1) / blockheight; 231 } 232 233 #endif 234