Subversion Repositories shark

Rev

Rev 56 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
56 pj 1
/* $Id: t_imm_fixup.c,v 1.1 2003-02-28 11:48:07 pj Exp $ */
2
 
3
/*
4
 * Mesa 3-D graphics library
5
 * Version:  4.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
 
27
/*
28
 * Authors:
29
 *    Keith Whitwell <keith@tungstengraphics.com>
30
 */
31
 
32
 
33
#include "glheader.h"
34
#include "context.h"
35
#include "enums.h"
36
#include "dlist.h"
37
#include "colormac.h"
38
#include "light.h"
39
#include "macros.h"
40
#include "imports.h"
41
#include "mmath.h"
42
#include "state.h"
43
#include "mtypes.h"
44
 
45
#include "math/m_matrix.h"
46
#include "math/m_xform.h"
47
 
48
#include "t_context.h"
49
#include "t_imm_alloc.h"
50
#include "t_imm_debug.h"
51
#include "t_imm_elt.h"
52
#include "t_imm_fixup.h"
53
#include "t_imm_exec.h"
54
#include "t_pipeline.h"
55
 
56
 
57
static const GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 };
58
static const GLuint intro[GL_POLYGON+2]     = { 0,0,2,2,0,2,2,0,2,2,0 };
59
 
60
void
61
_tnl_fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match )
62
{
63
   GLuint i = start;
64
 
65
   for (;;) {
66
      if ((flag[++i] & match) == 0) {
67
         COPY_4FV(data[i], data[i-1]);
68
         if (flag[i] & VERT_BIT_END_VB) break;
69
      }
70
   }
71
}
72
 
73
void
74
_tnl_fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match )
75
{
76
   GLuint i = start;
77
 
78
 
79
   for (;;) {
80
      if ((flag[++i] & match) == 0) {
81
/*       _mesa_debug(NULL, "_tnl_fixup_3f copy to %p values %f %f %f\n", */
82
/*               data[i],  */
83
/*               data[i-1][0], */
84
/*               data[i-1][1], */
85
/*               data[i-1][2]); */
86
         COPY_3V(data[i], data[i-1]);
87
         if (flag[i] & VERT_BIT_END_VB) break;
88
      }
89
   }
90
}
91
 
92
 
93
void
94
_tnl_fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match )
95
{
96
   GLuint i = start;
97
 
98
   for (;;) {
99
      if ((flag[++i] & match) == 0) {
100
         data[i] = data[i-1];
101
         if (flag[i] & VERT_BIT_END_VB) break;
102
      }
103
   }
104
   flag[i] |= match;
105
}
106
 
107
 
108
void
109
_tnl_fixup_1f( GLfloat *data, GLuint flag[], GLuint start, GLuint match )
110
{
111
   GLuint i = start;
112
 
113
   for (;;) {
114
      if ((flag[++i] & match) == 0) {
115
         data[i] = data[i-1];
116
         if (flag[i] & VERT_BIT_END_VB) break;
117
      }
118
   }
119
   flag[i] |= match;
120
}
121
 
122
void
123
_tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match )
124
{
125
   GLuint i = start;
126
 
127
   for (;;) {
128
      if ((flag[++i] & match) == 0) {
129
         data[i] = data[i-1];
130
         if (flag[i] & VERT_BIT_END_VB) break;
131
      }
132
   }
133
   flag[i] |= match;
134
}
135
 
136
 
137
static void
138
fixup_first_4f( GLfloat data[][4], GLuint flag[], GLuint match,
139
                GLuint start, GLfloat *dflt )
140
{
141
   GLuint i = start-1;
142
   match |= VERT_BIT_END_VB;
143
 
144
   while ((flag[++i]&match) == 0)
145
      COPY_4FV(data[i], dflt);
146
}
147
 
148
#if 0
149
static void
150
fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match,
151
                GLuint start, GLfloat *dflt )
