got rid of __FUNCTION__ :(
[mesa.git] / src / mesa / drivers / glide / fxvbtmp.h
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.1
4 *
5 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /* Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 * Daniel Borca <dborca@users.sourceforge.net>
28 */
29
30
31 #define VIEWPORT_X(dst,x) dst = s[0] * x + s[12]
32 #define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13]
33 #define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14]
34
35 static void TAG(emit)( GLcontext *ctx,
36 GLuint start, GLuint end,
37 void *dest )
38 {
39 fxMesaContext fxMesa = FX_CONTEXT(ctx);
40 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
41 GLuint tmu0_source = fxMesa->tmu_source[0];
42 GLuint tmu1_source = fxMesa->tmu_source[1];
43 GLfloat (*tc0)[4], (*tc1)[4];
44 GLfloat (*col)[4];
45 GLuint tc0_stride, tc1_stride, col_stride;
46 GLuint tc0_size, tc1_size;
47 GLfloat (*proj)[4] = VB->NdcPtr->data;
48 GLuint proj_stride = VB->NdcPtr->stride;
49 GLfloat (*psize)[4];
50 GLuint psize_stride;
51 GrVertex *v = (GrVertex *)dest;
52 GLfloat u0scale,v0scale,u1scale,v1scale;
53 const GLubyte *mask = VB->ClipMask;
54 const GLfloat *const s = ctx->Viewport._WindowMap.m;
55 int i;
56
57 if (IND & SETUP_PSIZ) {
58 psize = VB->PointSizePtr->data;
59 psize_stride = VB->PointSizePtr->stride;
60 }
61
62 if (IND & SETUP_TMU0) {
63 tc0 = VB->TexCoordPtr[tmu0_source]->data;
64 tc0_stride = VB->TexCoordPtr[tmu0_source]->stride;
65 u0scale = fxMesa->s0scale;
66 v0scale = fxMesa->t0scale;
67 if (IND & SETUP_PTEX)
68 tc0_size = VB->TexCoordPtr[tmu0_source]->size;
69 }
70
71 if (IND & SETUP_TMU1) {
72 tc1 = VB->TexCoordPtr[tmu1_source]->data;
73 tc1_stride = VB->TexCoordPtr[tmu1_source]->stride;
74 u1scale = fxMesa->s1scale; /* wrong if tmu1_source == 0, possible? */
75 v1scale = fxMesa->t1scale;
76 if (IND & SETUP_PTEX)
77 tc1_size = VB->TexCoordPtr[tmu1_source]->size;
78 }
79
80 if (IND & SETUP_RGBA) {
81 col = VB->ColorPtr[0]->data;
82 col_stride = VB->ColorPtr[0]->stride;
83 }
84
85 if (start) {
86 proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride);
87 if (IND & SETUP_PSIZ) {
88 psize = (GLfloat (*)[4])((GLubyte *)psize + start * psize_stride);
89 }
90 if (IND & SETUP_TMU0)
91 tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + start * tc0_stride);
92 if (IND & SETUP_TMU1)
93 tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride);
94 if (IND & SETUP_RGBA)
95 STRIDE_4F(col, start * col_stride);
96 }
97
98 for (i=start; i < end; i++, v++) {
99 if (IND & SETUP_PSIZ) {
100 v->psize = psize[0][0];
101 psize = (GLfloat (*)[4])((GLubyte *)psize + psize_stride);
102 }
103
104 if (IND & SETUP_XYZW) {
105 if (mask[i] == 0) {
106 /* unclipped */
107 VIEWPORT_X(v->x, proj[0][0]);
108 VIEWPORT_Y(v->y, proj[0][1]);
109 VIEWPORT_Z(v->ooz, proj[0][2]);
110 v->oow = proj[0][3];
111 } else {
112 /* clipped */
113 v->oow = 1.0;
114 }
115
116 if (IND & SETUP_SNAP) {
117 #if defined(USE_IEEE)
118 const float snapper = (3L << 18);
119 v->x += snapper;
120 v->x -= snapper;
121 v->y += snapper;
122 v->y -= snapper;
123 #else
124 v->x = ((int) (v->x * 16.0f)) * (1.0f / 16.0f);
125 v->y = ((int) (v->y * 16.0f)) * (1.0f / 16.0f);
126 #endif
127 }
128
129 proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride);
130 }
131 if (IND & SETUP_RGBA) {
132 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[2], col[0][0]);
133 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[1], col[0][1]);
134 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[0], col[0][2]);
135 UNCLAMPED_FLOAT_TO_UBYTE(v->pargb[3], col[0][3]);
136 STRIDE_4F(col, col_stride);
137 }
138 if (IND & SETUP_TMU0) {
139 GLfloat w = v->oow;
140 v->tmuvtx[0].sow = tc0[0][0] * u0scale * w;
141 v->tmuvtx[0].tow = tc0[0][1] * v0scale * w;
142 if (IND & SETUP_PTEX) {
143 v->tmuvtx[0].oow = w;
144 if (tc0_size == 4)
145 v->tmuvtx[0].oow *= tc0[0][3];
146 }
147 tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride);
148 }
149 if (IND & SETUP_TMU1) {
150 GLfloat w = v->oow;
151 v->tmuvtx[1].sow = tc1[0][0] * u1scale * w;
152 v->tmuvtx[1].tow = tc1[0][1] * v1scale * w;
153 if (IND & SETUP_PTEX) {
154 v->tmuvtx[1].oow = w;
155 if (tc1_size == 4)
156 v->tmuvtx[1].oow *= tc1[0][3];
157 }
158 tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride);
159 }
160 }
161 }
162
163 #if (IND & SETUP_XYZW) && (IND & SETUP_RGBA)
164
165 static GLboolean TAG(check_tex_sizes)( GLcontext *ctx )
166 {
167 /* fprintf(stderr, "%s\n", __FUNCTION__); */
168
169 if (IND & SETUP_PTEX)
170 return GL_TRUE;
171
172 if (IND & SETUP_TMU0) {
173 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
174
175 if (IND & SETUP_TMU1) {
176 if (VB->TexCoordPtr[0] == 0)
177 VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
178
179 if (VB->TexCoordPtr[1]->size == 4)
180 return GL_FALSE;
181 }
182
183 if (VB->TexCoordPtr[0] && VB->TexCoordPtr[0]->size == 4)
184 return GL_FALSE;
185 }
186
187 return GL_TRUE;
188 }
189
190 static void TAG(interp)( GLcontext *ctx,
191 GLfloat t,
192 GLuint edst, GLuint eout, GLuint ein,
193 GLboolean force_boundary )
194 {
195 fxMesaContext fxMesa = FX_CONTEXT( ctx );
196 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
197 const GLfloat *dstclip = VB->ClipPtr->data[edst];
198 const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]);
199 const GLfloat *const s = ctx->Viewport._WindowMap.m;
200 GrVertex *fxverts = fxMesa->verts;
201 GrVertex *dst = (GrVertex *) (fxverts + edst);
202 const GrVertex *out = (const GrVertex *) (fxverts + eout);
203 const GrVertex *in = (const GrVertex *) (fxverts + ein);
204 const GLfloat wout = 1.0F / out->oow;
205 const GLfloat win = 1.0F / in->oow;
206
207 VIEWPORT_X(dst->x, dstclip[0] * oow);
208 VIEWPORT_Y(dst->y, dstclip[1] * oow);
209 VIEWPORT_Z(dst->ooz, dstclip[2] * oow);
210 dst->oow = oow;
211
212 if (IND & SETUP_SNAP) {
213 #if defined(USE_IEEE)
214 const float snapper = (3L << 18);
215 dst->x += snapper;
216 dst->x -= snapper;
217 dst->y += snapper;
218 dst->y -= snapper;
219 #else
220 dst->x = ((int) (dst->x * 16.0f)) * (1.0f / 16.0f);
221 dst->y = ((int) (dst->y * 16.0f)) * (1.0f / 16.0f);
222 #endif
223 }
224
225
226 INTERP_UB( t, dst->pargb[0], out->pargb[0], in->pargb[0] );
227 INTERP_UB( t, dst->pargb[1], out->pargb[1], in->pargb[1] );
228 INTERP_UB( t, dst->pargb[2], out->pargb[2], in->pargb[2] );
229 INTERP_UB( t, dst->pargb[3], out->pargb[3], in->pargb[3] );
230
231 if (IND & SETUP_TMU0) {
232 if (IND & SETUP_PTEX) {
233 INTERP_F( t,
234 dst->tmuvtx[0].sow,
235 out->tmuvtx[0].sow * wout,
236 in->tmuvtx[0].sow * win );
237 INTERP_F( t,
238 dst->tmuvtx[0].tow,
239 out->tmuvtx[0].tow * wout,
240 in->tmuvtx[0].tow * win );
241 INTERP_F( t,
242 dst->tmuvtx[0].oow,
243 out->tmuvtx[0].oow * wout,
244 in->tmuvtx[0].oow * win );
245
246 dst->tmuvtx[0].sow *= oow;
247 dst->tmuvtx[0].tow *= oow;
248 dst->tmuvtx[0].oow *= oow;
249 } else {
250 INTERP_F( t,
251 dst->tmuvtx[0].sow,
252 out->tmuvtx[0].sow * wout,
253 in->tmuvtx[0].sow * win );
254 INTERP_F( t,
255 dst->tmuvtx[0].tow,
256 out->tmuvtx[0].tow * wout,
257 in->tmuvtx[0].tow * win );
258
259 dst->tmuvtx[0].sow *= oow;
260 dst->tmuvtx[0].tow *= oow;
261 }
262 }
263
264 if (IND & SETUP_TMU1) {
265 if (IND & SETUP_PTEX) {
266 INTERP_F( t,
267 dst->tmuvtx[1].sow,
268 out->tmuvtx[1].sow * wout,
269 in->tmuvtx[1].sow * win );
270 INTERP_F( t,
271 dst->tmuvtx[1].tow,
272 out->tmuvtx[1].tow * wout,
273 in->tmuvtx[1].tow * win );
274 INTERP_F( t,
275 dst->tmuvtx[1].oow,
276 out->tmuvtx[1].oow * wout,
277 in->tmuvtx[1].oow * win );
278
279 dst->tmuvtx[1].sow *= oow;
280 dst->tmuvtx[1].tow *= oow;
281 dst->tmuvtx[1].oow *= oow;
282 } else {
283 INTERP_F( t,
284 dst->tmuvtx[1].sow,
285 out->tmuvtx[1].sow * wout,
286 in->tmuvtx[1].sow * win );
287 INTERP_F( t,
288 dst->tmuvtx[1].tow,
289 out->tmuvtx[1].tow * wout,
290 in->tmuvtx[1].tow * win );
291
292 dst->tmuvtx[1].sow *= oow;
293 dst->tmuvtx[1].tow *= oow;
294 }
295 }
296 }
297 #endif
298
299
300 static void TAG(init)( void )
301 {
302 setup_tab[IND].emit = TAG(emit);
303
304 #if ((IND & SETUP_XYZW) && (IND & SETUP_RGBA))
305 setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
306 setup_tab[IND].interp = TAG(interp);
307
308 if (IND & SETUP_PTEX) {
309 setup_tab[IND].vertex_format = (GR_STWHINT_W_DIFF_TMU0 |
310 GR_STWHINT_W_DIFF_TMU1);
311 }
312 else {
313 setup_tab[IND].vertex_format = 0;
314 }
315
316 #if (IND & SETUP_TMU1)
317 setup_tab[IND].vertex_format |= GR_STWHINT_ST_DIFF_TMU1;
318 #endif
319
320 #endif
321 }
322
323
324 #undef IND
325 #undef TAG