improved error string
[mesa.git] / src / mesa / tnl / t_imm_api.c
1 /* $Id: t_imm_api.c,v 1.31 2002/09/03 18:05:52 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 <keithw@valinux.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 "mem.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_BEGIN|VERT_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 _tnl_end( ctx );
379
380 /* Need to keep save primitive uptodate in COMPILE and
381 * COMPILE_AND_EXEC modes, need to keep exec primitive uptodate
382 * otherwise.
383 */
384 if (ctx->CompileFlag)
385 ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
386 }
387
388
389 #define COLOR( r, g, b, a ) \
390 { \
391 GET_IMMEDIATE; \
392 GLuint count = IM->Count; \
393 GLfloat *color = IM->Attrib[VERT_ATTRIB_COLOR0][count]; \
394 IM->Flag[count] |= VERT_BIT_COLOR0; \
395 color[0] = r; \
396 color[1] = g; \
397 color[2] = b; \
398 color[3] = a; \
399 }
400
401 static void
402 _tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue )
403 {
404 COLOR( red, green, blue, 1.0 );
405 }
406
407 static void
408 _tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue )
409 {
410 COLOR(UBYTE_TO_FLOAT(red),
411 UBYTE_TO_FLOAT(green),
412 UBYTE_TO_FLOAT(blue),
413 1.0);
414 }
415
416 static void
417 _tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
418 {
419 COLOR( red, green, blue, alpha );
420 }
421
422 static void
423 _tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
424 {
425 COLOR(UBYTE_TO_FLOAT(red),
426 UBYTE_TO_FLOAT(green),
427 UBYTE_TO_FLOAT(blue),
428 UBYTE_TO_FLOAT(alpha));
429 }
430
431 static void
432 _tnl_Color3fv( const GLfloat *v )
433 {
434 COLOR( v[0], v[1], v[2], 1.0 );
435 }
436
437 static void
438 _tnl_Color3ubv( const GLubyte *v )
439 {
440 COLOR(UBYTE_TO_FLOAT(v[0]),
441 UBYTE_TO_FLOAT(v[1]),
442 UBYTE_TO_FLOAT(v[2]),
443 1.0 );
444 }
445
446 static void
447 _tnl_Color4fv( const GLfloat *v )
448 {
449 COLOR( v[0], v[1], v[2], v[3] );
450 }
451
452 static void
453 _tnl_Color4ubv( const GLubyte *v)
454 {
455 COLOR(UBYTE_TO_FLOAT(v[0]),
456 UBYTE_TO_FLOAT(v[1]),
457 UBYTE_TO_FLOAT(v[2]),
458 UBYTE_TO_FLOAT(v[3]));
459 }
460
461
462
463
464 #define SECONDARY_COLOR( r, g, b ) \
465 { \
466 GLuint count; \
467 GET_IMMEDIATE; \
468 count = IM->Count; \
469 IM->Flag[count] |= VERT_BIT_COLOR1; \
470 IM->Attrib[VERT_ATTRIB_COLOR1][count][0] = r; \
471 IM->Attrib[VERT_ATTRIB_COLOR1][count][1] = g; \
472 IM->Attrib[VERT_ATTRIB_COLOR1][count][2] = b; \
473 }
474
475 static void
476 _tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue )
477 {
478 SECONDARY_COLOR( red, green, blue );
479 }
480
481 static void
482 _tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue )
483 {
484 SECONDARY_COLOR(UBYTE_TO_FLOAT(red),
485 UBYTE_TO_FLOAT(green),
486 UBYTE_TO_FLOAT(blue));
487 }
488
489 static void
490 _tnl_SecondaryColor3fvEXT( const GLfloat *v )
491 {
492 SECONDARY_COLOR( v[0], v[1], v[2] );
493 }
494
495 static void
496 _tnl_SecondaryColor3ubvEXT( const GLubyte *v )
497 {
498 SECONDARY_COLOR(UBYTE_TO_FLOAT(v[0]),
499 UBYTE_TO_FLOAT(v[1]),
500 UBYTE_TO_FLOAT(v[2]));
501 }
502
503
504 static void
505 _tnl_EdgeFlag( GLboolean flag )
506 {
507 GLuint count;
508 GET_IMMEDIATE;
509 count = IM->Count;
510 IM->EdgeFlag[count] = flag;
511 IM->Flag[count] |= VERT_BIT_EDGEFLAG;
512 }
513
514
515 static void
516 _tnl_EdgeFlagv( const GLboolean *flag )
517 {
518 GLuint count;
519 GET_IMMEDIATE;
520 count = IM->Count;
521 IM->EdgeFlag[count] = *flag;
522 IM->Flag[count] |= VERT_BIT_EDGEFLAG;
523 }
524
525
526 static void
527 _tnl_FogCoordfEXT( GLfloat f )
528 {
529 GLuint count;
530 GET_IMMEDIATE;
531 count = IM->Count;
532 IM->Attrib[VERT_ATTRIB_FOG][count][0] = f; /*FogCoord[count] = f;*/
533 IM->Flag[count] |= VERT_BIT_FOG;
534 }
535
536 static void
537 _tnl_FogCoordfvEXT( const GLfloat *v )
538 {
539 GLuint count;
540 GET_IMMEDIATE;
541 count = IM->Count;
542 IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0]; /*FogCoord[count] = v[0];*/
543 IM->Flag[count] |= VERT_BIT_FOG;
544 }
545
546
547 static void
548 _tnl_Indexi( GLint c )
549 {
550 GLuint count;
551 GET_IMMEDIATE;
552 count = IM->Count;
553 IM->Index[count] = c;
554 IM->Flag[count] |= VERT_BIT_INDEX;
555 }
556
557
558 static void
559 _tnl_Indexiv( const GLint *c )
560 {
561 GLuint count;
562 GET_IMMEDIATE;
563 count = IM->Count;
564 IM->Index[count] = *c;
565 IM->Flag[count] |= VERT_BIT_INDEX;
566 }
567
568
569 #define NORMAL( x, y, z ) \
570 { \
571 GLuint count; \
572 GLfloat *normal; \
573 GET_IMMEDIATE; \
574 count = IM->Count; \
575 IM->Flag[count] |= VERT_BIT_NORMAL; \
576 normal = IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
577 ASSIGN_3V(normal, x,y,z); \
578 }
579
580 #if defined(USE_IEEE)
581 #define NORMALF( x, y, z ) \
582 { \
583 GLuint count; \
584 fi_type *normal; \
585 GET_IMMEDIATE; \
586 count = IM->Count; \
587 IM->Flag[count] |= VERT_BIT_NORMAL; \
588 normal = (fi_type *)IM->Attrib[VERT_ATTRIB_NORMAL][count]; \
589 normal[0].i = ((fi_type *)&(x))->i; \
590 normal[1].i = ((fi_type *)&(y))->i; \
591 normal[2].i = ((fi_type *)&(z))->i; \
592 }
593 #else
594 #define NORMALF NORMAL
595 #endif
596
597 static void
598 _tnl_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz )
599 {
600 NORMALF(nx, ny, nz);
601 }
602
603
604 static void
605 _tnl_Normal3fv( const GLfloat *v )
606 {
607 NORMALF( v[0], v[1], v[2] );
608 /* struct immediate *IM = (struct immediate *)(((GLcontext *) _glapi_Context)->swtnl_im); */
609 /* IM->Flag[IM->Count] = VERT_NORM; */
610 }
611
612
613
614 #define TEXCOORD1(s) \
615 { \
616 GLuint count; \
617 GLfloat *tc; \
618 GET_IMMEDIATE; \
619 count = IM->Count; \
620 IM->Flag[count] |= VERT_BIT_TEX0; \
621 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
622 ASSIGN_4V(tc,s,0,0,1); \
623 }
624
625 #define TEXCOORD2(s, t) \
626 { \
627 GLuint count; \
628 GLfloat *tc; \
629 GET_IMMEDIATE; \
630 count = IM->Count; \
631 IM->Flag[count] |= VERT_BIT_TEX0; \
632 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
633 ASSIGN_4V(tc, s, t, 0, 1); \
634 }
635
636 #define TEXCOORD3(s, t, u) \
637 { \
638 GLuint count; \
639 GLfloat *tc; \
640 GET_IMMEDIATE; \
641 count = IM->Count; \
642 IM->Flag[count] |= VERT_BIT_TEX0; \
643 IM->TexSize |= TEX_0_SIZE_3; \
644 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
645 ASSIGN_4V(tc, s, t, u, 1); \
646 }
647
648 #define TEXCOORD4(s, t, u, v) \
649 { \
650 GLuint count; \
651 GLfloat *tc; \
652 GET_IMMEDIATE; \
653 count = IM->Count; \
654 IM->Flag[count] |= VERT_BIT_TEX0; \
655 IM->TexSize |= TEX_0_SIZE_4; \
656 tc = IM->Attrib[VERT_ATTRIB_TEX0][count]; \
657 ASSIGN_4V(tc, s, t, u, v); \
658 }
659
660 #if defined(USE_IEEE)
661 #define TEXCOORD2F(s, t) \
662 { \
663 GLuint count; \
664 fi_type *tc; \
665 GET_IMMEDIATE; \
666 count = IM->Count; \
667 IM->Flag[count] |= VERT_BIT_TEX0; \
668 tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0][count]; \
669 tc[0].i = ((fi_type *)&(s))->i; \
670 tc[1].i = ((fi_type *)&(t))->i; \
671 tc[2].i = 0; \
672 tc[3].i = IEEE_ONE; \
673 }
674 #else
675 #define TEXCOORD2F TEXCOORD2
676 #endif
677
678 static void
679 _tnl_TexCoord1f( GLfloat s )
680 {
681 TEXCOORD1(s);
682 }
683
684
685 static void
686 _tnl_TexCoord2f( GLfloat s, GLfloat t )
687 {
688 TEXCOORD2F(s, t);
689 }
690
691
692 static void
693 _tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
694 {
695 TEXCOORD3(s, t, r);
696 }
697
698 static void
699 _tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
700 {
701 TEXCOORD4(s, t, r, q)
702 }
703
704 static void
705 _tnl_TexCoord1fv( const GLfloat *v )
706 {
707 TEXCOORD1(v[0]);
708 }
709
710 static void
711 _tnl_TexCoord2fv( const GLfloat *v )
712 {
713 TEXCOORD2F(v[0], v[1]);
714 }
715
716 static void
717 _tnl_TexCoord3fv( const GLfloat *v )
718 {
719 TEXCOORD3(v[0], v[1], v[2]);
720 }
721
722 static void
723 _tnl_TexCoord4fv( const GLfloat *v )
724 {
725 TEXCOORD4(v[0], v[1], v[2], v[3]);
726 }
727
728
729
730 /* KW: Run into bad problems in vertex copying if we don't fully pad
731 * the incoming vertices.
732 */
733 #define VERTEX2(IM, x,y) \
734 { \
735 GLuint count = IM->Count++; \
736 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
737 IM->Flag[count] |= VERT_BIT_POS; \
738 ASSIGN_4V(dest, x, y, 0, 1); \
739 /* ASSERT(IM->Flag[IM->Count]==0); */ \
740 if (count == IMM_MAXDATA - 1) \
741 _tnl_flush_immediate( NULL, IM ); \
742 }
743
744 #define VERTEX3(IM,x,y,z) \
745 { \
746 GLuint count = IM->Count++; \
747 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
748 IM->Flag[count] |= VERT_BITS_OBJ_23; \
749 ASSIGN_4V(dest, x, y, z, 1); \
750 /* ASSERT(IM->Flag[IM->Count]==0); */ \
751 if (count == IMM_MAXDATA - 1) \
752 _tnl_flush_immediate( NULL, IM ); \
753 }
754
755 #define VERTEX4(IM, x,y,z,w) \
756 { \
757 GLuint count = IM->Count++; \
758 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
759 IM->Flag[count] |= VERT_BITS_OBJ_234; \
760 ASSIGN_4V(dest, x, y, z, w); \
761 if (count == IMM_MAXDATA - 1) \
762 _tnl_flush_immediate( NULL, IM ); \
763 }
764
765 #if defined(USE_IEEE)
766 #define VERTEX2F(IM, x, y) \
767 { \
768 GLuint count = IM->Count++; \
769 fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
770 IM->Flag[count] |= VERT_BIT_POS; \
771 dest[0].i = ((fi_type *)&(x))->i; \
772 dest[1].i = ((fi_type *)&(y))->i; \
773 dest[2].i = 0; \
774 dest[3].i = IEEE_ONE; \
775 /* ASSERT(IM->Flag[IM->Count]==0); */ \
776 if (count == IMM_MAXDATA - 1) \
777 _tnl_flush_immediate( NULL, IM ); \
778 }
779 #else
780 #define VERTEX2F VERTEX2
781 #endif
782
783 #if defined(USE_IEEE)
784 #define VERTEX3F(IM, x, y, z) \
785 { \
786 GLuint count = IM->Count++; \
787 fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
788 IM->Flag[count] |= VERT_BITS_OBJ_23; \
789 dest[0].i = ((fi_type *)&(x))->i; \
790 dest[1].i = ((fi_type *)&(y))->i; \
791 dest[2].i = ((fi_type *)&(z))->i; \
792 dest[3].i = IEEE_ONE; \
793 /* ASSERT(IM->Flag[IM->Count]==0); */ \
794 if (count == IMM_MAXDATA - 1) \
795 _tnl_flush_immediate( NULL, IM ); \
796 }
797 #else
798 #define VERTEX3F VERTEX3
799 #endif
800
801 #if defined(USE_IEEE)
802 #define VERTEX4F(IM, x, y, z, w) \
803 { \
804 GLuint count = IM->Count++; \
805 fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count]; \
806 IM->Flag[count] |= VERT_BITS_OBJ_234; \
807 dest[0].i = ((fi_type *)&(x))->i; \
808 dest[1].i = ((fi_type *)&(y))->i; \
809 dest[2].i = ((fi_type *)&(z))->i; \
810 dest[3].i = ((fi_type *)&(w))->i; \
811 if (count == IMM_MAXDATA - 1) \
812 _tnl_flush_immediate( NULL, IM ); \
813 }
814 #else
815 #define VERTEX4F VERTEX4
816 #endif
817
818
819
820 static void
821 _tnl_Vertex2f( GLfloat x, GLfloat y )
822 {
823 GET_IMMEDIATE;
824 VERTEX2F( IM, x, y );
825 }
826
827 static void
828 _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
829 {
830 GET_IMMEDIATE;
831 VERTEX3F( IM, x, y, z );
832 }
833 static void
834 _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
835 {
836 GET_IMMEDIATE;
837 VERTEX4F( IM, x, y, z, w );
838 }
839
840 static void
841 _tnl_Vertex2fv( const GLfloat *v )
842 {
843 GET_IMMEDIATE;
844 VERTEX2F( IM, v[0], v[1] );
845 }
846
847 static void
848 _tnl_Vertex3fv( const GLfloat *v )
849 {
850 GET_IMMEDIATE;
851 VERTEX3F( IM, v[0], v[1], v[2] );
852 }
853
854 static void
855 _tnl_Vertex4fv( const GLfloat *v )
856 {
857 GET_IMMEDIATE;
858 VERTEX4F( IM, v[0], v[1], v[2], v[3] );
859 }
860
861
862
863
864 /*
865 * GL_ARB_multitexture
866 *
867 * Note: the multitexture spec says that specifying an invalid target
868 * has undefined results and does not have to generate an error. Just
869 * don't crash. We no-op on invalid targets.
870 */
871
872 #define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
873
874 #define MULTI_TEXCOORD1(target, s) \
875 { \
876 GET_IMMEDIATE; \
877 GLuint texunit = target - GL_TEXTURE0_ARB; \
878 if (texunit < IM->MaxTextureUnits) { \
879 GLuint count = IM->Count; \
880 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
881 ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F); \
882 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
883 } \
884 }
885
886 #define MULTI_TEXCOORD2(target, s, t) \
887 { \
888 GET_IMMEDIATE; \
889 GLuint texunit = target - GL_TEXTURE0_ARB; \
890 if (texunit < IM->MaxTextureUnits) { \
891 GLuint count = IM->Count; \
892 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
893 ASSIGN_4V(tc, s, t, 0.0F, 1.0F); \
894 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
895 } \
896 }
897
898 #define MULTI_TEXCOORD3(target, s, t, u) \
899 { \
900 GET_IMMEDIATE; \
901 GLuint texunit = target - GL_TEXTURE0_ARB; \
902 if (texunit < IM->MaxTextureUnits) { \
903 GLuint count = IM->Count; \
904 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
905 ASSIGN_4V(tc, s, t, u, 1.0F); \
906 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
907 IM->TexSize |= TEX_SIZE_3(texunit); \
908 } \
909 }
910
911 #define MULTI_TEXCOORD4(target, s, t, u, v) \
912 { \
913 GET_IMMEDIATE; \
914 GLuint texunit = target - GL_TEXTURE0_ARB; \
915 if (texunit < IM->MaxTextureUnits) { \
916 GLuint count = IM->Count; \
917 GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count]; \
918 ASSIGN_4V(tc, s, t, u, v); \
919 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
920 IM->TexSize |= TEX_SIZE_4(texunit); \
921 } \
922 }
923
924 #if defined(USE_IEEE)
925 #define MULTI_TEXCOORD2F(target, s, t) \
926 { \
927 GET_IMMEDIATE; \
928 GLuint texunit = target - GL_TEXTURE0_ARB; \
929 if (texunit < IM->MaxTextureUnits) { \
930 GLuint count = IM->Count; \
931 fi_type *tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];\
932 IM->Flag[count] |= VERT_BIT_TEX(texunit); \
933 tc[0].i = ((fi_type *)&(s))->i; \
934 tc[1].i = ((fi_type *)&(t))->i; \
935 tc[2].i = 0; \
936 tc[3].i = IEEE_ONE; \
937 } \
938 }
939 #else
940 #define MULTI_TEXCOORD2F MULTI_TEXCOORD2
941 #endif
942
943 static void
944 _tnl_MultiTexCoord1fARB(GLenum target, GLfloat s)
945 {
946 MULTI_TEXCOORD1( target, s );
947 }
948
949 static void
950 _tnl_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
951 {
952 MULTI_TEXCOORD1( target, v[0] );
953 }
954
955 static void
956 _tnl_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
957 {
958 MULTI_TEXCOORD2F( target, s, t );
959 }
960
961 static void
962 _tnl_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
963 {
964 MULTI_TEXCOORD2F( target, v[0], v[1] );
965 }
966
967 static void
968 _tnl_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
969 {
970 MULTI_TEXCOORD3( target, s, t, r );
971 }
972
973 static void
974 _tnl_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
975 {
976 MULTI_TEXCOORD3( target, v[0], v[1], v[2] );
977 }
978
979 static void
980 _tnl_MultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
981 {
982 MULTI_TEXCOORD4( target, s, t, r, q );
983 }
984
985 static void
986 _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v)
987 {
988 MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] );
989 }
990
991
992
993 /* KW: Because the eval values don't become 'current', fixup will flow
994 * through these vertices, and then evaluation will write on top
995 * of the fixup results.
996 *
997 * Note: using Obj to hold eval coord data.
998 */
999 #define EVALCOORD1(IM, x) \
1000 { \
1001 GLuint count = IM->Count++; \
1002 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1003 IM->Flag[count] |= VERT_BIT_EVAL_C1; \
1004 ASSIGN_4V(dest, x, 0, 0, 1); \
1005 if (count == IMM_MAXDATA-1) \
1006 _tnl_flush_immediate( NULL, IM ); \
1007 }
1008
1009 #define EVALCOORD2(IM, x, y) \
1010 { \
1011 GLuint count = IM->Count++; \
1012 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1013 IM->Flag[count] |= VERT_BIT_EVAL_C2; \
1014 ASSIGN_4V(dest, x, y, 0, 1); \
1015 if (count == IMM_MAXDATA-1) \
1016 _tnl_flush_immediate( NULL, IM ); \
1017 }
1018
1019 #define EVALPOINT1(IM, x) \
1020 { \
1021 GLuint count = IM->Count++; \
1022 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1023 IM->Flag[count] |= VERT_BIT_EVAL_P1; \
1024 ASSIGN_4V(dest, x, 0, 0, 1); \
1025 if (count == IMM_MAXDATA-1) \
1026 _tnl_flush_immediate( NULL, IM ); \
1027 }
1028
1029 #define EVALPOINT2(IM, x, y) \
1030 { \
1031 GLuint count = IM->Count++; \
1032 GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count]; \
1033 IM->Flag[count] |= VERT_BIT_EVAL_P2; \
1034 ASSIGN_4V(dest, x, y, 0, 1); \
1035 if (count == IMM_MAXDATA-1) \
1036 _tnl_flush_immediate( NULL, IM ); \
1037 }
1038
1039 static void
1040 _tnl_EvalCoord1f( GLfloat u )
1041 {
1042 GET_IMMEDIATE;
1043 EVALCOORD1( IM, u );
1044 }
1045
1046 static void
1047 _tnl_EvalCoord1fv( const GLfloat *u )
1048 {
1049 GET_IMMEDIATE;
1050 EVALCOORD1( IM, (GLfloat) *u );
1051 }
1052
1053 static void
1054 _tnl_EvalCoord2f( GLfloat u, GLfloat v )
1055 {
1056 GET_IMMEDIATE;
1057 EVALCOORD2( IM, u, v );
1058 }
1059
1060 static void
1061 _tnl_EvalCoord2fv( const GLfloat *u )
1062 {
1063 GET_IMMEDIATE;
1064 EVALCOORD2( IM, u[0], u[1] );
1065 }
1066
1067
1068 static void
1069 _tnl_EvalPoint1( GLint i )
1070 {
1071 GET_IMMEDIATE;
1072 EVALPOINT1( IM, (GLfloat) i );
1073 }
1074
1075
1076 static void
1077 _tnl_EvalPoint2( GLint i, GLint j )
1078 {
1079 GET_IMMEDIATE;
1080 EVALPOINT2( IM, (GLfloat) i, (GLfloat) j );
1081 }
1082
1083
1084 /* Need to use the default array-elt outside begin/end for strict
1085 * conformance.
1086 */
1087 #define ARRAY_ELT( IM, i ) \
1088 { \
1089 GLuint count = IM->Count; \
1090 IM->Elt[count] = i; \
1091 IM->Flag[count] &= IM->ArrayEltFlags; \
1092 IM->Flag[count] |= VERT_BIT_ELT; \
1093 IM->FlushElt = IM->ArrayEltFlush; \
1094 IM->Count += IM->ArrayEltIncr; \
1095 if (IM->Count == IMM_MAXDATA) \
1096 _tnl_flush_immediate( NULL, IM ); \
1097 }
1098
1099
1100 static void
1101 _tnl_ArrayElement( GLint i )
1102 {
1103 GET_IMMEDIATE;
1104 ARRAY_ELT( IM, i );
1105 }
1106
1107
1108 /* Internal functions. These are safe to use providing either:
1109 *
1110 * - It is determined that a display list is not being compiled, or
1111 * if so that these commands won't be compiled into the list (see
1112 * t_eval.c for an example).
1113 *
1114 * - _tnl_hard_begin() is used instead of _tnl_[bB]egin, and tested
1115 * for a GL_TRUE return value. See _tnl_Rectf, below.
1116 */
1117 void
1118 _tnl_eval_coord1f( GLcontext *CC, GLfloat u )
1119 {
1120 struct immediate *i = TNL_CURRENT_IM(CC);
1121 EVALCOORD1( i, u );
1122 }
1123
1124 void
1125 _tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
1126 {
1127 struct immediate *i = TNL_CURRENT_IM(CC);
1128 EVALCOORD2( i, u, v );
1129 }
1130
1131
1132
1133
1134 /*
1135 * NV_vertex_program
1136 */
1137
1138 static void
1139 _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
1140 {
1141 if (index < 16) {
1142 GET_IMMEDIATE;
1143 const GLuint count = IM->Count;
1144 GLfloat *attrib = IM->Attrib[index][count];
1145 ASSIGN_4V(attrib, x, y, z, w);
1146 IM->Flag[count] |= (1 << index);
1147 if (index == 0) {
1148 IM->Count++;
1149 if (count == IMM_MAXDATA - 1)
1150 _tnl_flush_immediate( NULL, IM );
1151 }
1152 }
1153 }
1154
1155 static void
1156 _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
1157 {
1158 if (index < 16) {
1159 GET_IMMEDIATE;
1160 const GLuint count = IM->Count;
1161 GLfloat *attrib = IM->Attrib[index][count];
1162 COPY_4V(attrib, v);
1163 IM->Flag[count] |= (1 << index);
1164 if (index == 0) {
1165 IM->Count++;
1166 if (count == IMM_MAXDATA - 1)
1167 _tnl_flush_immediate( NULL, IM );
1168 }
1169 }
1170 }
1171
1172
1173 /* Execute a glRectf() function. _tnl_hard_begin() ensures the check
1174 * on outside_begin_end is executed even in compiled lists. These
1175 * vertices can now participate in the same immediate as regular ones,
1176 * even in most display lists.
1177 */
1178 static void
1179 _tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
1180 {
1181 GET_CURRENT_CONTEXT(ctx);
1182
1183 if (_tnl_hard_begin( ctx, GL_QUADS )) {
1184 glVertex2f( x1, y1 );
1185 glVertex2f( x2, y1 );
1186 glVertex2f( x2, y2 );
1187 glVertex2f( x1, y2 );
1188 glEnd();
1189 }
1190 }
1191
1192 static void
1193 _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
1194 {
1195 GET_CURRENT_CONTEXT(ctx);
1196 TNLcontext *tnl = TNL_CONTEXT(ctx);
1197 struct immediate *IM = TNL_CURRENT_IM(ctx);
1198 GLuint count = IM->Count;
1199 struct gl_material *mat;
1200 GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv");
1201
1202 if (bitmask == 0)
1203 return;
1204
1205 if (MESA_VERBOSE & VERBOSE_API)
1206 _mesa_debug(ctx, "_tnl_Materialfv\n");
1207
1208 if (tnl->IsolateMaterials &&
1209 !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
1210 {
1211 _tnl_flush_immediate( ctx, IM );
1212 IM = TNL_CURRENT_IM(ctx);
1213 count = IM->Count;
1214 }
1215
1216 if (!(IM->Flag[count] & VERT_BIT_MATERIAL)) {
1217 if (!IM->Material) {
1218 IM->Material = (struct gl_material (*)[2])
1219 MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
1220 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
1221 IM->MaterialMask[IM->LastMaterial] = 0;
1222 }
1223 else if (IM->MaterialOrMask & ~bitmask) {
1224 _mesa_copy_material_pairs( IM->Material[count],
1225 IM->Material[IM->LastMaterial],
1226 IM->MaterialOrMask & ~bitmask );
1227 }
1228
1229 IM->Flag[count] |= VERT_BIT_MATERIAL;
1230 IM->MaterialMask[count] = 0;
1231 IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
1232 IM->LastMaterial = count;
1233 }
1234
1235 IM->MaterialOrMask |= bitmask;
1236 IM->MaterialMask[count] |= bitmask;
1237 mat = IM->Material[count];
1238
1239 if (bitmask & FRONT_AMBIENT_BIT) {
1240 COPY_4FV( mat[0].Ambient, params );
1241 }
1242 if (bitmask & BACK_AMBIENT_BIT) {
1243 COPY_4FV( mat[1].Ambient, params );
1244 }
1245 if (bitmask & FRONT_DIFFUSE_BIT) {
1246 COPY_4FV( mat[0].Diffuse, params );
1247 }
1248 if (bitmask & BACK_DIFFUSE_BIT) {
1249 COPY_4FV( mat[1].Diffuse, params );
1250 }
1251 if (bitmask & FRONT_SPECULAR_BIT) {
1252 COPY_4FV( mat[0].Specular, params );
1253 }
1254 if (bitmask & BACK_SPECULAR_BIT) {
1255 COPY_4FV( mat[1].Specular, params );
1256 }
1257 if (bitmask & FRONT_EMISSION_BIT) {
1258 COPY_4FV( mat[0].Emission, params );
1259 }
1260 if (bitmask & BACK_EMISSION_BIT) {
1261 COPY_4FV( mat[1].Emission, params );
1262 }
1263 if (bitmask & FRONT_SHININESS_BIT) {
1264 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
1265 mat[0].Shininess = shininess;
1266 }
1267 if (bitmask & BACK_SHININESS_BIT) {
1268 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
1269 mat[1].Shininess = shininess;
1270 }
1271 if (bitmask & FRONT_INDEXES_BIT) {
1272 mat[0].AmbientIndex = params[0];
1273 mat[0].DiffuseIndex = params[1];
1274 mat[0].SpecularIndex = params[2];
1275 }
1276 if (bitmask & BACK_INDEXES_BIT) {
1277 mat[1].AmbientIndex = params[0];
1278 mat[1].DiffuseIndex = params[1];
1279 mat[1].SpecularIndex = params[2];
1280 }
1281
1282 if (tnl->IsolateMaterials &&
1283 !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
1284 {
1285 _tnl_flush_immediate( ctx, IM );
1286 }
1287 }
1288
1289 void _tnl_imm_vtxfmt_init( GLcontext *ctx )
1290 {
1291 GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
1292
1293 /* All begin/end operations are handled by this vertex format:
1294 */
1295 vfmt->ArrayElement = _tnl_ArrayElement;
1296 vfmt->Begin = _tnl_Begin;
1297 vfmt->Color3f = _tnl_Color3f;
1298 vfmt->Color3fv = _tnl_Color3fv;
1299 vfmt->Color3ub = _tnl_Color3ub;
1300 vfmt->Color3ubv = _tnl_Color3ubv;
1301 vfmt->Color4f = _tnl_Color4f;
1302 vfmt->Color4fv = _tnl_Color4fv;
1303 vfmt->Color4ub = _tnl_Color4ub;
1304 vfmt->Color4ubv = _tnl_Color4ubv;
1305 vfmt->EdgeFlag = _tnl_EdgeFlag;
1306 vfmt->EdgeFlagv = _tnl_EdgeFlagv;
1307 vfmt->End = _tnl_End;
1308 vfmt->EvalCoord1f = _tnl_EvalCoord1f;
1309 vfmt->EvalCoord1fv = _tnl_EvalCoord1fv;
1310 vfmt->EvalCoord2f = _tnl_EvalCoord2f;
1311 vfmt->EvalCoord2fv = _tnl_EvalCoord2fv;
1312 vfmt->EvalPoint1 = _tnl_EvalPoint1;
1313 vfmt->EvalPoint2 = _tnl_EvalPoint2;
1314 vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
1315 vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
1316 vfmt->Indexi = _tnl_Indexi;
1317 vfmt->Indexiv = _tnl_Indexiv;
1318 vfmt->Materialfv = _tnl_Materialfv;
1319 vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1fARB;
1320 vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fvARB;
1321 vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2fARB;
1322 vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fvARB;
1323 vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3fARB;
1324 vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fvARB;
1325 vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4fARB;
1326 vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fvARB;
1327 vfmt->Normal3f = _tnl_Normal3f;
1328 vfmt->Normal3fv = _tnl_Normal3fv;
1329 vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
1330 vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
1331 vfmt->SecondaryColor3ubEXT = _tnl_SecondaryColor3ubEXT;
1332 vfmt->SecondaryColor3ubvEXT = _tnl_SecondaryColor3ubvEXT;
1333 vfmt->TexCoord1f = _tnl_TexCoord1f;
1334 vfmt->TexCoord1fv = _tnl_TexCoord1fv;
1335 vfmt->TexCoord2f = _tnl_TexCoord2f;
1336 vfmt->TexCoord2fv = _tnl_TexCoord2fv;
1337 vfmt->TexCoord3f = _tnl_TexCoord3f;
1338 vfmt->TexCoord3fv = _tnl_TexCoord3fv;
1339 vfmt->TexCoord4f = _tnl_TexCoord4f;
1340 vfmt->TexCoord4fv = _tnl_TexCoord4fv;
1341 vfmt->Vertex2f = _tnl_Vertex2f;
1342 vfmt->Vertex2fv = _tnl_Vertex2fv;
1343 vfmt->Vertex3f = _tnl_Vertex3f;
1344 vfmt->Vertex3fv = _tnl_Vertex3fv;
1345 vfmt->Vertex4f = _tnl_Vertex4f;
1346 vfmt->Vertex4fv = _tnl_Vertex4fv;
1347 vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
1348 vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
1349
1350 /* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
1351 */
1352 vfmt->Rectf = _tnl_Rectf;
1353
1354 /* Just use the core function:
1355 */
1356 vfmt->CallList = _mesa_CallList;
1357
1358 vfmt->prefer_float_colors = GL_FALSE;
1359 }