3bdcd38d72fe981c51c135184237545b55ef1f76
[mesa.git] / src / mesa / tnl / t_imm_api.c
1 /* $Id: t_imm_api.c,v 1.35 2002/10/29 20:29:01 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 * Authors:
27 * Keith Whitwell <keith@tungstengraphics.com>
28 */
29
30
31
32 #include "glheader.h"
33 #include "context.h"
34 #include "dlist.h"
35 #include "enums.h"
36 #include "light.h"
37 #include "imports.h"
38 #include "state.h"
39 #include "colormac.h"
40 #include "macros.h"
41 #include "vtxfmt.h"
42
43 #include "t_context.h"
44 #include "t_imm_api.h"
45 #include "t_imm_elt.h"
46 #include "t_imm_exec.h"
47 #include "t_imm_dlist.h"
48
49
50 /* A cassette is full or flushed on a statechange.
51 */
52 void _tnl_flush_immediate( GLcontext *ctx, struct immediate *IM )
53 {
54 if (!ctx) {
55 /* We were called by glVertex, glEvalCoord, glArrayElement, etc.
56 * The current context is corresponds to the IM structure.
57 */
58 GET_CURRENT_CONTEXT(context);
59 ctx = context;
60 }
61
62 if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
63 _mesa_debug(ctx, "_tnl_flush_immediate IM: %d compiling: %d\n",
64 IM->id, ctx->CompileFlag);
65
66 if (IM->FlushElt == FLUSH_ELT_EAGER) {
67 _tnl_translate_array_elts( ctx, IM, IM->LastPrimitive, IM->Count );
68 }
69
70 /* Mark the last primitive:
71 */
72 IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
73 IM->Primitive[IM->LastPrimitive] |= PRIM_LAST;
74
75 if (ctx->CompileFlag)
76 _tnl_compile_cassette( ctx, IM );
77 else
78 _tnl_execute_cassette( ctx, IM );
79 }
80
81
82 /* Hook for ctx->Driver.FlushVertices:
83 */
84 void _tnl_flush_vertices( GLcontext *ctx, GLuint flags )
85 {
86 struct immediate *IM = TNL_CURRENT_IM(ctx);
87
88 if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
89 _mesa_debug(ctx,
90 "_tnl_flush_vertices flags %x IM(%d) %d..%d Flag[%d]: %x\n",
91 flags, IM->id, IM->Start, IM->Count, IM->Start,
92 IM->Flag[IM->Start]);
93
94 if (IM->Flag[IM->Start]) {
95 if ((flags & FLUSH_UPDATE_CURRENT) ||
96 IM->Count > IM->Start ||
97 (IM->Flag[IM->Start] & (VERT_BIT_BEGIN | VERT_BIT_END))) {
98 _tnl_flush_immediate( ctx, IM );
99 }
100 }
101 }
102
103
104 void
105 _tnl_save_Begin( GLenum mode )
106 {
107 GET_CURRENT_CONTEXT(ctx);
108 struct immediate *IM = TNL_CURRENT_IM(ctx);
109 GLuint inflags, state;
110
111 /* _mesa_debug(ctx, "%s: before: %x\n", __FUNCTION__, IM->BeginState); */
112
113 if (mode > GL_POLYGON) {
114 _mesa_compile_error( ctx, GL_INVALID_ENUM, "_tnl_Begin" );
115 return;
116 }
117
118 if (ctx->NewState)
119 _mesa_update_state(ctx);
120
121 #if 000
122 /* if only a very few slots left, might as well flush now
123 */
124 if (IM->Count > IMM_MAXDATA-8) {
125 _tnl_flush_immediate( ctx, IM );
126 IM = TNL_CURRENT_IM(ctx);
127 }
128 #endif
129
130 /* Check for and flush buffered vertices from internal operations.
131 */
132 if (IM->SavedBeginState) {
133 _tnl_flush_immediate( ctx, IM );
134 IM = TNL_CURRENT_IM(ctx);
135 IM->BeginState = IM->SavedBeginState;
136 IM->SavedBeginState = 0;
137 }
138
139 state = IM->BeginState;
140 inflags = state & (VERT_BEGIN_0|VERT_BEGIN_1);
141 state |= inflags << 2; /* set error conditions */
142
143 if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
144 {
145 GLuint count = IM->Count;
146 GLuint last = IM->LastPrimitive;
147
148 state |= (VERT_BEGIN_0|VERT_BEGIN_1);
149 IM->Flag[count] |= VERT_BIT_BEGIN;
150 IM->Primitive[count] = mode | PRIM_BEGIN;
151 IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive;
152 IM->LastPrimitive = count;
153
154 /* Not quite right. Need to use the fallback '_aa_ArrayElement'
155 * when not known to be inside begin/end and arrays are
156 * unlocked.
157 */
158 if (IM->FlushElt == FLUSH_ELT_EAGER) {
159 _tnl_translate_array_elts( ctx, IM, last, count );
160 }
161 }
162
163 ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
164 IM->BeginState = state;
165
166 /* Update save_primitive now. Don't touch ExecPrimitive as this is
167 * updated in the replay of this cassette if we are in
168 * COMPILE_AND_EXECUTE mode.
169 */
170 if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
171 ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
172 else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
173 ctx->Driver.CurrentSavePrimitive = mode;
174 }
175
176
177 void
178 _tnl_Begin( GLenum mode )
179 {
180 GET_CURRENT_CONTEXT(ctx);
181 TNLcontext *tnl = TNL_CONTEXT(ctx);
182 ASSERT (!ctx->CompileFlag);
183
184 if (mode > GL_POLYGON) {
185 _mesa_error( ctx, GL_INVALID_ENUM, "_tnl_Begin(0x%x)", mode );
186 return;
187 }
188
189 if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
190 _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_Begin" );
191 return;
192 }
193
194 if (ctx->NewState)
195 _mesa_update_state(ctx);
196
197 {
198 struct immediate *IM = TNL_CURRENT_IM(ctx);
199 GLuint count = IM->Count;
200 GLuint last = IM->LastPrimitive;
201
202 if (IM->Start == IM->Count &&
203 tnl->Driver.NotifyBegin &&
204 tnl->Driver.NotifyBegin( ctx, mode )) {
205 return;
206 }
207
208 assert( IM->SavedBeginState == 0 );
209 assert( IM->BeginState == 0 );
210
211 /* Not quite right. Need to use the fallback '_aa_ArrayElement'
212 * when not known to be inside begin/end and arrays are
213 * unlocked.
214 */
215 if (IM->FlushElt == FLUSH_ELT_EAGER) {
216 _tnl_translate_array_elts( ctx, IM, last, count );
217 }
218
219 IM->Flag[count] |= VERT_BIT_BEGIN;
220 IM->Primitive[count] = mode | PRIM_BEGIN;
221 IM->PrimitiveLength[last] = count - last;
222 IM->LastPrimitive = count;
223 IM->BeginState = (VERT_BEGIN_0|VERT_BEGIN_1);
224
225 /* _mesa_debug(ctx, "%s: %x\n", __FUNCTION__, IM->BeginState); */
226
227 ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
228 ctx->Driver.CurrentExecPrimitive = mode;
229 }
230 }
231
232
233 /* Function which allows operations like 'glRectf' to decompose to a
234 * begin/end object and vertices without worrying about what happens
235 * with display lists.
236 */
237 GLboolean
238 _tnl_hard_begin( GLcontext *ctx, GLenum p )
239 {
240 /* _mesa_debug(ctx, "%s\n", __FUNCTION__); */
241
242 if (!ctx->CompileFlag) {
243 /* If not compiling, treat as a normal begin().
244 */
245 /* _mesa_debug(ctx, "%s: treating as glBegin\n", __FUNCTION__); */
246 glBegin( p );
247 return GL_TRUE;
248 }
249 else {
250 /* Otherwise, need to do special processing to preserve the
251 * condition that these vertices will only be replayed outside
252 * future begin/end objects.
253 */
254 struct immediate *IM = TNL_CURRENT_IM(ctx);
255
256 if (ctx->NewState)
257 _mesa_update_state(ctx);
258
259 if (IM->Count > IMM_MAXDATA-8) {
260 _tnl_flush_immediate( ctx, IM );
261 IM = TNL_CURRENT_IM(ctx);
262 }
263
264 /* A lot depends on the degree to which the display list has
265 * constrained the possible begin/end states at this point:
266 */
267 switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
268 case VERT_BEGIN_0|VERT_BEGIN_1:
269 /* This is an immediate known to be inside a begin/end object.
270 */
271 ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON);
272 IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
273 return GL_FALSE;
274
275 case VERT_BEGIN_0:
276 case VERT_BEGIN_1:
277 /* This is a display-list immediate in an unknown begin/end
278 * state. Assert it is empty and convert it to a 'hard' one.
279 */
280 ASSERT(IM->SavedBeginState == 0);
281 ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN);
282
283 /* Push current beginstate, to be restored later. Don't worry
284 * about raising errors.
285 */
286 IM->SavedBeginState = IM->BeginState;
287
288 /* FALLTHROUGH */
289
290 case 0:
291 /* Unless we have fallen through, this is an immediate known to
292 * be outside begin/end objects.
293 */
294 ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN ||
295 ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END);
296 ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
297
298 IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
299 IM->Flag[IM->Count] |= VERT_BIT_BEGIN;
300 IM->Primitive[IM->Count] = p | PRIM_BEGIN;
301 IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
302 IM->LastPrimitive = IM->Count;
303
304 /* This is necessary as this immediate will not be flushed in
305 * _tnl_end() -- we leave it active, hoping to pick up more
306 * vertices before the next state change.
307 */
308 ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
309 return GL_TRUE;
310
311 default:
312 assert (0);
313 return GL_TRUE;
314 }
315 }
316 }
317
318
319
320
321
322
323 /* Both streams now outside begin/end.
324 *
325 * Leave SavedBeginState untouched -- attempt to gather several
326 * rects/arrays together in a single immediate struct.
327 */
328 void
329 _tnl_end( GLcontext *ctx )
330 {
331 struct immediate *IM = TNL_CURRENT_IM(ctx);
332 GLuint state = IM->BeginState;
333 GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1);
334
335 assert( ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES );
336
337 state |= inflags << 2; /* errors */
338
339 if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
340 {
341 GLuint count = IM->Count;
342 GLuint last = IM->LastPrimitive;
343
344 state &= ~(VERT_BEGIN_0|VERT_BEGIN_1); /* update state */
345 IM->Flag[count] |= VERT_BIT_END;
346 IM->Primitive[last] |= PRIM_END;
347 IM->PrimitiveLength[last] = count - last;
348 IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END; /* removes PRIM_BEGIN
349 * flag if length == 0
350 */
351 IM->LastPrimitive = count;
352
353 if (IM->FlushElt == FLUSH_ELT_EAGER) {
354 _tnl_translate_array_elts( ctx, IM, last, count );
355 }
356 }
357
358 IM->BeginState = state;
359
360 if (!ctx->CompileFlag) {
361 if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END)
362 _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_End" );
363 else
364 ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
365 }
366
367 /* You can set this flag to get the old 'flush_vb on glEnd()'
368 * behaviour.
369 */
370 if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
371 _tnl_flush_immediate( ctx, IM );
372 }
373
374 void
375 _tnl_End(void)
376 {
377 GET_CURRENT_CONTEXT(ctx);
378
379 _tnl_end( ctx );
380
381 /* Need to keep save primitive uptodate in COMPILE and
382 * COMPILE_AND_EXEC modes, need to keep exec primitive uptodate
383 * otherwise.
384 */
385 if (ctx->CompileFlag)
386 ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
387 }
388
389
390 #define COLOR( r, g, b, a ) \
391 { \
392 GET_IMMEDIATE; \
393 GLuint count = IM->Count; \
394 GLfloat *color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \
395 IM->Flag[count] |= VERT_BIT_COLOR0; \
396 color[0] = r; \
397 color[1] = g; \
398 color[2] = b; \
399 color[3] = a; \
400 }
401
402 static void
403 _tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue )
404 {
405 COLOR( red, green, blue, 1.0 );
406 }
407
408 static void
409 _tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue )
410 {
411 COLOR(UBYTE_TO_FLOAT(red),
412 UBYTE_TO_FLOAT(green),
413 UBYTE_TO_FLOAT(blue),
414 1.0);
415 }
416
417 static void
418 _tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
419 {
420 COLOR( red, green, blue, alpha );
421 }
422
423 static void
424 _tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
425 {
426 COLOR(UBYTE_TO_FLOAT(red),
427 UBYTE_TO_FLOAT(green),
428 UBYTE_TO_FLOAT(blue),
429 UBYTE_TO_FLOAT(alpha));
430 }
431
432 static void
433 _tnl_Color3fv( const GLfloat *v )
434 {
435 COLOR( v[0], v[1], v[2], 1.0 );
436 }
437
438 static void
439 _tnl_Color3ubv( const GLubyte *v )
440 {
441 COLOR(UBYTE_TO_FLOAT(v[0]),
442 UBYTE_TO_FLOAT(v[1]),
443 UBYTE_TO_FLOAT(v[2]),
444 1.0 );
445 }
446
447 static void
448 _tnl_Color4fv( const GLfloat *v )
449 {
450 COLOR( v[0], v[1], v[2], v[3] );
451 }
452
453 static void
454 _tnl_Color4ubv( const GLubyte *v)
455 {
456 COLOR(UBYTE_TO_FLOAT(v[0]),
457 UBYTE_TO_FLOAT(v[1]),
458 UBYTE_TO_FLOAT(v[2]),
459 UBYTE_TO_FLOAT(v[3]));
460 }
461
462
463
464
465 #define SECONDARY_COLOR( r, g, b ) \
466 { \
467 GLuint count; \
468 GET_IMMEDIATE; \
469 count = IM->Count; \
470 IM->Flag[count] |= VERT_BIT_COLOR1; \
471 IM->Attrib[VERT_ATTRIB_COLOR1][count][0] = r; \
472 IM->Attrib[VERT_ATTRIB_COLOR1][count][1] = g; \
473 IM->Attrib[VERT_ATTRIB_COLOR1][count][2] = b; \
474 }
475
476 static void
477 _tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue )
478 {
479 SECONDARY_COLOR( red, green, blue );
480 }
481
482 static void
483 _tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue )
484 {
485 SECONDARY_COLOR(UBYTE_TO_FLOAT(red),
486 UBYTE_TO_FLOAT(green),
487 UBYTE_TO_FLOAT(blue));
488 }
489
490 static void
491 _tnl_SecondaryColor3fvEXT( const GLfloat *v )
492 {
493 SECONDARY_COLOR( v[0], v[1], v[2] );
494 }
495
496 static void
497 _tnl_SecondaryColor3ubvEXT( const GLubyte *v )
498 {
499 SECONDARY_COLOR(UBYTE_TO_FLOAT(v[0]),
500 UBYTE_TO_FLOAT(v[1]),
501 UBYTE_TO_FLOAT(v[2]));
502 }
503
504
505 static void
506 _tnl_EdgeFlag( GLboolean flag )
507 {
508 GLuint count;
509 GET_IMMEDIATE;
510 count = IM->Count;
511 IM->EdgeFlag[count] = flag;
512 IM->Flag[count] |= VERT_BIT_EDGEFLAG;
513 }
514
515
516 static void
517 _tnl_EdgeFlagv( const GLboolean *flag )
518 {
519 GLuint count;
520 GET_IMMEDIATE;
521 count = IM->Count;
522 IM->EdgeFlag[count] = *flag;
523 IM->Flag[count] |= VERT_BIT_EDGEFLAG;
524 }
525
526
527 static void
528 _tnl_FogCoordfEXT( GLfloat f )
529 {
530 GLuint count;
531 GET_IMMEDIATE;
532 count = IM->Count;
533 IM->Attrib[VERT_ATTRIB_FOG][count][0] = f; /*FogCoord[count] = f;*/
534 IM->Flag[count] |= VERT_BIT_FOG;
535 }
536
537 static void
538 _tnl_FogCoordfvEXT( const GLfloat *v )
539 {
540 GLuint count;
541 GET_IMMEDIATE;
542 count = IM->Count;
543 IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0]; /*FogCoord[count] = v[0];*/
544 IM->Flag[count] |= VERT_BIT_FOG;
545 }
546
547
548 static void
549 _tnl_Indexi( GLint c )
550 {
551 GLuint count;
552 GET_IMMEDIATE;
553 count = IM->Count;
554 IM->Index[count] = c;
555 IM->Flag[count] |= VERT_BIT_INDEX;
556 }
557
558
559 static void
560 _tnl_Indexiv( const GLint *c )
561 {
562 GLuint count;
563 GET_IMMEDIATE;
564 count = IM->Count;
565 IM->Index[count] = *c;
566 IM->Flag[count] |= VERT_BIT_INDEX;
567 }
568
569
570 #define NORMAL( x, y, z ) \
571 { \
572 GLuint count; \
573 GLfloat *normal; \
574 GET_IMMEDIATE; \
575 count = IM->Count; \
576 IM->Flag[count] |= VERT_BIT_NORMAL; \
577 normal = IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
578 ASSIGN_3V(normal, x,y,z); \
579 }
580
581 #if defined(USE_IEEE)
582 #define NORMALF( x, y, z ) \
583 { \
584 GLuint count; \
585 fi_type *normal; \
586 GET_IMMEDIATE; \
587 count = IM->Count; \
588 IM->Flag[count] |= VERT_BIT_NORMAL; \
589 normal = (fi_type *)IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
590 normal[0].i = ((fi_type *)&(x))->i; \
591 normal[1].i = ((fi_type *)&(y))->i; \
592 normal[2].i = ((fi_type *)&(z))->i; \
593 }
594 #else
595 #define NORMALF NORMAL
596 #endif
597
598 static void
599 _tnl_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz )
600 {
601 NORMALF(nx, ny, nz);
602 }
603
604
605 static void
606 _tnl_Normal3fv( const GLfloat *v )
607 {
608 NORMALF( v[0], v[1], v[2] );
609 /* struct immediate *IM = (struct immediate *)(((GLcontext *) _glapi_Context)->swtnl_im); */
610 /* IM->Flag[IM->Count] = VERT_NORM; */
611 }
612
613
614
615 #define TEXCOORD1(s) \
616 { \
617 GLuint count; \
618 GLfloat *tc; \
619 GET_IMMEDIATE; \
620 count = IM->Count; \
621 IM->Flag[count] |= VERT_BIT_TEX0; \
622 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
623 ASSIGN_4V(tc,s,0,0,1); \
624 }
625
626 #define TEXCOORD2(s, t) \
627 { \
628 GLuint count; \
629 GLfloat *tc; \
630 GET_IMMEDIATE; \
631 count = IM->Count; \
632 IM->Flag[count] |= VERT_BIT_TEX0; \
633 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
634 ASSIGN_4V(tc, s, t, 0, 1); \
635 }
636
637 #define TEXCOORD3(s, t, u) \
638 { \
639 GLuint count; \
640 GLfloat *tc; \
641 GET_IMMEDIATE; \
642 count = IM->Count; \
643 IM->Flag[count] |= VERT_BIT_TEX0; \
644 IM->TexSize |= TEX_0_SIZE_3; \
645 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
646 ASSIGN_4V(tc, s, t, u, 1); \
647 }
648
649 #define TEXCOORD4(s, t, u, v) \
650 { \
651 GLuint count; \
652 GLfloat *tc; \
653 GET_IMMEDIATE; \
654 count = IM->Count; \
655 IM->Flag[count] |= VERT_BIT_TEX0; \
656 IM->TexSize |= TEX_0_SIZE_4; \
657 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
658 ASSIGN_4V(tc, s, t, u, v); \
659 }
660
661 #if defined(USE_IEEE)
662 #define TEXCOORD2F(s, t) \
663 { \
664 GLuint count; \
665 fi_type *tc; \
666 GET_IMMEDIATE; \
667 count = IM->Count; \
668 IM->Flag[count] |= VERT_BIT_TEX0; \
669 tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0][count]; \
670 tc[0].i = ((fi_type *)&(s))->i; \
671 tc[1].i = ((fi_type *)&(t))->i; \
672 tc[2].i = 0; \
673 tc[3].i = IEEE_ONE; \
674 }
675 #else
676 #define TEXCOORD2F TEXCOORD2
677 #endif
678
679 static void
680 _tnl_TexCoord1f( GLfloat s )
681 {
682 TEXCOORD1(s);
683 }
684
685
686 static void
687 _tnl_TexCoord2f( GLfloat s, GLfloat t )
688 {
689 TEXCOORD2F(s, t);
690 }
691
692
693 static void
694 _tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
695 {
696 TEXCOORD3(s, t, r);
697 }
698
699 static void
700 _tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
701 {
702 TEXCOORD4(s, t, r, q)
703 }
704
705 static void
706 _tnl_TexCoord1fv( const GLfloat *v )
707 {
708 TEXCOORD1(v[0]);
709 }
710
711 static void
712 _tnl_TexCoord2fv( const GLfloat *v )
713 {
714 TEXCOORD2F(v[0], v[1]);
715 }
716
717 static void
718 _tnl_TexCoord3fv( const GLfloat *v )
719 {
720 TEXCOORD3(v[0], v[1], v[2]);
721 }
722
723 static void
724 _tnl_TexCoord4fv( const GLfloat *v )
725 {
726 TEXCOORD4(v[0], v[1], v[2], v[3]);
727 }
728
729
730
731 /* KW: Run into bad problems in vertex copying if we don't fully pad
732 * the incoming vertices.
733 */
734 #define VERTEX2(IM, x,y) \
735 { \
736 GLuint count = IM->Count++; \
737 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
738 IM->Flag[count] |= VERT_BIT_POS; \
739 ASSIGN_4V(dest, x, y, 0, 1); \
740 /* ASSERT(IM->Flag[IM->Count]==0); */ \
741 if (count == IMM_MAXDATA - 1) \
742 _tnl_flush_immediate( NULL, IM ); \
743 }
744
745 #define VERTEX3(IM,x,y,z) \
746 { \
747 GLuint count = IM->Count++; \
748 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
749 IM->Flag[count] |= VERT_BITS_OBJ_23; \
750 ASSIGN_4V(dest, x, y, z, 1); \
751 /* ASSERT(IM->Flag[IM->Count]==0); */ \
752 if (count == IMM_MAXDATA - 1) \
753 _tnl_flush_immediate( NULL, IM ); \
754 }
755
756 #define VERTEX4(IM, x,y,z,w) \
757 { \
758 GLuint count = IM->Count++; \
759 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
760 IM->Flag[count] |= VERT_BITS_OBJ_234; \
761 ASSIGN_4V(dest, x, y, z, w); \
762 if (count == IMM_MAXDATA - 1) \
763 _tnl_flush_immediate( NULL, IM ); \
764 }
765
766 #if defined(USE_IEEE)
767 #define VERTEX2F(IM, x, y) \
768 { \
769 GLuint count = IM->Count++; \
770 fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
771 IM->Flag[count] |= VERT_BIT_POS; \
772 dest[0].i = ((fi_type *)&(x))->i; \
773 dest[1].i = ((fi_type *)&(y))->i; \
774 dest[2].i = 0; \
775 dest[3].i = IEEE_ONE; \
776 /* ASSERT(IM->Flag[IM->Count]==0); */ \
777 if (count == IMM_MAXDATA - 1) \
778 _tnl_flush_immediate( NULL, IM ); \
779 }
780 #else
781 #define VERTEX2F VERTEX2
782 #endif
783
784 #if defined(USE_IEEE)
785 #define VERTEX3F(IM, x, y, z) \
786 { \
787 GLuint count = IM->Count++; \
788 fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
789 IM->Flag[count] |= VERT_BITS_OBJ_23; \
790 dest[0].i = ((fi_type *)&(x))->i; \
791 dest[1].i = ((fi_type *)&(y))->i; \
792 dest[2].i = ((fi_type *)&(z))->i; \
793 dest[3].i = IEEE_ONE; \
794 /* ASSERT(IM->Flag[IM->Count]==0); */ \
795 if (count == IMM_MAXDATA - 1) \
796 _tnl_flush_immediate( NULL, IM ); \
797 }
798 #else
799 #define VERTEX3F VERTEX3
800 #endif
801
802 #if defined(USE_IEEE)
803 #define VERTEX4F(IM, x, y, z, w) \
804 { \
805 GLuint count = IM->Count++; \
806 fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
807 IM->Flag[count] |= VERT_BITS_OBJ_234; \
808 dest[0].i = ((fi_type *)&(x))->i; \
809 dest[1].i = ((fi_type *)&(y))->i; \
810 dest[2].i = ((fi_type *)&(z))->i; \
811 dest[3].i = ((fi_type *)&(w))->i; \
812 if (count == IMM_MAXDATA - 1) \
813 _tnl_flush_immediate( NULL, IM ); \
814 }
815 #else
816 #define VERTEX4F VERTEX4
817 #endif
818
819
820
821 static void
822 _tnl_Vertex2f( GLfloat x, GLfloat y )
823 {
824 GET_IMMEDIATE;
825 VERTEX2F( IM, x, y );
826 }
827
828 static void
829 _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
830 {
831 GET_IMMEDIATE;
832 VERTEX3F( IM, x, y, z );
833 }
834 static void
835 _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
836 {
837 GET_IMMEDIATE;
838 VERTEX4F( IM, x, y, z, w );
839 }
840
841 static void
842 _tnl_Vertex2fv( const GLfloat *v )
843 {
844 GET_IMMEDIATE;
845 VERTEX2F( IM, v[0], v[1] );
846 }
847
848 static void
849 _tnl_Vertex3fv( const GLfloat *v )
850 {
851 GET_IMMEDIATE;
852 VERTEX3F( IM, v[0], v[1], v[2] );
853 }
854
855 static void
856 _tnl_Vertex4fv( const GLfloat *v )
857 {
858 GET_IMMEDIATE;
859 VERTEX4F( IM, v[0], v[1], v[2], v[3] );
860 }
861
862
863
864
865 /*
866 * GL_ARB_multitexture
867 *
868 * Note: the multitexture spec says that specifying an invalid target
869 * has undefined results and does not have to generate an error. Just
870 * don't crash. We no-op on invalid targets.
871 */
872
873 #define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
874
875 #define MULTI_TEXCOORD1(target, s) \
876 { \
877 GET_IMMEDIATE; \
878 GLuint texunit = target - GL_TEXTURE0_ARB; \
879 if (texunit < IM->MaxTextureUnits) { \
880 GLuint count = IM->Count; \
881 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
882 ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \
883 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
884 } \
885 }
886
887 #define MULTI_TEXCOORD2(target, s, t) \
888 { \
889 GET_IMMEDIATE; \
890 GLuint texunit = target - GL_TEXTURE0_ARB; \
891 if (texunit < IM->MaxTextureUnits) { \
892 GLuint count = IM->Count; \
893 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
894 ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \
895 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
896 } \
897 }
898
899 #define MULTI_TEXCOORD3(target, s, t, u) \
900 { \
901 GET_IMMEDIATE; \
902 GLuint texunit = target - GL_TEXTURE0_ARB; \
903 if (texunit < IM->MaxTextureUnits) { \
904 GLuint count = IM->Count; \
905 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
906 ASSIGN_4V(tc, s, t, u, 1.0F); \
907 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
908 IM->TexSize |= TEX_SIZE_3(texunit); \
909 } \
910 }
911
912 #define MULTI_TEXCOORD4(target, s, t, u, v) \
913 { \
914 GET_IMMEDIATE; \
915 GLuint texunit = target - GL_TEXTURE0_ARB; \
916 if (texunit < IM->MaxTextureUnits) { \
917 GLuint count = IM->Count; \
918 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
919 ASSIGN_4V(tc, s, t, u, v); \
920 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
921 IM->TexSize |= TEX_SIZE_4(texunit); \
922 } \
923 }
924
925 #if defined(USE_IEEE)
926 #define MULTI_TEXCOORD2F(target, s, t) \
927 { \
928 GET_IMMEDIATE; \
929 GLuint texunit = target - GL_TEXTURE0_ARB; \
930 if (texunit < IM->MaxTextureUnits) { \
931 GLuint count = IM->Count; \
932 fi_type *tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];\
933 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
934 tc[0].i = ((fi_type *)&(s))->i; \
935 tc[1].i = ((fi_type *)&(t))->i; \
936 tc[2].i = 0; \
937 tc[3].i = IEEE_ONE; \
938 } \
939 }
940 #else
941 #define MULTI_TEXCOORD2F MULTI_TEXCOORD2
942 #endif
943
944 static void
945 _tnl_MultiTexCoord1fARB(GLenum target, GLfloat s)
946 {
947 MULTI_TEXCOORD1( target, s );
948 }
949
950 static void
951 _tnl_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
952 {
953 MULTI_TEXCOORD1( target, v[0] );
954 }
955
956 static void
957 _tnl_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
958 {
959 MULTI_TEXCOORD2F( target, s, t );
960 }
961
962 static void
963 _tnl_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
964 {
965 MULTI_TEXCOORD2F( target, v[0], v[1] );
966 }
967
968 static void
969 _tnl_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
970 {
971 MULTI_TEXCOORD3( target, s, t, r );
972 }
973
974 static void
975 _tnl_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
976 {
977 MULTI_TEXCOORD3( target, v[0], v[1], v[2] );
978 }
979
980 static void
981 _tnl_MultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
982 {
983 MULTI_TEXCOORD4( target, s, t, r, q );
984 }
985
986 static void
987 _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v)
988 {
989 MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] );
990 }
991
992
993
994 /* KW: Because the eval values don't become 'current', fixup will flow
995 * through these vertices, and then evaluation will write on top
996 * of the fixup results.
997 *
998 * Note: using Obj to hold eval coord data.
999 */
1000 #define EVALCOORD1(IM, x) \
1001 { \
1002 GLuint count = IM->Count++; \
1003 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1004 IM->Flag[count] |= VERT_BIT_EVAL_C1; \
1005 ASSIGN_4V(dest, x, 0, 0, 1); \
1006 if (count == IMM_MAXDATA-1) \
1007 _tnl_flush_immediate( NULL, IM ); \
1008 }
1009
1010 #define EVALCOORD2(IM, x, y) \
1011 { \
1012 GLuint count = IM->Count++; \
1013 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1014 IM->Flag[count] |= VERT_BIT_EVAL_C2; \
1015 ASSIGN_4V(dest, x, y, 0, 1); \
1016 if (count == IMM_MAXDATA-1) \
1017 _tnl_flush_immediate( NULL, IM ); \
1018 }
1019
1020 #define EVALPOINT1(IM, x) \
1021 { \
1022 GLuint count = IM->Count++; \
1023 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1024 IM->Flag[count] |= VERT_BIT_EVAL_P1; \
1025 ASSIGN_4V(dest, x, 0, 0, 1); \
1026 if (count == IMM_MAXDATA-1) \
1027 _tnl_flush_immediate( NULL, IM ); \
1028 }
1029
1030 #define EVALPOINT2(IM, x, y) \
1031 { \
1032 GLuint count = IM->Count++; \
1033 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1034 IM->Flag[count] |= VERT_BIT_EVAL_P2; \
1035 ASSIGN_4V(dest, x, y, 0, 1); \
1036 if (count == IMM_MAXDATA-1) \
1037 _tnl_flush_immediate( NULL, IM ); \
1038 }
1039
1040 static void
1041 _tnl_EvalCoord1f( GLfloat u )
1042 {
1043 GET_IMMEDIATE;
1044 EVALCOORD1( IM, u );
1045 }
1046
1047 static void
1048 _tnl_EvalCoord1fv( const GLfloat *u )
1049 {
1050 GET_IMMEDIATE;
1051 EVALCOORD1( IM, (GLfloat) *u );
1052 }
1053
1054 static void
1055 _tnl_EvalCoord2f( GLfloat u, GLfloat v )
1056 {
1057 GET_IMMEDIATE;
1058 EVALCOORD2( IM, u, v );
1059 }
1060
1061 static void
1062 _tnl_EvalCoord2fv( const GLfloat *u )
1063 {
1064 GET_IMMEDIATE;
1065 EVALCOORD2( IM, u[0], u[1] );
1066 }
1067
1068
1069 static void
1070 _tnl_EvalPoint1( GLint i )
1071 {
1072 GET_IMMEDIATE;
1073 EVALPOINT1( IM, (GLfloat) i );
1074 }
1075
1076
1077 static void
1078 _tnl_EvalPoint2( GLint i, GLint j )
1079 {
1080 GET_IMMEDIATE;
1081 EVALPOINT2( IM, (GLfloat) i, (GLfloat) j );
1082 }
1083
1084
1085 /* Need to use the default array-elt outside begin/end for strict
1086 * conformance.
1087 */
1088 #define ARRAY_ELT( IM, i ) \
1089 { \
1090 GLuint count = IM->Count; \
1091 IM->Elt[count] = i; \
1092 IM->Flag[count] &= IM->ArrayEltFlags; \
1093 IM->Flag[count] |= VERT_BIT_ELT; \
1094 IM->FlushElt = IM->ArrayEltFlush; \
1095 IM->Count += IM->ArrayEltIncr; \
1096 if (IM->Count == IMM_MAXDATA) \
1097 _tnl_flush_immediate( NULL, IM ); \
1098 }
1099
1100
1101 static void
1102 _tnl_ArrayElement( GLint i )
1103 {
1104 GET_IMMEDIATE;
1105 ARRAY_ELT( IM, i );
1106 }
1107
1108
1109 /* Internal functions. These are safe to use providing either:
1110 *
1111 * - It is determined that a display list is not being compiled, or
1112 * if so that these commands won't be compiled into the list (see
1113 * t_eval.c for an example).
1114 *
1115 * - _tnl_hard_begin() is used instead of _tnl_[bB]egin, and tested
1116 * for a GL_TRUE return value. See _tnl_Rectf, below.
1117 */
1118 void
1119 _tnl_eval_coord1f( GLcontext *CC, GLfloat u )
1120 {
1121 struct immediate *i = TNL_CURRENT_IM(CC);
1122 EVALCOORD1( i, u );
1123 }
1124
1125 void
1126 _tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
1127 {
1128 struct immediate *i = TNL_CURRENT_IM(CC);
1129 EVALCOORD2( i, u, v );
1130 }
1131
1132
1133
1134
1135 /*
1136 * NV_vertex_program
1137 */
1138
1139 static void
1140 _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
1141 {
1142 if (index < 16) {
1143 GET_IMMEDIATE;
1144 const GLuint count = IM->Count;
1145 GLfloat *attrib = IM->Attrib[index][count];
1146 ASSIGN_4V(attrib, x, y, z, w);
1147 IM->Flag[count] |= (1 << index);
1148 if (index == 0) {
1149 IM->Count++;
1150 if (count == IMM_MAXDATA - 1)
1151 _tnl_flush_immediate( NULL, IM );
1152 }
1153 }
1154 else {
1155 GET_CURRENT_CONTEXT(ctx);
1156 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
1157 }
1158 }
1159
1160 static void
1161 _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
1162 {
1163 if (index < 16) {
1164 GET_IMMEDIATE;
1165 const GLuint count = IM->Count;
1166 GLfloat *attrib = IM->Attrib[index][count];
1167 COPY_4V(attrib, v);
1168 IM->Flag[count] |= (1 << index);
1169 if (index == 0) {
1170 IM->Count++;
1171 if (count == IMM_MAXDATA - 1)
1172 _tnl_flush_immediate( NULL, IM );
1173 }
1174 }
1175 else {
1176 GET_CURRENT_CONTEXT(ctx);
1177 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
1178 }
1179 }
1180
1181
1182 /* Execute a glRectf() function. _tnl_hard_begin() ensures the check
1183 * on outside_begin_end is executed even in compiled lists. These
1184 * vertices can now participate in the same immediate as regular ones,
1185 * even in most display lists.
1186 */
1187 static void
1188 _tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
1189 {
1190 GET_CURRENT_CONTEXT(ctx);
1191
1192 if (_tnl_hard_begin( ctx, GL_QUADS )) {
1193 glVertex2f( x1, y1 );
1194 glVertex2f( x2, y1 );
1195 glVertex2f( x2, y2 );
1196 glVertex2f( x1, y2 );
1197 glEnd();
1198 }
1199 }
1200
1201 static void
1202 _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
1203 {
1204 GET_CURRENT_CONTEXT(ctx);
1205 TNLcontext *tnl = TNL_CONTEXT(ctx);
1206 struct immediate *IM = TNL_CURRENT_IM(ctx);
1207 GLuint count = IM->Count;
1208 struct gl_material *mat;
1209 GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv");
1210
1211 if (bitmask == 0)
1212 return;
1213
1214 if (MESA_VERBOSE & VERBOSE_API)
1215 _mesa_debug(ctx, "_tnl_Materialfv\n");
1216
1217 if (tnl->IsolateMaterials &&
1218 !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
1219 {
1220 _tnl_flush_immediate( ctx, IM );
1221 IM = TNL_CURRENT_IM(ctx);
1222 count = IM->Count;
1223 }
1224
1225 if (!(IM->Flag[count] & VERT_BIT_MATERIAL)) {
1226 if (!IM->Material) {
1227 IM->Material = (struct gl_material (*)[2])
1228 MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
1229 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
1230 IM->MaterialMask[IM->LastMaterial] = 0;
1231 }
1232 else if (IM->MaterialOrMask & ~bitmask) {
1233 _mesa_copy_material_pairs( IM->Material[count],
1234 IM->Material[IM->LastMaterial],
1235 IM->MaterialOrMask & ~bitmask );
1236 }
1237
1238 IM->Flag[count] |= VERT_BIT_MATERIAL;
1239 IM->MaterialMask[count] = 0;
1240 IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
1241 IM->LastMaterial = count;
1242 }
1243
1244 IM->MaterialOrMask |= bitmask;
1245 IM->MaterialMask[count] |= bitmask;
1246 mat = IM->Material[count];
1247
1248 if (bitmask & FRONT_AMBIENT_BIT) {
1249 COPY_4FV( mat[0].Ambient, params );
1250 }
1251 if (bitmask & BACK_AMBIENT_BIT) {
1252 COPY_4FV( mat[1].Ambient, params );
1253 }
1254 if (bitmask & FRONT_DIFFUSE_BIT) {
1255 COPY_4FV( mat[0].Diffuse, params );
1256 }
1257 if (bitmask & BACK_DIFFUSE_BIT) {
1258 COPY_4FV( mat[1].Diffuse, params );
1259 }
1260 if (bitmask & FRONT_SPECULAR_BIT) {
1261 COPY_4FV( mat[0].Specular, params );
1262 }
1263 if (bitmask & BACK_SPECULAR_BIT) {
1264 COPY_4FV( mat[1].Specular, params );
1265 }
1266 if (bitmask & FRONT_EMISSION_BIT) {
1267 COPY_4FV( mat[0].Emission, params );
1268 }
1269 if (bitmask & BACK_EMISSION_BIT) {
1270 COPY_4FV( mat[1].Emission, params );
1271 }
1272 if (bitmask & FRONT_SHININESS_BIT) {
1273 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
1274 mat[0].Shininess = shininess;
1275 }
1276 if (bitmask & BACK_SHININESS_BIT) {
1277 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
1278 mat[1].Shininess = shininess;
1279 }
1280 if (bitmask & FRONT_INDEXES_BIT) {
1281 mat[0].AmbientIndex = params[0];
1282 mat[0].DiffuseIndex = params[1];
1283 mat[0].SpecularIndex = params[2];
1284 }
1285 if (bitmask & BACK_INDEXES_BIT) {
1286 mat[1].AmbientIndex = params[0];
1287 mat[1].DiffuseIndex = params[1];
1288 mat[1].SpecularIndex = params[2];
1289 }
1290
1291 if (tnl->IsolateMaterials &&
1292 !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
1293 {
1294 _tnl_flush_immediate( ctx, IM );
1295 }
1296 }
1297
1298 void _tnl_imm_vtxfmt_init( GLcontext *ctx )
1299 {
1300 GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
1301
1302 /* All begin/end operations are handled by this vertex format:
1303 */
1304 vfmt->ArrayElement = _tnl_ArrayElement;
1305 vfmt->Begin = _tnl_Begin;
1306 vfmt->Color3f = _tnl_Color3f;
1307 vfmt->Color3fv = _tnl_Color3fv;
1308 vfmt->Color3ub = _tnl_Color3ub;
1309 vfmt->Color3ubv = _tnl_Color3ubv;
1310 vfmt->Color4f = _tnl_Color4f;
1311 vfmt->Color4fv = _tnl_Color4fv;
1312 vfmt->Color4ub = _tnl_Color4ub;
1313 vfmt->Color4ubv = _tnl_Color4ubv;
1314 vfmt->EdgeFlag = _tnl_EdgeFlag;
1315 vfmt->EdgeFlagv = _tnl_EdgeFlagv;
1316 vfmt->End = _tnl_End;
1317 vfmt->EvalCoord1f = _tnl_EvalCoord1f;
1318 vfmt->EvalCoord1fv = _tnl_EvalCoord1fv;
1319 vfmt->EvalCoord2f = _tnl_EvalCoord2f;
1320 vfmt->EvalCoord2fv = _tnl_EvalCoord2fv;
1321 vfmt->EvalPoint1 = _tnl_EvalPoint1;
1322 vfmt->EvalPoint2 = _tnl_EvalPoint2;
1323 vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
1324 vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
1325 vfmt->Indexi = _tnl_Indexi;
1326 vfmt->Indexiv = _tnl_Indexiv;
1327 vfmt->Materialfv = _tnl_Materialfv;
1328 vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1fARB;
1329 vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fvARB;
1330 vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2fARB;
1331 vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fvARB;
1332 vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3fARB;
1333 vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fvARB;
1334 vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4fARB;
1335 vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fvARB;
1336 vfmt->Normal3f = _tnl_Normal3f;
1337 vfmt->Normal3fv = _tnl_Normal3fv;
1338 vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
1339 vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
1340 vfmt->SecondaryColor3ubEXT = _tnl_SecondaryColor3ubEXT;
1341 vfmt->SecondaryColor3ubvEXT = _tnl_SecondaryColor3ubvEXT;
1342 vfmt->TexCoord1f = _tnl_TexCoord1f;
1343 vfmt->TexCoord1fv = _tnl_TexCoord1fv;
1344 vfmt->TexCoord2f = _tnl_TexCoord2f;
1345 vfmt->TexCoord2fv = _tnl_TexCoord2fv;
1346 vfmt->TexCoord3f = _tnl_TexCoord3f;
1347 vfmt->TexCoord3fv = _tnl_TexCoord3fv;
1348 vfmt->TexCoord4f = _tnl_TexCoord4f;
1349 vfmt->TexCoord4fv = _tnl_TexCoord4fv;
1350 vfmt->Vertex2f = _tnl_Vertex2f;
1351 vfmt->Vertex2fv = _tnl_Vertex2fv;
1352 vfmt->Vertex3f = _tnl_Vertex3f;
1353 vfmt->Vertex3fv = _tnl_Vertex3fv;
1354 vfmt->Vertex4f = _tnl_Vertex4f;
1355 vfmt->Vertex4fv = _tnl_Vertex4fv;
1356 vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
1357 vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
1358
1359 /* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
1360 */
1361 vfmt->Rectf = _tnl_Rectf;
1362
1363 /* Just use the core function:
1364 */
1365 vfmt->CallList = _mesa_CallList;
1366
1367 vfmt->prefer_float_colors = GL_FALSE;
1368 }