temporary hack for divide by W
[mesa.git] / src / mesa / tnl / t_vb_program.c
1 /* $Id: t_vb_program.c,v 1.3 2001/12/15 21:31:28 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 4.1
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 /*
28 * -------- Regarding NV_vertex_program --------
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions are met:
31 *
32 * o Redistribution of the source code must contain a copyright notice
33 * and this list of conditions;
34 *
35 * o Redistribution in binary and source code form must contain the
36 * following Notice in the software and any documentation and/or other
37 * materials provided with the distribution; and
38 *
39 * o The name of Nvidia may not be used to promote or endorse software
40 * derived from the software.
41 *
42 * NOTICE: Nvidia hereby grants to each recipient a non-exclusive worldwide
43 * royalty free patent license under patent claims that are licensable by
44 * Nvidia and which are necessarily required and for which no commercially
45 * viable non infringing alternative exists to make, use, sell, offer to sell,
46 * import and otherwise transfer the vertex extension for the Mesa 3D Graphics
47 * Library as distributed in source code and object code form. No hardware or
48 * hardware implementation (including a semiconductor implementation and chips)
49 * are licensed hereunder. If a recipient makes a patent claim or institutes
50 * patent litigation against Nvidia or Nvidia's customers for use or sale of
51 * Nvidia products, then this license grant as to such recipient shall
52 * immediately terminate and recipient immediately agrees to cease use and
53 * distribution of the Mesa Program and derivatives thereof.
54 *
55 * THE MESA 3D GRAPHICS LIBRARY IS PROVIDED ON AN "AS IS BASIS, WITHOUT
56 * WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING,
57 * WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-NFRINGEMENT
58 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
59 *
60 * NVIDIA SHALL NOT HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
62 * LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
63 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
64 * ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE MESA 3D GRAPHICS
65 * LIBRARY OR EVIDENCE OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDR, EVEN
66 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 *
68 * If you do not comply with this agreement, then Nvidia may cancel the license
69 * and rights granted herein.
70 * ---------------------------------------------
71 */
72
73 /*
74 * Authors:
75 * Brian Paul
76 */
77
78
79 #include "glheader.h"
80 #include "api_noop.h"
81 #include "colormac.h"
82 #include "context.h"
83 #include "dlist.h"
84 #include "hash.h"
85 #include "light.h"
86 #include "macros.h"
87 #include "mem.h"
88 #include "mmath.h"
89 #include "simple_list.h"
90 #include "mtypes.h"
91 #include "vpexec.h"
92
93 #include "math/m_translate.h"
94
95 #include "t_context.h"
96 #include "t_pipeline.h"
97 #include "t_imm_api.h"
98 #include "t_imm_exec.h"
99
100
101
102 static void
103 _vp_ArrayElement( GLint i )
104 {
105 /* XXX to do */
106 }
107
108 static void
109 _vp_Color3f( GLfloat r, GLfloat g, GLfloat b )
110 {
111 GET_IMMEDIATE;
112 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
113 ASSIGN_4V(attrib, r, g, b, 1.0F);
114 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
115 }
116
117 static void
118 _vp_Color3fv( const GLfloat *color )
119 {
120 GET_IMMEDIATE;
121 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
122 ASSIGN_4V(attrib, color[0], color[1], color[2], 1.0F);
123 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
124 }
125
126 static void
127 _vp_Color3ub( GLubyte r, GLubyte g, GLubyte b )
128 {
129 GET_IMMEDIATE;
130 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
131 attrib[0] = UBYTE_TO_FLOAT(r);
132 attrib[1] = UBYTE_TO_FLOAT(g);
133 attrib[2] = UBYTE_TO_FLOAT(b);
134 attrib[3] = 1.0F;
135 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
136 }
137
138 static void
139 _vp_Color3ubv( const GLubyte *color )
140 {
141 GET_IMMEDIATE;
142 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
143 attrib[0] = UBYTE_TO_FLOAT(color[0]);
144 attrib[1] = UBYTE_TO_FLOAT(color[1]);
145 attrib[2] = UBYTE_TO_FLOAT(color[2]);
146 attrib[3] = 1.0F;
147 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
148 }
149
150 static void
151 _vp_Color4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
152 {
153 GET_IMMEDIATE;
154 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
155 ASSIGN_4V(attrib, r, g, b, a);
156 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
157 }
158
159 static void
160 _vp_Color4fv( const GLfloat *color )
161 {
162 GET_IMMEDIATE;
163 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
164 COPY_4V(attrib, color);
165 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
166 }
167
168 static void
169 _vp_Color4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
170 {
171 GET_IMMEDIATE;
172 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
173 attrib[0] = UBYTE_TO_FLOAT(r);
174 attrib[1] = UBYTE_TO_FLOAT(g);
175 attrib[2] = UBYTE_TO_FLOAT(b);
176 attrib[3] = UBYTE_TO_FLOAT(a);
177 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
178 }
179
180 static void
181 _vp_Color4ubv( const GLubyte *color )
182 {
183 GET_IMMEDIATE;
184 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR0][IM->Count];
185 attrib[0] = UBYTE_TO_FLOAT(color[0]);
186 attrib[1] = UBYTE_TO_FLOAT(color[1]);
187 attrib[2] = UBYTE_TO_FLOAT(color[2]);
188 attrib[3] = UBYTE_TO_FLOAT(color[3]);
189 IM->Flag[IM->Count] |= VERT_COLOR0_BIT;
190 }
191
192 static void
193 _vp_EdgeFlag( GLboolean flag )
194 {
195 GET_IMMEDIATE;
196 IM->EdgeFlag[IM->Count] = flag;
197 IM->Flag[IM->Count] |= VERT_EDGEFLAG_BIT;
198 }
199
200 static void
201 _vp_EdgeFlagv( const GLboolean *flag )
202 {
203 GET_IMMEDIATE;
204 IM->EdgeFlag[IM->Count] = *flag;
205 IM->Flag[IM->Count] |= VERT_EDGEFLAG_BIT;
206 }
207
208 static void
209 _vp_EvalCoord1f( GLfloat s )
210 {
211 (void) s;
212 /* XXX no-op? */
213 }
214
215 static void
216 _vp_EvalCoord1fv( const GLfloat *v )
217 {
218 (void) v;
219 /* XXX no-op? */
220 }
221
222 static void
223 _vp_EvalCoord2f( GLfloat s, GLfloat t )
224 {
225 (void) s;
226 (void )t;
227 /* XXX no-op? */
228 }
229
230 static void
231 _vp_EvalCoord2fv( const GLfloat *v )
232 {
233 (void) v;
234 /* XXX no-op? */
235 }
236
237 static void
238 _vp_EvalPoint1( GLint i )
239 {
240 (void) i;
241 }
242
243 static void
244 _vp_EvalPoint2( GLint i, GLint j )
245 {
246 (void) i;
247 (void) j;
248 }
249
250 static void
251 _vp_FogCoordf( GLfloat f )
252 {
253 GET_IMMEDIATE;
254 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_FOG][IM->Count];
255 ASSIGN_4V(attrib, f, 0.0F, 0.0F, 1.0F);
256 IM->Flag[IM->Count] |= VERT_FOG_BIT;
257 }
258
259 static void
260 _vp_FogCoordfv( const GLfloat *f )
261 {
262 GET_IMMEDIATE;
263 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_FOG][IM->Count];
264 ASSIGN_4V(attrib, f[0], 0.0F, 0.0F, 1.0F);
265 IM->Flag[IM->Count] |= VERT_FOG_BIT;
266 }
267
268 static void
269 _vp_Indexi( GLint i )
270 {
271 (void) i;
272 }
273
274 static void
275 _vp_Indexiv( const GLint *i )
276 {
277 (void) i;
278 }
279
280 static void
281 _vp_Materialfv( GLenum face, GLenum pname, const GLfloat *v)
282 {
283 /* XXX no-op? */
284 }
285
286 static void
287 _vp_MultiTexCoord1f( GLenum unit, GLfloat s )
288 {
289 const GLint u = (GLint) unit - GL_TEXTURE0_ARB;
290 if (u >=0 && u < 8) {
291 GET_IMMEDIATE;
292 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
293 ASSIGN_4V(attrib, s, 0.0F, 0.0F, 1.0F);
294 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
295 }
296 }
297
298 static void
299 _vp_MultiTexCoord1fv( GLenum unit, const GLfloat *c )
300 {
301 const GLint u = unit - GL_TEXTURE0_ARB;
302 if (u >=0 && u < 8) {
303 GET_IMMEDIATE;
304 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
305 ASSIGN_4V(attrib, c[0], 0.0F, 0.0F, 1.0F);
306 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
307 }
308 }
309
310 static void
311 _vp_MultiTexCoord2f( GLenum unit, GLfloat s, GLfloat t )
312 {
313 const GLint u = unit - GL_TEXTURE0_ARB;
314 if (u >=0 && u < 8) {
315 GET_IMMEDIATE;
316 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
317 ASSIGN_4V(attrib, s, t, 0.0F, 1.0F);
318 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
319 }
320 }
321
322 static void
323 _vp_MultiTexCoord2fv( GLenum unit, const GLfloat *c )
324 {
325 const GLint u = unit - GL_TEXTURE0_ARB;
326 if (u >=0 && u < 8) {
327 GET_IMMEDIATE;
328 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
329 ASSIGN_4V(attrib, c[0], c[1], 0.0F, 1.0F);
330 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
331 }
332 }
333
334 static void
335 _vp_MultiTexCoord3f( GLenum unit, GLfloat s, GLfloat t, GLfloat r )
336 {
337 const GLint u = unit - GL_TEXTURE0_ARB;
338 if (u >=0 && u < 8) {
339 GET_IMMEDIATE;
340 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
341 ASSIGN_4V(attrib, s, t, r, 1.0F);
342 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
343 }
344 }
345
346 static void
347 _vp_MultiTexCoord3fv( GLenum unit, const GLfloat *c )
348 {
349 const GLint u = unit - GL_TEXTURE0_ARB;
350 if (u >=0 && u < 8) {
351 GET_IMMEDIATE;
352 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
353 ASSIGN_4V(attrib, c[0], c[1], c[2], 1.0F);
354 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
355 }
356 }
357
358 static void
359 _vp_MultiTexCoord4f( GLenum unit, GLfloat s, GLfloat t, GLfloat r, GLfloat q )
360 {
361 const GLint u = unit - GL_TEXTURE0_ARB;
362 if (u >=0 && u < 8) {
363 GET_IMMEDIATE;
364 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
365 ASSIGN_4V(attrib, s, t, r, q);
366 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
367 }
368 }
369
370 static void
371 _vp_MultiTexCoord4fv( GLenum unit, const GLfloat *c )
372 {
373 const GLint u = unit - GL_TEXTURE0_ARB;
374 if (u >=0 && u < 8) {
375 GET_IMMEDIATE;
376 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0 + u][IM->Count];
377 COPY_4V(attrib, c);
378 IM->Flag[IM->Count] |= (VERT_TEX0_BIT << u);
379 }
380 }
381
382 static void
383 _vp_Normal3f( GLfloat x, GLfloat y, GLfloat z )
384 {
385 GET_IMMEDIATE;
386 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_NORMAL][IM->Count];
387 ASSIGN_4V(attrib, x, y, z, 1.0F);
388 IM->Flag[IM->Count] |= VERT_NORMAL_BIT;
389 }
390
391 static void
392 _vp_Normal3fv( const GLfloat *n )
393 {
394 GET_IMMEDIATE;
395 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_NORMAL][IM->Count];
396 ASSIGN_4V(attrib, n[0], n[1], n[2], 1.0F);
397 IM->Flag[IM->Count] |= VERT_NORMAL_BIT;
398 }
399
400 static void
401 _vp_SecondaryColor3f( GLfloat r, GLfloat g, GLfloat b )
402 {
403 GET_IMMEDIATE;
404 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR1][IM->Count];
405 ASSIGN_4V(attrib, r, g, b, 1.0F);
406 IM->Flag[IM->Count] |= VERT_COLOR1_BIT;
407 }
408
409 static void
410 _vp_SecondaryColor3fv( const GLfloat *color )
411 {
412 GET_IMMEDIATE;
413 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR1][IM->Count];
414 ASSIGN_4V(attrib, color[0], color[1], color[2], 1.0F);
415 IM->Flag[IM->Count] |= VERT_COLOR1_BIT;
416 }
417
418 static void
419 _vp_SecondaryColor3ub( GLubyte r, GLubyte g, GLubyte b )
420 {
421 GET_IMMEDIATE;
422 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR1][IM->Count];
423 attrib[0] = UBYTE_TO_FLOAT(r);
424 attrib[1] = UBYTE_TO_FLOAT(g);
425 attrib[2] = UBYTE_TO_FLOAT(b);
426 attrib[3] = 1.0F;
427 IM->Flag[IM->Count] |= VERT_COLOR1_BIT;
428 }
429
430 static void
431 _vp_SecondaryColor3ubv( const GLubyte *color )
432 {
433 GET_IMMEDIATE;
434 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_COLOR1][IM->Count];
435 attrib[0] = UBYTE_TO_FLOAT(color[0]);
436 attrib[1] = UBYTE_TO_FLOAT(color[1]);
437 attrib[2] = UBYTE_TO_FLOAT(color[2]);
438 attrib[3] = 1.0F;
439 IM->Flag[IM->Count] |= VERT_COLOR1_BIT;
440 }
441
442 static void
443 _vp_TexCoord1f( GLfloat s )
444 {
445 GET_IMMEDIATE;
446 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
447 ASSIGN_4V(attrib, s, 0.0F, 0.0F, 1.0F);
448 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
449 }
450
451 static void
452 _vp_TexCoord1fv( const GLfloat *c )
453 {
454 GET_IMMEDIATE;
455 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
456 ASSIGN_4V(attrib, c[0], 0.0F, 0.0F, 1.0F);
457 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
458 }
459
460 static void
461 _vp_TexCoord2f( GLfloat s, GLfloat t )
462 {
463 GET_IMMEDIATE;
464 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
465 ASSIGN_4V(attrib, s, t, 0.0F, 1.0F);
466 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
467 }
468
469 static void
470 _vp_TexCoord2fv( const GLfloat *c )
471 {
472 GET_IMMEDIATE;
473 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
474 ASSIGN_4V(attrib, c[0], c[1], 0.0F, 1.0F);
475 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
476 }
477
478 static void
479 _vp_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
480 {
481 GET_IMMEDIATE;
482 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
483 ASSIGN_4V(attrib, s, t, r, 1.0F);
484 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
485 }
486
487 static void
488 _vp_TexCoord3fv( const GLfloat *c )
489 {
490 GET_IMMEDIATE;
491 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
492 ASSIGN_4V(attrib, c[0], c[1], c[2], 1.0F);
493 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
494 }
495
496 static void
497 _vp_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
498 {
499 GET_IMMEDIATE;
500 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
501 ASSIGN_4V(attrib, s, t, r, 1.0F);
502 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
503 }
504
505 static void
506 _vp_TexCoord4fv( const GLfloat *c )
507 {
508 GET_IMMEDIATE;
509 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_TEX0][IM->Count];
510 COPY_4V(attrib, c);
511 IM->Flag[IM->Count] |= VERT_TEX0_BIT;
512 }
513
514 static void
515 _vp_Vertex2f( GLfloat x, GLfloat y )
516 {
517 GET_IMMEDIATE;
518 const GLuint count = IM->Count++;
519 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_POS][count];
520 ASSIGN_4V(attrib, x, y, 0.0F, 1.0F);
521 IM->Flag[count] |= VERT_OBJ_BIT;
522 if (count == IMM_MAXDATA - 1)
523 _tnl_flush_immediate( IM );
524 }
525
526 static void
527 _vp_Vertex2fv( const GLfloat *v )
528 {
529 GET_IMMEDIATE;
530 const GLuint count = IM->Count++;
531 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_POS][count];
532 ASSIGN_4V(attrib, v[0], v[1], 0.0F, 1.0F);
533 IM->Flag[count] |= VERT_OBJ_BIT;
534 if (count == IMM_MAXDATA - 1)
535 _tnl_flush_immediate( IM );
536 }
537
538 static void
539 _vp_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
540 {
541 GET_IMMEDIATE;
542 const GLuint count = IM->Count++;
543 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_POS][count];
544 ASSIGN_4V(attrib, x, y, z, 1.0F);
545 IM->Flag[count] |= VERT_OBJ_BIT;
546 if (count == IMM_MAXDATA - 1)
547 _tnl_flush_immediate( IM );
548 }
549
550 static void
551 _vp_Vertex3fv( const GLfloat *v )
552 {
553 GET_IMMEDIATE;
554 const GLuint count = IM->Count++;
555 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_POS][count];
556 ASSIGN_4V(attrib, v[0], v[1], v[2], 1.0F);
557 IM->Flag[count] |= VERT_OBJ_BIT;
558 if (count == IMM_MAXDATA - 1)
559 _tnl_flush_immediate( IM );
560 }
561
562 static void
563 _vp_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
564 {
565 GET_IMMEDIATE;
566 const GLuint count = IM->Count++;
567 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_POS][count];
568 ASSIGN_4V(attrib, x, y, z, w);
569 IM->Flag[count] |= VERT_OBJ_BIT;
570 if (count == IMM_MAXDATA - 1)
571 _tnl_flush_immediate( IM );
572 }
573
574 static void
575 _vp_Vertex4fv( const GLfloat *v )
576 {
577 GET_IMMEDIATE;
578 const GLuint count = IM->Count++;
579 GLfloat *attrib = IM->Attrib[VERT_ATTRIB_POS][count];
580 COPY_4V(attrib, v);
581 IM->Flag[count] |= VERT_OBJ_BIT;
582 if (count == IMM_MAXDATA - 1)
583 _tnl_flush_immediate( IM );
584 }
585
586 static void
587 _vp_VertexAttrib4f( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
588 {
589 if (index < 16) {
590 GET_IMMEDIATE;
591 const GLuint count = IM->Count;
592 GLfloat *attrib = IM->Attrib[index][count];
593 ASSIGN_4V(attrib, x, y, z, w);
594 IM->Flag[count] |= (1 << index);
595 if (index == 0) {
596 IM->Count++;
597 if (count == IMM_MAXDATA - 1)
598 _tnl_flush_immediate( IM );
599 }
600 }
601 }
602
603 static void
604 _vp_VertexAttrib4fv( GLuint index, const GLfloat *v )
605 {
606 if (index < 16) {
607 GET_IMMEDIATE;
608 const GLuint count = IM->Count;
609 GLfloat *attrib = IM->Attrib[index][count];
610 COPY_4V(attrib, v);
611 IM->Flag[count] |= (1 << index);
612 if (index == 0) {
613 IM->Count++;
614 if (count == IMM_MAXDATA - 1)
615 _tnl_flush_immediate( IM );
616 }
617 }
618 }
619
620
621 /*
622 * When vertex program mode is enabled we hook in different per-vertex
623 * functions.
624 */
625 void _tnl_vprog_vtxfmt_init( GLcontext *ctx )
626 {
627 GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
628
629 printf("%s()\n", __FUNCTION__);
630
631 /* All begin/end operations are handled by this vertex format:
632 */
633 vfmt->ArrayElement = _vp_ArrayElement;
634 vfmt->Begin = _tnl_Begin;
635 vfmt->Color3f = _vp_Color3f;
636 vfmt->Color3fv = _vp_Color3fv;
637 vfmt->Color3ub = _vp_Color3ub;
638 vfmt->Color3ubv = _vp_Color3ubv;
639 vfmt->Color4f = _vp_Color4f;
640 vfmt->Color4fv = _vp_Color4fv;
641 vfmt->Color4ub = _vp_Color4ub;
642 vfmt->Color4ubv = _vp_Color4ubv;
643 vfmt->EdgeFlag = _vp_EdgeFlag;
644 vfmt->EdgeFlagv = _vp_EdgeFlagv;
645 vfmt->End = _tnl_End;
646 vfmt->EvalCoord1f = _vp_EvalCoord1f;
647 vfmt->EvalCoord1fv = _vp_EvalCoord1fv;
648 vfmt->EvalCoord2f = _vp_EvalCoord2f;
649 vfmt->EvalCoord2fv = _vp_EvalCoord2fv;
650 vfmt->EvalPoint1 = _vp_EvalPoint1;
651 vfmt->EvalPoint2 = _vp_EvalPoint2;
652 vfmt->FogCoordfEXT = _vp_FogCoordf;
653 vfmt->FogCoordfvEXT = _vp_FogCoordfv;
654 vfmt->Indexi = _vp_Indexi;
655 vfmt->Indexiv = _vp_Indexiv;
656 vfmt->Materialfv = _vp_Materialfv;
657 vfmt->MultiTexCoord1fARB = _vp_MultiTexCoord1f;
658 vfmt->MultiTexCoord1fvARB = _vp_MultiTexCoord1fv;
659 vfmt->MultiTexCoord2fARB = _vp_MultiTexCoord2f;
660 vfmt->MultiTexCoord2fvARB = _vp_MultiTexCoord2fv;
661 vfmt->MultiTexCoord3fARB = _vp_MultiTexCoord3f;
662 vfmt->MultiTexCoord3fvARB = _vp_MultiTexCoord3fv;
663 vfmt->MultiTexCoord4fARB = _vp_MultiTexCoord4f;
664 vfmt->MultiTexCoord4fvARB = _vp_MultiTexCoord4fv;
665 vfmt->Normal3f = _vp_Normal3f;
666 vfmt->Normal3fv = _vp_Normal3fv;
667 vfmt->SecondaryColor3fEXT = _vp_SecondaryColor3f;
668 vfmt->SecondaryColor3fvEXT = _vp_SecondaryColor3fv;
669 vfmt->SecondaryColor3ubEXT = _vp_SecondaryColor3ub;
670 vfmt->SecondaryColor3ubvEXT = _vp_SecondaryColor3ubv;
671 vfmt->TexCoord1f = _vp_TexCoord1f;
672 vfmt->TexCoord1fv = _vp_TexCoord1fv;
673 vfmt->TexCoord2f = _vp_TexCoord2f;
674 vfmt->TexCoord2fv = _vp_TexCoord2fv;
675 vfmt->TexCoord3f = _vp_TexCoord3f;
676 vfmt->TexCoord3fv = _vp_TexCoord3fv;
677 vfmt->TexCoord4f = _vp_TexCoord4f;
678 vfmt->TexCoord4fv = _vp_TexCoord4fv;
679 vfmt->Vertex2f = _vp_Vertex2f;
680 vfmt->Vertex2fv = _vp_Vertex2fv;
681 vfmt->Vertex3f = _vp_Vertex3f;
682 vfmt->Vertex3fv = _vp_Vertex3fv;
683 vfmt->Vertex4f = _vp_Vertex4f;
684 vfmt->Vertex4fv = _vp_Vertex4fv;
685 vfmt->VertexAttrib4fNV = _vp_VertexAttrib4f;
686 vfmt->VertexAttrib4fvNV = _vp_VertexAttrib4fv;
687
688 /* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
689 */
690 vfmt->Rectf = _mesa_noop_Rectf;
691
692 /* Just use the core function:
693 */
694 vfmt->CallList = _mesa_CallList;
695
696 vfmt->prefer_float_colors = GL_TRUE;
697 }
698
699
700
701 struct vp_stage_data {
702 GLvector4f clipCoords; /* resulting vertex positions */
703 struct gl_client_array color0[2]; /* front and back */
704 struct gl_client_array color1[2]; /* front and back */
705 GLvector4f texCoord[MAX_TEXTURE_UNITS];
706 GLvector1f fogCoord;
707 GLvector1f pointSize;
708 };
709
710
711 #define VP_STAGE_DATA(stage) ((struct vp_stage_data *)(stage->privatePtr))
712
713
714 static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
715 {
716 TNLcontext *tnl = TNL_CONTEXT(ctx);
717 struct vp_stage_data *store = VP_STAGE_DATA(stage);
718 struct vertex_buffer *VB = &tnl->vb;
719 struct vp_machine *machine = &(ctx->VertexProgram.Machine);
720 struct vp_program *program;
721 GLfloat (*clip)[4];
722 GLfloat (*color0)[4], (*color1)[4];
723 GLfloat (*bfcolor0)[4], (*bfcolor1)[4];
724 GLfloat *fog, *pointSize;
725 GLfloat (*texture0)[4];
726 GLfloat (*texture1)[4];
727 GLfloat (*texture2)[4];
728 GLfloat (*texture3)[4];
729 GLint i;
730
731 /* convenience pointers */
732 store->clipCoords.size = 4;
733 clip = (GLfloat (*)[4]) store->clipCoords.data;
734 color0 = (GLfloat (*)[4]) store->color0[0].Ptr;
735 color1 = (GLfloat (*)[4]) store->color1[0].Ptr;
736 bfcolor0 = (GLfloat (*)[4]) store->color0[1].Ptr;
737 bfcolor1 = (GLfloat (*)[4]) store->color1[1].Ptr;
738 fog = (GLfloat *) store->fogCoord.data;
739 pointSize = (GLfloat *) store->pointSize.data;
740 texture0 = (GLfloat (*)[4]) store->texCoord[0].data;
741 texture1 = (GLfloat (*)[4]) store->texCoord[1].data;
742 texture2 = (GLfloat (*)[4]) store->texCoord[2].data;
743 texture3 = (GLfloat (*)[4]) store->texCoord[3].data;
744
745
746 printf("In %s()\n", __FUNCTION__);
747
748 program = (struct vp_program *) _mesa_HashLookup(ctx->VertexProgram.HashTable, ctx->VertexProgram.Binding);
749 assert(program);
750
751 _mesa_init_tracked_matrices(ctx);
752 _mesa_init_vp_registers(ctx); /* sets temp regs to (0,0,0,1) */
753
754 for (i = 0; i < VB->Count; i++) {
755 GLuint attr;
756
757 printf("Input %d: %f, %f, %f, %f\n", i,
758 VB->AttribPtr[0]->data[i][0],
759 VB->AttribPtr[0]->data[i][1],
760 VB->AttribPtr[0]->data[i][2],
761 VB->AttribPtr[0]->data[i][3]);
762 printf(" color: %f, %f, %f, %f\n",
763 VB->AttribPtr[3]->data[i][0],
764 VB->AttribPtr[3]->data[i][1],
765 VB->AttribPtr[3]->data[i][2],
766 VB->AttribPtr[3]->data[i][3]);
767 printf(" normal: %f, %f, %f, %f\n",
768 VB->AttribPtr[2]->data[i][0],
769 VB->AttribPtr[2]->data[i][1],
770 VB->AttribPtr[2]->data[i][2],
771 VB->AttribPtr[2]->data[i][3]);
772
773
774 /* load the input attribute registers */
775 for (attr = 0; attr < 16; attr++) {
776 if (VB->Flag[i] & (1 << attr)) {
777 COPY_4V(machine->Registers[VP_INPUT_REG_START + attr],
778 VB->AttribPtr[attr]->data[i]);
779 }
780 }
781
782 /* execute the program */
783 _mesa_exec_program(ctx, program);
784
785 printf("Output %d: %f, %f, %f, %f\n", i,
786 machine->Registers[VP_OUT_HPOS][0],
787 machine->Registers[VP_OUT_HPOS][1],
788 machine->Registers[VP_OUT_HPOS][2],
789 machine->Registers[VP_OUT_HPOS][3]);
790 printf(" color: %f, %f, %f, %f\n",
791 machine->Registers[VP_OUT_COL0][0],
792 machine->Registers[VP_OUT_COL0][1],
793 machine->Registers[VP_OUT_COL0][2],
794 machine->Registers[VP_OUT_COL0][3]);
795
796 /* store the attribute output registers into the VB arrays */
797 COPY_4V(clip[i], machine->Registers[VP_OUT_HPOS]);
798 clip[i][0] /= clip[i][3];
799 clip[i][1] /= clip[i][3];
800 clip[i][2] /= clip[i][3];
801 COPY_4V(color0[i], machine->Registers[VP_OUT_COL0]);
802 COPY_4V(color1[i], machine->Registers[VP_OUT_COL1]);
803 COPY_4V(bfcolor0[i], machine->Registers[VP_OUT_BFC0]);
804 COPY_4V(bfcolor1[i], machine->Registers[VP_OUT_BFC1]);
805 fog[i] = machine->Registers[VP_OUT_FOGC][0];
806 pointSize[i] = machine->Registers[VP_OUT_PSIZ][0];
807 COPY_4V(texture0[i], machine->Registers[VP_OUT_TEX0]);
808 COPY_4V(texture1[i], machine->Registers[VP_OUT_TEX0]);
809 COPY_4V(texture2[i], machine->Registers[VP_OUT_TEX0]);
810 COPY_4V(texture3[i], machine->Registers[VP_OUT_TEX0]);
811 }
812
813 VB->ColorPtr[0] = &store->color0[0];
814 VB->ColorPtr[1] = &store->color0[1];
815 VB->SecondaryColorPtr[0] = &store->color1[0];
816 VB->SecondaryColorPtr[1] = &store->color1[1];
817 VB->ProjectedClipPtr = &store->clipCoords;
818 VB->FogCoordPtr = &store->fogCoord;
819 VB->PointSizePtr = &store->pointSize;
820 VB->TexCoordPtr[0] = &store->texCoord[0];
821 VB->TexCoordPtr[1] = &store->texCoord[1];
822 VB->TexCoordPtr[2] = &store->texCoord[2];
823 VB->TexCoordPtr[3] = &store->texCoord[3];
824
825 #if 000
826
827 GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
828 GLuint ind;
829
830 /* _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */
831
832 /* Make sure we can talk about elements 0..2 in the vector we are
833 * lighting.
834 */
835 if (stage->changed_inputs & (VERT_EYE|VERT_OBJ_BIT)) {
836 if (input->size <= 2) {
837 if (input->flags & VEC_NOT_WRITEABLE) {
838 ASSERT(VB->importable_data & VERT_OBJ_BIT);
839
840 VB->import_data( ctx, VERT_OBJ_BIT, VEC_NOT_WRITEABLE );
841 input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
842
843 ASSERT((input->flags & VEC_NOT_WRITEABLE) == 0);
844 }
845
846 _mesa_vector4f_clean_elem(input, VB->Count, 2);
847 }
848 }
849
850 if (VB->Flag)
851 ind = LIGHT_FLAGS;
852 else
853 ind = 0;
854
855 /* The individual functions know about replaying side-effects
856 * vs. full re-execution.
857 */
858 store->light_func_tab[ind]( ctx, VB, stage, input );
859 #endif
860
861 return GL_TRUE;
862 }
863
864
865 /* Called in place of do_lighting when the light table may have changed.
866 */
867 static GLboolean run_validate_program( GLcontext *ctx,
868 struct gl_pipeline_stage *stage )
869 {
870 #if 000
871 GLuint ind = 0;
872 light_func *tab;
873
874 if (ctx->Visual.rgbMode) {
875 if (ctx->Light._NeedVertices) {
876 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
877 tab = _tnl_light_spec_tab;
878 else
879 tab = _tnl_light_tab;
880 }
881 else {
882 if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
883 tab = _tnl_light_fast_single_tab;
884 else
885 tab = _tnl_light_fast_tab;
886 }
887 }
888 else
889 tab = _tnl_light_ci_tab;
890
891 if (ctx->Light.ColorMaterialEnabled)
892 ind |= LIGHT_COLORMATERIAL;
893
894 if (ctx->Light.Model.TwoSide)
895 ind |= LIGHT_TWOSIDE;
896
897 VP_STAGE_DATA(stage)->light_func_tab = &tab[ind];
898
899 /* This and the above should only be done on _NEW_LIGHT:
900 */
901 _mesa_validate_all_lighting_tables( ctx );
902 #endif
903
904 /* Now run the stage...
905 */
906 stage->run = run_vp;
907 return stage->run( ctx, stage );
908 }
909
910
911
912 #if 0
913 static void alloc_4chan( struct gl_client_array *a, GLuint sz )
914 {
915 a->Ptr = ALIGN_MALLOC( sz * sizeof(GLchan) * 4, 32 );
916 a->Size = 4;
917 a->Type = CHAN_TYPE;
918 a->Stride = 0;
919 a->StrideB = sizeof(GLchan) * 4;
920 a->Enabled = 0;
921 a->Flags = 0;
922 }
923 #endif
924
925 static void alloc_4float( struct gl_client_array *a, GLuint sz )
926 {
927 a->Ptr = ALIGN_MALLOC( sz * sizeof(GLfloat) * 4, 32 );
928 a->Size = 4;
929 a->Type = GL_FLOAT;
930 a->Stride = 0;
931 a->StrideB = sizeof(GLfloat) * 4;
932 a->Enabled = 0;
933 a->Flags = 0;
934 }
935
936
937 /* Called the first time stage->run is called. In effect, don't
938 * allocate data until the first time the stage is run.
939 */
940 static GLboolean run_init_vp( GLcontext *ctx,
941 struct gl_pipeline_stage *stage )
942 {
943 TNLcontext *tnl = TNL_CONTEXT(ctx);
944 struct vertex_buffer *VB = &(tnl->vb);
945 struct vp_stage_data *store;
946 const GLuint size = VB->Size;
947 GLuint i;
948
949 stage->privatePtr = MALLOC(sizeof(*store));
950 store = VP_STAGE_DATA(stage);
951 if (!store)
952 return GL_FALSE;
953
954 /* The output of a vertex program is: */
955 _mesa_vector4f_alloc( &store->clipCoords, 0, size, 32 );
956 alloc_4float( &store->color0[0], size );
957 alloc_4float( &store->color0[1], size );
958 alloc_4float( &store->color1[0], size );
959 alloc_4float( &store->color1[1], size );
960 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
961 _mesa_vector4f_alloc( &store->texCoord[i], 0, VB->Size, 32 );
962 _mesa_vector1f_alloc( &store->fogCoord, 0, size, 32 );
963 _mesa_vector1f_alloc( &store->pointSize, 0, size, 32 );
964
965
966 /* Now validate the stage derived data...
967 */
968 stage->run = run_validate_program;
969 return stage->run( ctx, stage );
970 }
971
972
973
974 /*
975 * Check if vertex program mode is enabled.
976 * If so, configure the pipeline stage's type, inputs, and outputs.
977 */
978 static void check_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
979 {
980 stage->active = ctx->VertexProgram.Enabled;
981
982 if (stage->active) {
983 #if 000
984 if (stage->privatePtr)
985 stage->run = run_validate_program;
986 stage->inputs = VERT_NORMAL_BIT|VERT_MATERIAL;
987 if (ctx->Light._NeedVertices)
988 stage->inputs |= VERT_EYE; /* effectively, even when lighting in obj */
989 if (ctx->Light.ColorMaterialEnabled)
990 stage->inputs |= VERT_COLOR0_BIT;
991
992 stage->outputs = VERT_COLOR0_BIT;
993 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
994 stage->outputs |= VERT_COLOR1_BIT;
995 #endif
996 }
997 }
998
999
1000 static void dtr( struct gl_pipeline_stage *stage )
1001 {
1002 struct vp_stage_data *store = VP_STAGE_DATA(stage);
1003
1004 if (store) {
1005 GLuint i;
1006 _mesa_vector4f_free( &store->clipCoords );
1007 ALIGN_FREE( store->color0[0].Ptr );
1008 ALIGN_FREE( store->color0[1].Ptr );
1009 ALIGN_FREE( store->color1[0].Ptr );
1010 ALIGN_FREE( store->color1[1].Ptr );
1011 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
1012 if (store->texCoord[i].data)
1013 _mesa_vector4f_free( &store->texCoord[i] );
1014 _mesa_vector1f_free( &store->fogCoord );
1015 _mesa_vector1f_free( &store->pointSize );
1016
1017 FREE( store );
1018 stage->privatePtr = 0;
1019 }
1020 }
1021
1022 const struct gl_pipeline_stage _tnl_vertex_program_stage =
1023 {
1024 "vertex-program",
1025 _NEW_ALL, /*XXX FIX */ /* recheck */
1026 _NEW_ALL, /*XXX FIX */ /* recalc -- modelview dependency
1027 * otherwise not captured by inputs
1028 * (which may be VERT_OBJ_BIT) */
1029 GL_FALSE, /* active */
1030 0, /* inputs */
1031 VERT_CLIP | VERT_COLOR0_BIT, /* outputs */
1032 0, /* changed_inputs */
1033 NULL, /* private_data */
1034 dtr, /* destroy */
1035 check_vp, /* check */
1036 run_init_vp /* run -- initially set to ctr */
1037 };