152
{
153
   GLuint i = start-1;
154
   match |= VERT_BIT_END_VB;
155
 
156
/*     _mesa_debug(NULL, "fixup_first_3f default: %f %f %f start: %d\n", */
157
/*         dflt[0], dflt[1], dflt[2], start);  */
158
 
159
   while ((flag[++i]&match) == 0)
160
      COPY_3FV(data[i], dflt);
161
}
162
#endif
163
 
164
static void
165
fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match,
166
                 GLuint start, GLuint dflt )
167
{
168
   GLuint i = start-1;
169
   match |= VERT_BIT_END_VB;
170
 
171
   while ((flag[++i]&match) == 0)
172
      data[i] = dflt;
173
}
174
 
175
#if 00
176
static void
177
fixup_first_1f( GLfloat data[], GLuint flag[], GLuint match,
178
                GLuint start, GLfloat dflt )
179
{
180
   GLuint i = start-1;
181
   match |= VERT_BIT_END_VB;
182
 
183
   while ((flag[++i]&match) == 0)
184
      data[i] = dflt;
185
}
186
#endif
187
 
188
static void
189
fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match,
190
                 GLuint start, GLubyte dflt )
191
{
192
   GLuint i = start-1;
193
   match |= VERT_BIT_END_VB;
194
 
195
   while ((flag[++i]&match) == 0)
196
      data[i] = dflt;
197
}
198
 
199
/*
200
 * Copy vertex attributes from the ctx->Current group into the immediate
201
 * struct at the given position according to copyMask.
202
 */
203
static void copy_from_current( GLcontext *ctx, struct immediate *IM,
204
                              GLuint pos, GLuint copyMask )
205
{
206
   GLuint attrib, attribBit;
207
 
208
   if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
209
      _tnl_print_vert_flags("copy from current", copyMask);
210
 
211
#if 0
212
   if (copyMask & VERT_BIT_NORMAL) {
213
      COPY_4V(IM->Attrib[VERT_ATTRIB_NORMAL][pos],
214
              ctx->Current.Attrib[VERT_ATTRIB_NORMAL]);
215
   }
216
 
217
   if (copyMask & VERT_BIT_COLOR0) {
218
      COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR0][pos],
219
                ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
220
   }
221
 
222
   if (copyMask & VERT_BIT_COLOR1)
223
      COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR1][pos],
224
                ctx->Current.Attrib[VERT_ATTRIB_COLOR1]);
225
 
226
   if (copyMask & VERT_BIT_FOG)
227
      IM->Attrib[VERT_ATTRIB_FOG][pos][0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
228
 
229
   if (copyMask & VERT_BITS_TEX_ANY) {
230
      GLuint i;
231
      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
232
         if (copyMask & VERT_BIT_TEX(i))
233
            COPY_4FV(IM->Attrib[VERT_ATTRIB_TEX0 + i][pos],
234
                     ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i]);
235
      }
236
   }
237
#else
238
   for (attrib = 0, attribBit = 1; attrib < 16; attrib++, attribBit <<= 1) {
239
      if (copyMask & attribBit) {
240
         COPY_4FV( IM->Attrib[attrib][pos], ctx->Current.Attrib[attrib]);
241
      }
242
   }
243
#endif
244
 
245
   if (copyMask & VERT_BIT_INDEX)
246
      IM->Index[pos] = ctx->Current.Index;
247
 
248
   if (copyMask & VERT_BIT_EDGEFLAG)
249
      IM->EdgeFlag[pos] = ctx->Current.EdgeFlag;
250
}
251
 
252
 
