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(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