t_vb_program.c revision c3d90f3211d3214722a60c46ec5cef7c65836b39
1/* $Id: t_vb_program.c,v 1.2 2001/12/15 02:13:32 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
102static void
103_vp_ArrayElement( GLint i )
104{
105   /* XXX to do */
106}
107
108static 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
117static 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
126static 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
138static 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
150static 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
159static 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
168static 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
180static 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
192static 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
200static 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
208static void
209_vp_EvalCoord1f( GLfloat s )
210{
211   (void) s;
212   /* XXX no-op? */
213}
214
215static void
216_vp_EvalCoord1fv( const GLfloat *v )
217{
218   (void) v;
219   /* XXX no-op? */
220}
221
222static void
223_vp_EvalCoord2f( GLfloat s, GLfloat t )
224{
225   (void) s;
226   (void )t;
227   /* XXX no-op? */
228}
229
230static void
231_vp_EvalCoord2fv( const GLfloat *v )
232{
233   (void) v;
234   /* XXX no-op? */
235}
236
237static void
238_vp_EvalPoint1( GLint i )
239{
240   (void) i;
241}
242
243static void
244_vp_EvalPoint2( GLint i, GLint j )
245{
246   (void) i;
247   (void) j;
248}
249
250static 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
259static 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
268static void
269_vp_Indexi( GLint i )
270{
271   (void) i;
272}
273
274static void
275_vp_Indexiv( const GLint *i )
276{
277   (void) i;
278}
279
280static void
281_vp_Materialfv( GLenum face, GLenum pname, const GLfloat *v)
282{
283   /* XXX no-op? */
284}
285
286static 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
298static 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
310static 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
322static 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
334static 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
346static 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
358static 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
370static 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
382static 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
391static 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
400static 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
409static 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
418static 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
430static 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
442static 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
451static 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
460static 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
469static 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
478static 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
487static 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
496static 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
505static 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
514static 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
526static 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
538static 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
550static 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
562static 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
574static 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
586static 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
603static 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 */
625void _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
701struct 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
714static 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_OUTPUT_REG_START + 0][0],
787             machine->Registers[VP_OUTPUT_REG_START + 0][1],
788             machine->Registers[VP_OUTPUT_REG_START + 0][2],
789             machine->Registers[VP_OUTPUT_REG_START + 0][3]);
790      printf("   color: %f, %f, %f, %f\n",
791             machine->Registers[VP_OUTPUT_REG_START + 1][0],
792             machine->Registers[VP_OUTPUT_REG_START + 1][1],
793             machine->Registers[VP_OUTPUT_REG_START + 1][2],
794             machine->Registers[VP_OUTPUT_REG_START + 1][3]);
795
796      /* store the attribute output registers into the VB arrays */
797      COPY_4V(clip[i], machine->Registers[VP_OUT_HPOS]);
798      COPY_4V(color0[i], machine->Registers[VP_OUT_COL0]);
799      COPY_4V(color1[i], machine->Registers[VP_OUT_COL1]);
800      COPY_4V(bfcolor0[i], machine->Registers[VP_OUT_BFC0]);
801      COPY_4V(bfcolor1[i], machine->Registers[VP_OUT_BFC1]);
802      fog[i] = machine->Registers[VP_OUT_FOGC][0];
803      pointSize[i] = machine->Registers[VP_OUT_PSIZ][0];
804      COPY_4V(texture0[i], machine->Registers[VP_OUT_TEX0]);
805      COPY_4V(texture1[i], machine->Registers[VP_OUT_TEX0]);
806      COPY_4V(texture2[i], machine->Registers[VP_OUT_TEX0]);
807      COPY_4V(texture3[i], machine->Registers[VP_OUT_TEX0]);
808   }
809
810   VB->ColorPtr[0] = &store->color0[0];
811   VB->ColorPtr[1] = &store->color0[1];
812   VB->SecondaryColorPtr[0] = &store->color1[0];
813   VB->SecondaryColorPtr[1] = &store->color1[1];
814   VB->ProjectedClipPtr = &store->clipCoords;
815   VB->FogCoordPtr = &store->fogCoord;
816   VB->PointSizePtr = &store->pointSize;
817   VB->TexCoordPtr[0] = &store->texCoord[0];
818   VB->TexCoordPtr[1] = &store->texCoord[1];
819   VB->TexCoordPtr[2] = &store->texCoord[2];
820   VB->TexCoordPtr[3] = &store->texCoord[3];
821
822#if 000
823
824   GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
825   GLuint ind;
826
827/*     _tnl_print_vert_flags( __FUNCTION__, stage->changed_inputs ); */
828
829   /* Make sure we can talk about elements 0..2 in the vector we are
830    * lighting.
831    */
832   if (stage->changed_inputs & (VERT_EYE|VERT_OBJ_BIT)) {
833      if (input->size <= 2) {
834	 if (input->flags & VEC_NOT_WRITEABLE) {
835	    ASSERT(VB->importable_data & VERT_OBJ_BIT);
836
837	    VB->import_data( ctx, VERT_OBJ_BIT, VEC_NOT_WRITEABLE );
838	    input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
839
840	    ASSERT((input->flags & VEC_NOT_WRITEABLE) == 0);
841	 }
842
843	 _mesa_vector4f_clean_elem(input, VB->Count, 2);
844      }
845   }
846
847   if (VB->Flag)
848      ind = LIGHT_FLAGS;
849   else
850      ind = 0;
851
852   /* The individual functions know about replaying side-effects
853    * vs. full re-execution.
854    */
855   store->light_func_tab[ind]( ctx, VB, stage, input );
856#endif
857
858   return GL_TRUE;
859}
860
861
862/* Called in place of do_lighting when the light table may have changed.
863 */
864static GLboolean run_validate_program( GLcontext *ctx,
865					struct gl_pipeline_stage *stage )
866{
867#if 000
868   GLuint ind = 0;
869   light_func *tab;
870
871   if (ctx->Visual.rgbMode) {
872      if (ctx->Light._NeedVertices) {
873	 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
874	    tab = _tnl_light_spec_tab;
875	 else
876	    tab = _tnl_light_tab;
877      }
878      else {
879	 if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
880	    tab = _tnl_light_fast_single_tab;
881	 else
882	    tab = _tnl_light_fast_tab;
883      }
884   }
885   else
886      tab = _tnl_light_ci_tab;
887
888   if (ctx->Light.ColorMaterialEnabled)
889      ind |= LIGHT_COLORMATERIAL;
890
891   if (ctx->Light.Model.TwoSide)
892      ind |= LIGHT_TWOSIDE;
893
894   VP_STAGE_DATA(stage)->light_func_tab = &tab[ind];
895
896   /* This and the above should only be done on _NEW_LIGHT:
897    */
898   _mesa_validate_all_lighting_tables( ctx );
899#endif
900
901   /* Now run the stage...
902    */
903   stage->run = run_vp;
904   return stage->run( ctx, stage );
905}
906
907
908
909#if 0
910static void alloc_4chan( struct gl_client_array *a, GLuint sz )
911{
912   a->Ptr = ALIGN_MALLOC( sz * sizeof(GLchan) * 4, 32 );
913   a->Size = 4;
914   a->Type = CHAN_TYPE;
915   a->Stride = 0;
916   a->StrideB = sizeof(GLchan) * 4;
917   a->Enabled = 0;
918   a->Flags = 0;
919}
920#endif
921
922static void alloc_4float( struct gl_client_array *a, GLuint sz )
923{
924   a->Ptr = ALIGN_MALLOC( sz * sizeof(GLfloat) * 4, 32 );
925   a->Size = 4;
926   a->Type = GL_FLOAT;
927   a->Stride = 0;
928   a->StrideB = sizeof(GLfloat) * 4;
929   a->Enabled = 0;
930   a->Flags = 0;
931}
932
933
934/* Called the first time stage->run is called.  In effect, don't
935 * allocate data until the first time the stage is run.
936 */
937static GLboolean run_init_vp( GLcontext *ctx,
938                              struct gl_pipeline_stage *stage )
939{
940   TNLcontext *tnl = TNL_CONTEXT(ctx);
941   struct vertex_buffer *VB = &(tnl->vb);
942   struct vp_stage_data *store;
943   const GLuint size = VB->Size;
944   GLuint i;
945
946   stage->privatePtr = MALLOC(sizeof(*store));
947   store = VP_STAGE_DATA(stage);
948   if (!store)
949      return GL_FALSE;
950
951   /* The output of a vertex program is: */
952   _mesa_vector4f_alloc( &store->clipCoords, 0, size, 32 );
953   alloc_4float( &store->color0[0], size );
954   alloc_4float( &store->color0[1], size );
955   alloc_4float( &store->color1[0], size );
956   alloc_4float( &store->color1[1], size );
957   for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
958      _mesa_vector4f_alloc( &store->texCoord[i], 0, VB->Size, 32 );
959   _mesa_vector1f_alloc( &store->fogCoord, 0, size, 32 );
960   _mesa_vector1f_alloc( &store->pointSize, 0, size, 32 );
961
962
963   /* Now validate the stage derived data...
964    */
965   stage->run = run_validate_program;
966   return stage->run( ctx, stage );
967}
968
969
970
971/*
972 * Check if vertex program mode is enabled.
973 * If so, configure the pipeline stage's type, inputs, and outputs.
974 */
975static void check_vp( GLcontext *ctx, struct gl_pipeline_stage *stage )
976{
977   stage->active = ctx->VertexProgram.Enabled;
978
979   if (stage->active) {
980#if 000
981      if (stage->privatePtr)
982	 stage->run = run_validate_program;
983      stage->inputs = VERT_NORMAL_BIT|VERT_MATERIAL;
984      if (ctx->Light._NeedVertices)
985	 stage->inputs |= VERT_EYE; /* effectively, even when lighting in obj */
986      if (ctx->Light.ColorMaterialEnabled)
987	 stage->inputs |= VERT_COLOR0_BIT;
988
989      stage->outputs = VERT_COLOR0_BIT;
990      if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
991	 stage->outputs |= VERT_COLOR1_BIT;
992#endif
993   }
994}
995
996
997static void dtr( struct gl_pipeline_stage *stage )
998{
999   struct vp_stage_data *store = VP_STAGE_DATA(stage);
1000
1001   if (store) {
1002      GLuint i;
1003      _mesa_vector4f_free( &store->clipCoords );
1004      ALIGN_FREE( store->color0[0].Ptr );
1005      ALIGN_FREE( store->color0[1].Ptr );
1006      ALIGN_FREE( store->color1[0].Ptr );
1007      ALIGN_FREE( store->color1[1].Ptr );
1008      for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
1009	 if (store->texCoord[i].data)
1010            _mesa_vector4f_free( &store->texCoord[i] );
1011      _mesa_vector1f_free( &store->fogCoord );
1012      _mesa_vector1f_free( &store->pointSize );
1013
1014      FREE( store );
1015      stage->privatePtr = 0;
1016   }
1017}
1018
1019const struct gl_pipeline_stage _tnl_vertex_program_stage =
1020{
1021   "vertex-program",
1022   _NEW_ALL,	/*XXX FIX */	/* recheck */
1023   _NEW_ALL,	/*XXX FIX */    /* recalc -- modelview dependency
1024				 * otherwise not captured by inputs
1025				 * (which may be VERT_OBJ_BIT) */
1026   GL_FALSE,			/* active */
1027   0,				/* inputs */
1028   VERT_CLIP | VERT_COLOR0_BIT,			/* outputs */
1029   0,				/* changed_inputs */
1030   NULL,			/* private_data */
1031   dtr,				/* destroy */
1032   check_vp,			/* check */
1033   run_init_vp			/* run -- initially set to ctr */
1034};
1035