253
void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM )
254
{
255
   TNLcontext *tnl = TNL_CONTEXT(ctx);
256
   GLuint start = IM->CopyStart;
257
   GLuint andflag = IM->CopyAndFlag;
258
   GLuint orflag = IM->CopyOrFlag | IM->Evaluated;
259
   GLuint fixup;
260
 
261
   IM->CopyTexSize = IM->TexSize;
262
 
263
/*     _mesa_debug(ctx, "Fixup input, Start: %u Count: %u LastData: %u\n", */
264
/*         IM->Start, IM->Count, IM->LastData); */
265
/*     _tnl_print_vert_flags("Orflag", orflag); */
266
/*     _tnl_print_vert_flags("Andflag", andflag); */
267
 
268
 
269
   fixup = ~andflag & VERT_BITS_FIXUP;
270
 
271
   if (!ctx->CompileFlag)
272
      fixup &= tnl->pipeline.inputs;
273
 
274
   if (!ctx->ExecuteFlag)
275
      fixup &= orflag;
276
 
277
   if ((orflag & (VERT_BIT_POS|VERT_BITS_EVAL_ANY)) == 0)
278
      fixup = 0;
279
 
280
   if (fixup) {
281
      GLuint copy = fixup & ~IM->Flag[start];
282
 
283
 
284
      /* Equivalent to a lazy copy-from-current when setting up the
285
       * immediate.
286
       */
287
      if (ctx->ExecuteFlag && copy)
288
         copy_from_current( ctx, IM, start, copy );
289
 
290
      if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
291
         _tnl_print_vert_flags("fixup", fixup);
292
 
293
      /* XXX replace these conditionals with a loop over the 16
294
       * vertex attributes.
295
       */
296
 
297
      if (fixup & VERT_BITS_TEX_ANY) {
298
         GLuint i;
299
         for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
300
            if (fixup & VERT_BIT_TEX(i)) {
301
               if (orflag & VERT_BIT_TEX(i))
302
                  _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag,
303
                                 start, VERT_BIT_TEX(i) );
304
               else
305
                  fixup_first_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag,
306
                                  VERT_BIT_END_VB, start,
307
                                  IM->Attrib[VERT_ATTRIB_TEX0 + i][start]);
308
            }
309
         }
310
      }
311
 
312
 
313
      if (fixup & VERT_BIT_EDGEFLAG) {
314
         if (orflag & VERT_BIT_EDGEFLAG)
315
            _tnl_fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_BIT_EDGEFLAG );
316
         else
317
            fixup_first_1ub( IM->EdgeFlag, IM->Flag, VERT_BIT_END_VB, start,
318
                             IM->EdgeFlag[start] );
319
      }
320
 
321
      if (fixup & VERT_BIT_INDEX) {
322
         if (orflag & VERT_BIT_INDEX)
323
            _tnl_fixup_1ui( IM->Index, IM->Flag, start, VERT_BIT_INDEX );
324
         else
325
            fixup_first_1ui( IM->Index, IM->Flag, VERT_BIT_END_VB, start,
326
                             IM->Index[start] );
327
      }
328
 
329
      if (fixup & VERT_BIT_COLOR0) {
330
         if (orflag & VERT_BIT_COLOR0)
331
            _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag, start,
332
                           VERT_BIT_COLOR0 );
333
         /* No need for else case as the drivers understand stride
334
          * zero here.  (TODO - propogate this)
335
          */
336
      }
337
 
338
      if (fixup & VERT_BIT_COLOR1) {
339
         if (orflag & VERT_BIT_COLOR1)
340
            _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, start,
341
                           VERT_BIT_COLOR1 );
342
         else
343
            fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, VERT_BIT_END_VB, start,
344
                            IM->Attrib[VERT_ATTRIB_COLOR1][start] );
345
      }
346
 
347
      if (fixup & VERT_BIT_FOG) {
348
         if (orflag & VERT_BIT_FOG)
349
            _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag,
350
                           start, VERT_BIT_FOG );
351
         else
352
            fixup_first_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag, VERT_BIT_END_VB,
353
                            start, IM->Attrib[VERT_ATTRIB_FOG][start] );
354
      }
355
 
356
      if (fixup & VERT_BIT_NORMAL) {
357
         if (orflag & VERT_BIT_NORMAL)
358
            _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag, start,
359
                           VERT_BIT_NORMAL );
