Home | History | Annotate | Download | only in nouveau
      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