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