360
         else
361
            fixup_first_4f( IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag,
362
                            VERT_BIT_END_VB, start,
363
                            IM->Attrib[VERT_ATTRIB_NORMAL][start] );
364
      }
365
   }
366
 
367
   /* Prune possible half-filled slot.
368
    */
369
   IM->Flag[IM->LastData+1] &= ~VERT_BIT_END_VB;
370
   IM->Flag[IM->Count] |= VERT_BIT_END_VB;
371
 
372
 
373
   /* Materials:
374
    */
375
   if (IM->MaterialOrMask & ~IM->MaterialAndMask) {
376
      GLuint vulnerable = IM->MaterialOrMask;
377
      GLuint i = IM->Start;
378
 
379
      do {
380
         while (!(IM->Flag[i] & VERT_BIT_MATERIAL))
381
            i++;
382
 
383
         vulnerable &= ~IM->MaterialMask[i];
384
         _mesa_copy_material_pairs( IM->Material[i],
385
                                    ctx->Light.Material,
386
                                    vulnerable );
387
 
388
 
389
        ++i;
390
      } while (vulnerable);
391
   }
392
}
393
 
394
 
395
static void
396
copy_material( struct immediate *next,
397
               struct immediate *prev,
398
               GLuint dst, GLuint src )
399
{
400
/*     _mesa_debug(NULL, "%s\n", __FUNCTION__); */
401
 
402
   if (next->Material == 0) {
403
      next->Material = (struct gl_material (*)[2])
404
         MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
405
      next->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
406
   }
407
 
408
   next->MaterialMask[dst] = prev->MaterialOrMask;
409
   MEMCPY(next->Material[dst], prev->Material[src],
410
          2 * sizeof(struct gl_material));
411
}
412
 
413
 
414
 
415
static GLboolean is_fan_like[GL_POLYGON+1] = {
416
   GL_FALSE,
417
   GL_FALSE,
418
   GL_TRUE,                     /* line loop */
419
   GL_FALSE,
420
   GL_FALSE,
421
   GL_FALSE,
422
   GL_TRUE,                     /* tri fan */
423
   GL_FALSE,
424
   GL_FALSE,
425
   GL_TRUE                      /* polygon */
426
};
427
 
428
 
429
/* Copy the untransformed data from the shared vertices of a primitive
430
 * that wraps over two immediate structs.  This is done prior to
431
 * set_immediate so that prev and next may point to the same
432
 * structure.  In general it's difficult to avoid this copy on long
433
 * primitives.
434
 *
435
 * Have to be careful with the transitions between display list
436
 * replay, compile and normal execute modes.
437
 */
