• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
pack_rgba_i(mesa_format f,const uint8_t c[])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
pack_zs_i(mesa_format f,uint32_t z,uint8_t s)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
pack_rgba_f(mesa_format f,const float c[])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
pack_rgba_clamp_f(mesa_format f,const float c[])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
pack_zs_f(mesa_format f,float z,uint8_t s)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
pack_la_clamp_f(mesa_format f,float l,float a)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
log2i(unsigned i)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
get_scissors(struct gl_framebuffer * fb,int * x,int * y,int * w,int * h)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
get_viewport_scale(struct gl_context * ctx,float a[16])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
get_viewport_translate(struct gl_context * ctx,float a[4])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
is_color_operand(int op)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
is_negative_operand(int op)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
is_texture_source(int s)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 *
get_texgen_coord(struct gl_fixedfunc_texture_unit * u,int i)196 get_texgen_coord(struct gl_fixedfunc_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 *
get_texgen_coeff(struct gl_fixedfunc_texture_unit * u,GLenum mode,unsigned chan)203 get_texgen_coeff(struct gl_fixedfunc_texture_unit *u, GLenum mode, unsigned chan)
204 {
205 	if (mode == GL_OBJECT_LINEAR)
206 		return u->ObjectPlane[chan];
207 	else if (mode == GL_EYE_LINEAR)
208 		return u->EyePlane[chan];
209 	else
210 		return NULL;
211 }
212 
213 static inline unsigned
get_format_blocksx(mesa_format format,unsigned x)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
get_format_blocksy(mesa_format format,unsigned y)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