aea3c868acaf7289760c0c350efffa297a8b7296
[mesa.git] / src / mesa / tnl / t_vb_program.c
1 /* $Id: t_vb_program.c,v 1.5 2001/12/18 04:06:46 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 /* All begin/end operations are handled by this vertex format:
630 */
631 vfmt->ArrayElement = _vp_ArrayElement;
632 vfmt->Begin = _tnl_Begin;
633 vfmt->Color3f = _vp_Color3f;
634 vfmt->Color3fv = _vp_Color3fv;
635 vfmt->Color3ub = _vp_Color3ub;
636 vfmt->Color3ubv = _vp_Color3ubv;
637 vfmt->Color4f = _vp_Color4f;
638 vfmt->Color4fv = _vp_Color4fv;
639 vfmt->Color4ub = _vp_Color4ub;
640 vfmt->Color4ubv = _vp_Color4ubv;
641 vfmt->EdgeFlag = _vp_EdgeFlag;
642 vfmt->EdgeFlagv = _vp_EdgeFlagv;
643 vfmt->End = _tnl_End;
644 vfmt->EvalCoord1f = _vp_EvalCoord1f;
645 vfmt->EvalCoord1fv = _vp_EvalCoord1fv;
646 vfmt->EvalCoord2f = _vp_EvalCoord2f;
647 vfmt->EvalCoord2fv = _vp_EvalCoord2fv;
648 vfmt->EvalPoint1 = _vp_EvalPoint1;
649 vfmt->EvalPoint2 = _vp_EvalPoint2;
650 vfmt->FogCoordfEXT = _vp_FogCoordf;
651 vfmt->FogCoordfvEXT = _vp_FogCoordfv;
652 vfmt->Indexi = _vp_Indexi;
653 vfmt->Indexiv = _vp_Indexiv;
654 vfmt->Materialfv = _vp_Materialfv;
655 vfmt->MultiTexCoord1fARB = _vp_MultiTexCoord1f;
656 vfmt->MultiTexCoord1fvARB = _vp_MultiTexCoord1fv;
657 vfmt->MultiTexCoord2fARB = _vp_MultiTexCoord2f;
658 vfmt->MultiTexCoord2fvARB = _vp_MultiTexCoord2fv;
659 vfmt->MultiTexCoord3fARB = _vp_MultiTexCoord3f;
660 vfmt->MultiTexCoord3fvARB = _vp_MultiTexCoord3fv;
661 vfmt->MultiTexCoord4fARB = _vp_MultiTexCoord4f;
662 vfmt->MultiTexCoord4fvARB = _vp_MultiTexCoord4fv;
663 vfmt->Normal3f = _vp_Normal3f;
664 vfmt->Normal3fv = _vp_Normal3fv;
665 vfmt->SecondaryColor3fEXT = _vp_SecondaryColor3f;
666 vfmt->SecondaryColor3fvEXT = _vp_SecondaryColor3fv;
667 vfmt->SecondaryColor3ubEXT = _vp_SecondaryColor3ub;
668 vfmt->SecondaryColor3ubvEXT = _vp_SecondaryColor3ubv;
669 vfmt->TexCoord1f = _vp_TexCoord1f;
670 vfmt->TexCoord1fv = _vp_TexCoord1fv;
671 vfmt->TexCoord2f = _vp_TexCoord2f;
672 vfmt->TexCoord2fv = _vp_TexCoord2fv;
673 vfmt->TexCoord3f = _vp_TexCoord3f;
674 vfmt->TexCoord3fv = _vp_TexCoord3fv;
675 vfmt->TexCoord4f = _vp_TexCoord4f;
676 vfmt->TexCoord4fv = _vp_TexCoord4fv;
677 vfmt->Vertex2f = _vp_Vertex2f;
678 vfmt->Vertex2fv = _vp_Vertex2fv;
679 vfmt->Vertex3f = _vp_Vertex3f;
680 vfmt->Vertex3fv = _vp_Vertex3fv;
681 vfmt->Vertex4f = _vp_Vertex4f;
682 vfmt->Vertex4fv = _vp_Vertex4fv;
683 vfmt->VertexAttrib4fNV = _vp_VertexAttrib4f;
684 vfmt->VertexAttrib4fvNV = _vp_VertexAttrib4fv;
685
686 /* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
687 */
688 vfmt->Rectf = _mesa_noop_Rectf;
689
690 /* Just use the core function:
691 */
692 vfmt->CallList = _mesa_CallList;
693
694 vfmt->prefer_float_colors = GL_TRUE;
695 }
696
697
698
699 struct vp_stage_data {
700 GLvector4f clipCoords; /* post-modelview/projection coords */
701 GLvector4f ndcCoords; /* normalized device coords */
702 struct gl_client_array color0[2]; /* front and back */
703 struct gl_client_array color1[2]; /* front and back */
704 GLvector4f texCoord[MAX_TEXTURE_UNITS];
705 GLvector1f fogCoord;
706 GLvector1f pointSize;
707 GLubyte *clipmask;
708 GLubyte ormask, andmask;
709 };
710
711
712 #define VP_STAGE_DATA(stage) ((struct vp_stage_data *)(stage->privatePtr))
713
714
715 static GLboolean run_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
716 {
717 TNLcontext *tnl = TNL_CONTEXT(ctx);
718 struct vp_stage_data *store = VP_STAGE_DATA(stage);
719 struct vertex_buffer *VB = &tnl->vb;
720 struct vp_machine *machine = &(ctx->VertexProgram.Machine);
721 GLint i;
722
723 /* convenience pointers */
724 GLfloat (*clip)[4] = (GLfloat (*)[4]) store->clipCoords.data;
725 GLfloat (*color0)[4] = (GLfloat (*)[4]) store->color0[0].Ptr;
726 GLfloat (*color1)[4] = (GLfloat (*)[4]) store->color1[0].Ptr;
727 GLfloat (*bfcolor0)[4] = (GLfloat (*)[4]) store->color0[1].Ptr;
728 GLfloat (*bfcolor1)[4] = (GLfloat (*)[4]) store->color1[1].Ptr;
729 GLfloat *fog = (GLfloat *) store->fogCoord.data;
730 GLfloat *pointSize = (GLfloat *) store->pointSize.data;
731 GLfloat (*texture0)[4] = (GLfloat (*)[4]) store->texCoord[0].data;
732 GLfloat (*texture1)[4] = (GLfloat (*)[4]) store->texCoord[1].data;
733 GLfloat (*texture2)[4] = (GLfloat (*)[4]) store->texCoord[2].data;
734 GLfloat (*texture3)[4] = (GLfloat (*)[4]) store->texCoord[3].data;
735
736 _mesa_init_tracked_matrices(ctx);
737 _mesa_init_vp_registers(ctx); /* sets temp regs to (0,0,0,1) */
738
739 for (i = 0; i < VB->Count; i++) {
740 GLuint attr;
741
742 #if 0
743 printf("Input %d: %f, %f, %f, %f\n", i,
744 VB->AttribPtr[0]->data[i][0],
745 VB->AttribPtr[0]->data[i][1],
746 VB->AttribPtr[0]->data[i][2],
747 VB->AttribPtr[0]->data[i][3]);
748 printf(" color: %f, %f, %f, %f\n",
749 VB->AttribPtr[3]->data[i][0],
750 VB->AttribPtr[3]->data[i][1],
751 VB->AttribPtr[3]->data[i][2],
752 VB->AttribPtr[3]->data[i][3]);
753 printf(" normal: %f, %f, %f, %f\n",
754 VB->AttribPtr[2]->data[i][0],
755 VB->AttribPtr[2]->data[i][1],
756 VB->AttribPtr[2]->data[i][2],
757 VB->AttribPtr[2]->data[i][3]);
758 #endif
759
760 /* load the input attribute registers */
761 for (attr = 0; attr < 16; attr++) {
762 if (VB->Flag[i] & (1 << attr)) {
763 COPY_4V(machine->Registers[VP_INPUT_REG_START + attr],
764 VB->AttribPtr[attr]->data[i]);
765 }
766 }
767
768 /* execute the program */
769 ASSERT(ctx->VertexProgram.Current);
770 _mesa_exec_program(ctx, ctx->VertexProgram.Current);
771
772 #if 0
773 printf("Output %d: %f, %f, %f, %f\n", i,
774 machine->Registers[VP_OUT_HPOS][0],
775 machine->Registers[VP_OUT_HPOS][1],
776 machine->Registers[VP_OUT_HPOS][2],
777 machine->Registers[VP_OUT_HPOS][3]);
778 printf(" color: %f, %f, %f, %f\n",
779 machine->Registers[VP_OUT_COL0][0],
780 machine->Registers[VP_OUT_COL0][1],
781 machine->Registers[VP_OUT_COL0][2],
782 machine->Registers[VP_OUT_COL0][3]);
783 #endif
784
785 /* store the attribute output registers into the VB arrays */
786 COPY_4V(clip[i], machine->Registers[VP_OUT_HPOS]);
787 COPY_4V(color0[i], machine->Registers[VP_OUT_COL0]);
788 COPY_4V(color1[i], machine->Registers[VP_OUT_COL1]);
789 COPY_4V(bfcolor0[i], machine->Registers[VP_OUT_BFC0]);
790 COPY_4V(bfcolor1[i], machine->Registers[VP_OUT_BFC1]);
791 fog[i] = machine->Registers[VP_OUT_FOGC][0];
792 pointSize[i] = machine->Registers[VP_OUT_PSIZ][0];
793 COPY_4V(texture0[i], machine->Registers[VP_OUT_TEX0]);
794 COPY_4V(texture1[i], machine->Registers[VP_OUT_TEX0]);
795 COPY_4V(texture2[i], machine->Registers[VP_OUT_TEX0]);
796 COPY_4V(texture3[i], machine->Registers[VP_OUT_TEX0]);
797 }
798
799 VB->ClipPtr = &store->clipCoords;
800 VB->ClipPtr->size = 4;
801 VB->ClipPtr->count = VB->Count;
802 VB->ColorPtr[0] = &store->color0[0];
803 VB->ColorPtr[1] = &store->color0[1];
804 VB->SecondaryColorPtr[0] = &store->color1[0];
805 VB->SecondaryColorPtr[1] = &store->color1[1];
806 VB->FogCoordPtr = &store->fogCoord;
807 VB->PointSizePtr = &store->pointSize;
808 VB->TexCoordPtr[0] = &store->texCoord[0];
809 VB->TexCoordPtr[1] = &store->texCoord[1];
810 VB->TexCoordPtr[2] = &store->texCoord[2];
811 VB->TexCoordPtr[3] = &store->texCoord[3];
812
813 /* Cliptest and perspective divide. Clip functions must clear
814 * the clipmask.
815 */
816 store->ormask = 0;
817 store->andmask = CLIP_ALL_BITS;
818
819 if (tnl->NeedNdcCoords) {
820 VB->NdcPtr =
821 _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
822 &store->ndcCoords,
823 store->clipmask,
824 &store->ormask,
825 &store->andmask );
826
827 }
828 else {
829 VB->NdcPtr = 0;
830 _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
831 0,
832 store->clipmask,
833 &store->ormask,
834 &store->andmask );
835 }
836
837 if (store->andmask) /* All vertices are outside the frustum */
838 return GL_FALSE;
839
840
841 /* This is where we'd do clip testing against the user-defined
842 * clipping planes, but they're not supported by vertex programs.
843 */
844
845 VB->ClipOrMask = store->ormask;
846 VB->ClipMask = store->clipmask;
847
848 /* XXXX what's this?
849 if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ_BIT))
850 VB->importable_data |= VERT_CLIP;
851 */
852
853 return GL_TRUE;
854 }
855
856
857 /* Called in place of do_lighting when the light table may have changed.
858 */
859 static GLboolean run_validate_program( GLcontext *ctx,
860 struct gl_pipeline_stage *stage )
861 {
862 #if 000
863 GLuint ind = 0;
864 light_func *tab;
865
866 if (ctx->Visual.rgbMode) {
867 if (ctx->Light._NeedVertices) {
868 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
869 tab = _tnl_light_spec_tab;
870 else
871 tab = _tnl_light_tab;
872 }
873 else {
874 if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
875 tab = _tnl_light_fast_single_tab;
876 else
877 tab = _tnl_light_fast_tab;
878 }
879 }
880 else
881 tab = _tnl_light_ci_tab;
882
883 if (ctx->Light.ColorMaterialEnabled)
884 ind |= LIGHT_COLORMATERIAL;
885
886 if (ctx->Light.Model.TwoSide)
887 ind |= LIGHT_TWOSIDE;
888
889 VP_STAGE_DATA(stage)->light_func_tab = &tab[ind];
890
891 /* This and the above should only be done on _NEW_LIGHT:
892 */
893 _mesa_validate_all_lighting_tables( ctx );
894 #endif
895
896 /* Now run the stage...
897 */
898 stage->run = run_vp;
899 return stage->run( ctx, stage );
900 }
901
902
903
904 #if 0
905 static void alloc_4chan( struct gl_client_array *a, GLuint sz )
906 {
907 a->Ptr = ALIGN_MALLOC( sz * sizeof(GLchan) * 4, 32 );
908 a->Size = 4;
909 a->Type = CHAN_TYPE;
910 a->Stride = 0;
911 a->StrideB = sizeof(GLchan) * 4;
912 a->Enabled = 0;
913 a->Flags = 0;
914 }
915 #endif
916
917 static void alloc_4float( struct gl_client_array *a, GLuint sz )
918 {
919 a->Ptr = ALIGN_MALLOC( sz * sizeof(GLfloat) * 4, 32 );
920 a->Size = 4;
921 a->Type = GL_FLOAT;
922 a->Stride = 0;
923 a->StrideB = sizeof(GLfloat) * 4;
924 a->Enabled = 0;
925 a->Flags = 0;
926 }
927
928
929 /* Called the first time stage->run is called. In effect, don't
930 * allocate data until the first time the stage is run.
931 */
932 static GLboolean run_init_vp( GLcontext *ctx,
933 struct gl_pipeline_stage *stage )
934 {
935 TNLcontext *tnl = TNL_CONTEXT(ctx);
936 struct vertex_buffer *VB = &(tnl->vb);
937 struct vp_stage_data *store;
938 const GLuint size = VB->Size;
939 GLuint i;
940
941 stage->privatePtr = MALLOC(sizeof(*store));
942 store = VP_STAGE_DATA(stage);
943 if (!store)
944 return GL_FALSE;
945
946 /* The output of a vertex program is: */
947 _mesa_vector4f_alloc( &store->clipCoords, 0, size, 32 );
948 _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
949 alloc_4float( &store->color0[0], size );
950 alloc_4float( &store->color0[1], size );
951 alloc_4float( &store->color1[0], size );
952 alloc_4float( &store->color1[1], size );
953 for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
954 _mesa_vector4f_alloc( &store->texCoord[i], 0, VB->Size, 32 );
955 _mesa_vector1f_alloc( &store->fogCoord, 0, size, 32 );
956 _mesa_vector1f_alloc( &store->pointSize, 0, size, 32 );
957 store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
958
959
960 /* Now validate the stage derived data...
961 */
962 stage->run = run_validate_program;
963 return stage->run( ctx, stage );
964 }
965
966
967
968 /*
969 * Check if vertex program mode is enabled.
970 * If so, configure the pipeline stage's type, inputs, and outputs.
971 */
972 static void check_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
973 {
974 stage->active = ctx->VertexProgram.Enabled;
975
976 if (stage->active) {
977 #if 000
978 if (stage->privatePtr)
979 stage->run = run_validate_program;
980 stage->inputs = VERT_NORMAL_BIT|VERT_MATERIAL;
981 if (ctx->Light._NeedVertices)
982 stage->inputs |= VERT_EYE; /* effectively, even when lighting in obj */
983 if (ctx->Light.ColorMaterialEnabled)
984 stage->inputs |= VERT_COLOR0_BIT;
985
986 stage->outputs = VERT_COLOR0_BIT;
987 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
988 stage->outputs |= VERT_COLOR1_BIT;
989 #endif
990 }
991 }
992
993
994 static void dtr( struct gl_pipeline_stage *stage )
995 {
996 struct vp_stage_data *store = VP_STAGE_DATA(stage);
997
998 if (store) {
999 GLuint i;
1000 _mesa_vector4f_free( &store->clipCoords );
1001 _mesa_vector4f_free( &store->ndcCoords );
1002 ALIGN_FREE( store->color0[0].Ptr );
1003 ALIGN_FREE( store->color0[1].Ptr );
1004 ALIGN_FREE( store->color1[0].Ptr );
1005 ALIGN_FREE( store->color1[1].Ptr );
1006 for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
1007 if (store->texCoord[i].data)
1008 _mesa_vector4f_free( &store->texCoord[i] );
1009 _mesa_vector1f_free( &store->fogCoord );
1010 _mesa_vector1f_free( &store->pointSize );
1011 ALIGN_FREE( store->clipmask );
1012
1013 FREE( store );
1014 stage->privatePtr = 0;
1015 }
1016 }
1017
1018 const struct gl_pipeline_stage _tnl_vertex_program_stage =
1019 {
1020 "vertex-program",
1021 _NEW_ALL, /*XXX FIX */ /* recheck */
1022 _NEW_ALL, /*XXX FIX */ /* recalc -- modelview dependency
1023 * otherwise not captured by inputs
1024 * (which may be VERT_OBJ_BIT) */
1025 GL_FALSE, /* active */
1026 0, /* inputs */
1027 VERT_CLIP | VERT_COLOR0_BIT, /* outputs */
1028 0, /* changed_inputs */
1029 NULL, /* private_data */
1030 dtr, /* destroy */
1031 check_vp, /* check */
1032 run_init_vp /* run -- initially set to ctr */
1033 };