438
void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next )
439
{
440
   TNLcontext *tnl = TNL_CONTEXT(ctx);
441
   struct immediate *prev = tnl->ExecCopySource;
442
   struct vertex_arrays *inputs = &tnl->imm_inputs;
443
   GLuint count = tnl->ExecCopyCount;
444
   GLuint *elts = tnl->ExecCopyElts;
445
   GLuint offset = IMM_MAX_COPIED_VERTS - count;
446
   GLuint i;
447
 
448
   if (!prev) {
449
      ASSERT(tnl->ExecCopyCount == 0);
450
      return;
451
   }
452
 
453
   next->CopyStart = next->Start - count;
454
 
455
   if ((prev->CopyOrFlag & VERT_BITS_DATA) == VERT_BIT_ELT &&
456
       ctx->Array.LockCount &&
457
       ctx->Array.Vertex.Enabled)
458
   {
459
      /* Copy Elt values only
460
       */
461
      for (i = 0 ; i < count ; i++)
462
      {
463
         GLuint src = elts[i+offset];
464
         GLuint dst = next->CopyStart+i;
465
         next->Elt[dst] = prev->Elt[src];
466
         next->Flag[dst] = VERT_BIT_ELT;
467
         elts[i+offset] = dst;
468
      }
469
/*        _mesa_debug(ctx, "ADDING VERT_BIT_ELT!\n"); */
470
      next->CopyOrFlag |= VERT_BIT_ELT;
471
      next->CopyAndFlag &= VERT_BIT_ELT;
472
   }
473
   else {
474
      GLuint copy = tnl->pipeline.inputs & (prev->CopyOrFlag|prev->Evaluated);
475
      GLuint flag;
476
 
477
      if (is_fan_like[ctx->Driver.CurrentExecPrimitive]) {
478
         flag = ((prev->CopyOrFlag|prev->Evaluated) & VERT_BITS_FIXUP);
479
         next->CopyOrFlag |= flag;
480
      }
481
      else {
482
         /* Don't let an early 'glColor', etc. poison the elt path.
483
          */
484
         flag = ((prev->OrFlag|prev->Evaluated) & VERT_BITS_FIXUP);
485
      }
486
 
487
      next->TexSize |= tnl->ExecCopyTexSize;
488
      next->CopyAndFlag &= flag;
489
 
490
 
491
/*        _tnl_print_vert_flags("copy vertex components", copy); */
492
/*        _tnl_print_vert_flags("prev copyorflag", prev->CopyOrFlag); */
493
/*        _tnl_print_vert_flags("flag", flag); */
494
 
495
      /* Copy whole vertices
496
       */
497
      for (i = 0 ; i < count ; i++)
498
      {
499
         GLuint src = elts[i+offset];
500
         GLuint isrc = src - prev->CopyStart;
501
         GLuint dst = next->CopyStart+i;
502
 
503
         /* Values subject to eval must be copied out of the 'inputs'
504
          * struct.  (Copied rows should not be evaluated twice).
505
          *
506
          * Note these pointers are null when inactive.
507
          */
508
         COPY_4FV( next->Attrib[VERT_ATTRIB_POS][dst],
509
                   inputs->Obj.data[isrc] );
510
 
511
         if (copy & VERT_BIT_NORMAL) {
512
/*          _mesa_debug(ctx, "copy vert norm %d to %d (%p): %f %f %f\n", */
513
/*                  isrc, dst,  */
514
/*                  next->Normal[dst], */
515
/*                  inputs->Normal.data[isrc][0], */
516
/*                  inputs->Normal.data[isrc][1], */
517
/*                  inputs->Normal.data[isrc][2]); */
518
            COPY_3FV( next->Attrib[VERT_ATTRIB_NORMAL][dst], inputs->Normal.data[isrc] );
519
         }
520
 
521
         if (copy & VERT_BIT_COLOR0)
522
            COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR0][dst],
523
                      ((GLfloat (*)[4])inputs->Color.Ptr)[isrc] );
524
 
525
         if (copy & VERT_BIT_INDEX)
526
            next->Index[dst] = inputs->Index.data[isrc];
527
 
528
         if (copy & VERT_BITS_TEX_ANY) {
529
            GLuint i;
530
            for (i = 0 ; i < prev->MaxTextureUnits ; i++) {
531
               if (copy & VERT_BIT_TEX(i))
532
                  COPY_4FV( next->Attrib[VERT_ATTRIB_TEX0 + i][dst],
533
                            inputs->TexCoord[i].data[isrc] );
534
            }
535
         }
536
 
537
         /* Remaining values should be the same in the 'input' struct and the
538
          * original immediate.
539
          */
540
         if (copy & (VERT_BIT_ELT|VERT_BIT_EDGEFLAG|VERT_BIT_COLOR1|VERT_BIT_FOG|
541
                     VERT_BIT_MATERIAL)) {
542
 
543
            if (prev->Flag[src] & VERT_BIT_MATERIAL)
544
               copy_material(next, prev, dst, src);
545
 
546
            next->Elt[dst] = prev->Elt[src];
547
            next->EdgeFlag[dst] = prev->EdgeFlag[src];
548
            COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR1][dst],
549
                      prev->Attrib[VERT_ATTRIB_COLOR1][src] );
