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