Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

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