550
            COPY_4FV( next->Attrib[VERT_ATTRIB_FOG][dst],
551
                      prev->Attrib[VERT_ATTRIB_FOG][src] );
552
         }
553
 
554
         next->Flag[dst] = flag;
555
         next->CopyOrFlag |= prev->Flag[src] & (VERT_BITS_FIXUP|
556
                                                VERT_BIT_MATERIAL|
557
                                                VERT_BIT_POS);
558
         elts[i+offset] = dst;
559
      }
560
   }
561
 
562
   if (--tnl->ExecCopySource->ref_count == 0)
563
      _tnl_free_immediate( ctx, tnl->ExecCopySource );
564
 
565
   tnl->ExecCopySource = next; next->ref_count++;
566
}
567
 
568
 
569
 
570
/* Revive a compiled immediate struct - propogate new 'Current'
571
 * values.  Often this is redundant because the current values were
572
 * known and fixed up at compile time (or in the first execution of
573
 * the cassette).
574
 */
575
void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM )
576
{
577
   TNLcontext *tnl = TNL_CONTEXT(ctx);
578
   GLuint fixup;
579
   GLuint start = IM->Start;
580
 
581
/*     _mesa_debug(ctx, "%s\n", __FUNCTION__); */
582
 
583
   IM->Evaluated = 0;
584
   IM->CopyOrFlag = IM->OrFlag;  
585
   IM->CopyAndFlag = IM->AndFlag;
586
   IM->CopyTexSize = IM->TexSize | tnl->ExecCopyTexSize;
587
 
588
   _tnl_copy_immediate_vertices( ctx, IM );
589
 
590
   if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
591
      ASSERT(IM->CopyStart == IM->Start);
592
   }
593
 
594
   /* Naked array elements can be copied into the first cassette in a
595
    * display list.  Need to translate them away:
596
    */
597
   if (IM->CopyOrFlag & VERT_BIT_ELT) {
598
      GLuint copy = tnl->pipeline.inputs & ~ctx->Array._Enabled;
599
      GLuint i;
600
 
601
      ASSERT(IM->CopyStart < IM->Start);
602
 
603
      _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Start );
604
 
605
      for (i = IM->CopyStart ; i < IM->Start ; i++)
606
         copy_from_current( ctx, IM, i, copy );
607
 
608
      _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->Start );
609
   }
610
 
611
   fixup = tnl->pipeline.inputs & ~IM->Flag[start] & VERT_BITS_FIXUP;
612
 
613
/*     _tnl_print_vert_flags("fixup compiled", fixup); */
614
 
615
   if (fixup) {
616
 
617
      /* XXX try to replace this code with a loop over the 16 vertex
618
       * attributes.
619
       */
620
 
621
      if (fixup & VERT_BIT_NORMAL) {
622
         fixup_first_4f(IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag,
623
                        VERT_BIT_NORMAL, start,
624
                        ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
625
      }
626
 
627
      if (fixup & VERT_BIT_COLOR0) {
628
         if (IM->CopyOrFlag & VERT_BIT_COLOR0)
629
            fixup_first_4f(IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
630
                           VERT_BIT_COLOR0, start,
631
                           ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
632
         else
633
            fixup &= ~VERT_BIT_COLOR0;
634
      }
635
 
636
      if (fixup & VERT_BIT_COLOR1)
637
         fixup_first_4f(IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag,
638
                        VERT_BIT_COLOR1, start,
639
                        ctx->Current.Attrib[VERT_ATTRIB_COLOR1] );
640
 
641
      if (fixup & VERT_BIT_FOG)
642
         fixup_first_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag,
643
                         VERT_BIT_FOG, start,
644
                         ctx->Current.Attrib[VERT_ATTRIB_FOG] );
645
 
646
      if (fixup & VERT_BITS_TEX_ANY) {
647
         GLuint i;
648
         for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
649
            if (fixup & VERT_BIT_TEX(i))
650
               fixup_first_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag,
651
                               VERT_BIT_TEX(i), start,
652
                               ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i] );
653
         }
