/* * Copyright (C) 2009 Francisco Jerez. * All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial * portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ #ifndef __NOUVEAU_UTIL_H__ #define __NOUVEAU_UTIL_H__ #include "main/formats.h" #include "main/colormac.h" static inline unsigned pack_rgba_i(gl_format f, uint8_t c[]) { switch (f) { case MESA_FORMAT_ARGB8888: return PACK_COLOR_8888(c[ACOMP], c[RCOMP], c[GCOMP], c[BCOMP]); case MESA_FORMAT_ARGB8888_REV: return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], c[ACOMP]); case MESA_FORMAT_XRGB8888: return PACK_COLOR_8888(0, c[RCOMP], c[GCOMP], c[BCOMP]); case MESA_FORMAT_XRGB8888_REV: return PACK_COLOR_8888(c[BCOMP], c[GCOMP], c[RCOMP], 0); case MESA_FORMAT_RGBA8888: return PACK_COLOR_8888(c[RCOMP], c[GCOMP], c[BCOMP], c[ACOMP]); case MESA_FORMAT_RGBA8888_REV: return PACK_COLOR_8888(c[ACOMP], c[BCOMP], c[GCOMP], c[RCOMP]); case MESA_FORMAT_RGB565: return PACK_COLOR_565(c[RCOMP], c[GCOMP], c[BCOMP]); default: assert(0); } } static inline unsigned pack_zs_i(gl_format f, uint32_t z, uint8_t s) { switch (f) { case MESA_FORMAT_Z24_S8: return (z & 0xffffff00) | (s & 0xff); case MESA_FORMAT_Z24_X8: return (z & 0xffffff00); case MESA_FORMAT_Z16: return (z & 0xffff0000) >> 16; default: assert(0); } } static inline unsigned pack_rgba_f(gl_format f, float c[]) { return pack_rgba_i(f, (uint8_t []) { FLOAT_TO_UBYTE(c[RCOMP]), FLOAT_TO_UBYTE(c[GCOMP]), FLOAT_TO_UBYTE(c[BCOMP]), FLOAT_TO_UBYTE(c[ACOMP]) }); } static inline unsigned pack_zs_f(gl_format f, float z, uint8_t s) { return pack_zs_i(f, FLOAT_TO_UINT(z), s); } /* Integer base-2 logarithm, rounded towards zero. */ static inline unsigned log2i(unsigned i) { unsigned r = 0; if (i & 0xffff0000) { i >>= 16; r += 16; } if (i & 0x0000ff00) { i >>= 8; r += 8; } if (i & 0x000000f0) { i >>= 4; r += 4; } if (i & 0x0000000c) { i >>= 2; r += 2; } if (i & 0x00000002) { r += 1; } return r; } static inline unsigned align(unsigned x, unsigned m) { return (x + m - 1) & ~(m - 1); } static inline void get_scissors(struct gl_framebuffer *fb, int *x, int *y, int *w, int *h) { *w = fb->_Xmax - fb->_Xmin; *h = fb->_Ymax - fb->_Ymin; *x = fb->_Xmin; *y = (fb->Name ? fb->_Ymin : /* Window system FBO: Flip the Y coordinate. */ fb->Height - fb->_Ymax); } static inline void get_viewport_scale(struct gl_context *ctx, float a[16]) { struct gl_viewport_attrib *vp = &ctx->Viewport; struct gl_framebuffer *fb = ctx->DrawBuffer; a[MAT_SX] = (float)vp->Width / 2; if (fb->Name) a[MAT_SY] = (float)vp->Height / 2; else /* Window system FBO: Flip the Y coordinate. */ a[MAT_SY] = - (float)vp->Height / 2; a[MAT_SZ] = fb->_DepthMaxF * (vp->Far - vp->Near) / 2; } static inline void get_viewport_translate(struct gl_context *ctx, float a[4]) { struct gl_viewport_attrib *vp = &ctx->Viewport; struct gl_framebuffer *fb = ctx->DrawBuffer; a[0] = (float)vp->Width / 2 + vp->X; if (fb->Name) a[1] = (float)vp->Height / 2 + vp->Y; else /* Window system FBO: Flip the Y coordinate. */ a[1] = fb->Height - (float)vp->Height / 2 - vp->Y; a[2] = fb->_DepthMaxF * (vp->Far + vp->Near) / 2; } static inline void OUT_RINGb(struct nouveau_channel *chan, GLboolean x) { OUT_RING(chan, x ? 1 : 0); } static inline void OUT_RINGm(struct nouveau_channel *chan, float m[16]) { int i, j; for (i = 0; i < 4; i++) for (j = 0; j < 4; j++) OUT_RINGf(chan, m[4*j + i]); } static inline GLboolean is_color_operand(int op) { return op == GL_SRC_COLOR || op == GL_ONE_MINUS_SRC_COLOR; } static inline GLboolean is_negative_operand(int op) { return op == GL_ONE_MINUS_SRC_COLOR || op == GL_ONE_MINUS_SRC_ALPHA; } static inline GLboolean is_texture_source(int s) { return s == GL_TEXTURE || (s >= GL_TEXTURE0 && s <= GL_TEXTURE31); } static inline struct gl_texgen * get_texgen_coord(struct gl_texture_unit *u, int i) { return ((struct gl_texgen *[]) { &u->GenS, &u->GenT, &u->GenR, &u->GenQ }) [i]; } static inline float * get_texgen_coeff(struct gl_texgen *c) { if (c->Mode == GL_OBJECT_LINEAR) return c->ObjectPlane; else if (c->Mode == GL_EYE_LINEAR) return c->EyePlane; else return NULL; } #endif