654
      }
655
 
656
      if (fixup & VERT_BIT_EDGEFLAG)
657
         fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_BIT_EDGEFLAG, start,
658
                         ctx->Current.EdgeFlag );
659
 
660
      if (fixup & VERT_BIT_INDEX)
661
         fixup_first_1ui(IM->Index, IM->Flag, VERT_BIT_INDEX, start,
662
                         ctx->Current.Index );
663
 
664
      IM->CopyOrFlag |= fixup;
665
   }
666
 
667
 
668
   /* Materials:
669
    */
670
   if (IM->MaterialOrMask & ~IM->MaterialAndMask) {
671
      GLuint vulnerable = IM->MaterialOrMask;
672
      GLuint i = IM->Start;
673
 
674
      do {
675
         while (!(IM->Flag[i] & VERT_BIT_MATERIAL))
676
            i++;
677
 
678
         vulnerable &= ~IM->MaterialMask[i];
679
         _mesa_copy_material_pairs( IM->Material[i],
680
                                    ctx->Light.Material,
681
                                    vulnerable );
682
 
683
 
684
         ++i;
685
      } while (vulnerable);
686
   }
687
}
688
 
689
 
690
 
691
 
692
 
693
 
694
static void copy_none( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
695
{
696
   (void) (start && ovf && tnl && count);
697
}
698
 
699
static void copy_last( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
700
{
701
   (void) start; (void) ovf;
702
   tnl->ExecCopyCount = 1;
703
   tnl->ExecCopyElts[2] = count-1;
704
}
705
 
706
static void copy_first_and_last( TNLcontext *tnl, GLuint start, GLuint count,
707
                                 GLuint ovf)
708
{
709
   (void) ovf;
710
   tnl->ExecCopyCount = 2;
711
   tnl->ExecCopyElts[1] = start;
712
   tnl->ExecCopyElts[2] = count-1;
713
}
714
 
715
static void copy_last_two( TNLcontext *tnl, GLuint start, GLuint count,
716
                           GLuint ovf )
717
{
718
   (void) start;
719
   tnl->ExecCopyCount = 2+ovf;
720
   tnl->ExecCopyElts[0] = count-3;
721
   tnl->ExecCopyElts[1] = count-2;
722
   tnl->ExecCopyElts[2] = count-1;
723
}
724
 
725
static void copy_overflow( TNLcontext *tnl, GLuint start, GLuint count,
726
                           GLuint ovf )
727
{
728
   (void) start;
729
   tnl->ExecCopyCount = ovf;
730
   tnl->ExecCopyElts[0] = count-3;
731
   tnl->ExecCopyElts[1] = count-2;
732
   tnl->ExecCopyElts[2] = count-1;
733
}
734
 
735
 
736
typedef void (*copy_func)( TNLcontext *tnl, GLuint start, GLuint count,
737
                           GLuint ovf );
738
 
739
static copy_func copy_tab[GL_POLYGON+2] =
740
{
741
   copy_none,
742
   copy_overflow,
743
   copy_first_and_last,
744
   copy_last,
745
   copy_overflow,
746
   copy_last_two,
747
   copy_first_and_last,
748
   copy_overflow,
749
   copy_last_two,
750
   copy_first_and_last,
751
   copy_none
752
};
753
 
754
 
755
 
756
 
757
 
758
/* Figure out what vertices need to be copied next time.
759
 */
760
void
761
_tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM )
762
{
763
 
764
   TNLcontext *tnl = TNL_CONTEXT(ctx);
765
   GLuint last = IM->LastPrimitive;
766
   GLuint prim = ctx->Driver.CurrentExecPrimitive;
767
   GLuint pincr = increment[prim];
768
   GLuint pintro = intro[prim];
769
   GLuint ovf = 0;
770
 
771
/*     _mesa_debug(ctx, "_tnl_get_exec_copy_verts %s\n",  */
772
/*         _mesa_lookup_enum_by_nr(prim)); */
773
 
774
   if (tnl->ExecCopySource)
775
      if (--tnl->ExecCopySource->ref_count == 0)
776
         _tnl_free_immediate( ctx, tnl->ExecCopySource );
777
 
778
   if (prim == GL_POLYGON+1) {
779
      tnl->ExecCopySource = 0;
780
      tnl->ExecCopyCount = 0;
781
      tnl->ExecCopyTexSize = 0;
782
      tnl->ExecParity = 0;
783
   } else {
784
      /* Remember this immediate as the one to copy from.
785
       */
786
      tnl->ExecCopySource = IM; IM->ref_count++;
787
      tnl->ExecCopyCount = 0;
788
      tnl->ExecCopyTexSize = IM->CopyTexSize;
789
 
790
      if (IM->LastPrimitive != IM->CopyStart)
791
         tnl->ExecParity = 0;
792
 
793
      tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1;
794
 
795
 
796
      if (pincr != 1 && (IM->Count - last - pintro))
797
         ovf = (IM->Count - last - pintro) % pincr;
798
 
799
      if (last < IM->Count)
800
         copy_tab[prim]( tnl, last, IM->Count, ovf );
801
   }
802
}
803
 
804
 
805
/* Recalculate ExecCopyElts, ExecParity, etc.  
806
 */
807
void
808
_tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM )
809
{
810
   TNLcontext *tnl = TNL_CONTEXT(ctx);
811
 
812
   if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
813
      GLuint last = IM->LastPrimitive;
814
      GLenum prim = IM->Primitive[last];
815
      GLuint pincr = increment[prim];
816
      GLuint pintro = intro[prim];
817
      GLuint ovf = 0, i;
818
 
819
      tnl->ExecCopyCount = 0;
820
      if (IM->LastPrimitive != IM->CopyStart)
821
         tnl->ExecParity = 0;
822
 
823
      tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1;
824
 
825
      if (pincr != 1 && (IM->Count - last - pintro))
826
         ovf = (IM->Count - last - pintro) % pincr;
827
 
828
      if (last < IM->Count)
829
         copy_tab[prim]( tnl, last, IM->Count, ovf );
830
 
831
      for (i = 0 ; i < tnl->ExecCopyCount ; i++)
832
         tnl->ExecCopyElts[i] = IM->Elt[tnl->ExecCopyElts[i]];
833
   }
834
}
835
 
836
 
837
void _tnl_upgrade_current_data( GLcontext *ctx,
838
                                GLuint required,
839
                                GLuint flags )
840
{
841
   TNLcontext *tnl = TNL_CONTEXT(ctx);
842
   struct vertex_buffer *VB = &tnl->vb;
843
   struct immediate *IM = (struct immediate *)VB->import_source;
844
 
845
   ASSERT(IM);
846
 
847
/*     _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
848
 
849
   if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & CA_CLIENT_DATA)) {
850
      struct gl_client_array *tmp = &tnl->imm_inputs.Color;
851
      GLuint start = IM->CopyStart;
852
 
853
      tmp->Ptr = IM->Attrib[VERT_ATTRIB_COLOR0] + start;
854
      tmp->StrideB = 4 * sizeof(GLfloat);
855
      tmp->Flags = 0;
856
 
857
      COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR0][start],
858
                ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);  
859
 
860
      /*
861
      ASSERT(IM->Flag[IM->LastData+1] & VERT_BIT_END_VB);
862
      */
863
 
864
      fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
865
                      VERT_BIT_END_VB,
866
                      start, IM->Attrib[VERT_ATTRIB_COLOR0][start] );
867
 
868
      VB->importable_data &= ~VERT_BIT_COLOR0;
869
   }
870
}
871