1 /* $Id: t_imm_fixup.c,v 1.28 2001/12/03 17:47:04 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
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:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
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.
29 * Keith Whitwell <keithw@valinux.com>
45 #include "math/m_matrix.h"
46 #include "math/m_xform.h"
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"
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 };
61 _tnl_fixup_4f( GLfloat data
[][4], GLuint flag
[], GLuint start
, GLuint match
)
66 if ((flag
[++i
] & match
) == 0) {
67 COPY_4FV(data
[i
], data
[i
-1]);
68 if (flag
[i
] & VERT_END_VB
) break;
74 _tnl_fixup_3f( float data
[][3], GLuint flag
[], GLuint start
, GLuint match
)
80 if ((flag
[++i
] & match
) == 0) {
81 /* fprintf(stderr, "_tnl_fixup_3f copy to %p values %f %f %f\n", */
86 COPY_3V(data
[i
], data
[i
-1]);
87 if (flag
[i
] & VERT_END_VB
) break;
94 _tnl_fixup_1ui( GLuint
*data
, GLuint flag
[], GLuint start
, GLuint match
)
99 if ((flag
[++i
] & match
) == 0) {
101 if (flag
[i
] & VERT_END_VB
) break;
109 _tnl_fixup_1f( GLfloat
*data
, GLuint flag
[], GLuint start
, GLuint match
)
114 if ((flag
[++i
] & match
) == 0) {
116 if (flag
[i
] & VERT_END_VB
) break;
123 _tnl_fixup_1ub( GLubyte
*data
, GLuint flag
[], GLuint start
, GLuint match
)
128 if ((flag
[++i
] & match
) == 0) {
130 if (flag
[i
] & VERT_END_VB
) break;
138 fixup_first_4f( GLfloat data
[][4], GLuint flag
[], GLuint match
,
139 GLuint start
, GLfloat
*dflt
)
142 match
|= VERT_END_VB
;
144 while ((flag
[++i
]&match
) == 0)
145 COPY_4FV(data
[i
], dflt
);
149 fixup_first_3f( GLfloat data
[][3], GLuint flag
[], GLuint match
,
150 GLuint start
, GLfloat
*dflt
)
153 match
|= VERT_END_VB
;
155 /* fprintf(stderr, "fixup_first_3f default: %f %f %f start: %d\n", */
156 /* dflt[0], dflt[1], dflt[2], start); */
158 while ((flag
[++i
]&match
) == 0)
159 COPY_3FV(data
[i
], dflt
);
164 fixup_first_1ui( GLuint data
[], GLuint flag
[], GLuint match
,
165 GLuint start
, GLuint dflt
)
168 match
|= VERT_END_VB
;
170 while ((flag
[++i
]&match
) == 0)
175 fixup_first_1f( GLfloat data
[], GLuint flag
[], GLuint match
,
176 GLuint start
, GLfloat dflt
)
179 match
|= VERT_END_VB
;
181 while ((flag
[++i
]&match
) == 0)
187 fixup_first_1ub( GLubyte data
[], GLuint flag
[], GLuint match
,
188 GLuint start
, GLubyte dflt
)
191 match
|= VERT_END_VB
;
193 while ((flag
[++i
]&match
) == 0)
197 static void copy_from_current( GLcontext
*ctx
, struct immediate
*IM
,
198 GLuint start
, GLuint copy
)
200 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
201 _tnl_print_vert_flags("copy from current", copy
);
203 if (copy
& VERT_NORM
) {
204 COPY_3V( IM
->Normal
[start
], ctx
->Current
.Normal
);
207 if (copy
& VERT_RGBA
) {
208 COPY_4FV( IM
->Color
[start
], ctx
->Current
.Color
);
211 if (copy
& VERT_SPEC_RGB
)
212 COPY_4FV( IM
->SecondaryColor
[start
], ctx
->Current
.SecondaryColor
);
214 if (copy
& VERT_FOG_COORD
)
215 IM
->FogCoord
[start
] = ctx
->Current
.FogCoord
;
217 if (copy
& VERT_INDEX
)
218 IM
->Index
[start
] = ctx
->Current
.Index
;
220 if (copy
& VERT_EDGE
)
221 IM
->EdgeFlag
[start
] = ctx
->Current
.EdgeFlag
;
223 if (copy
& VERT_TEX_ANY
) {
225 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
226 if (copy
& VERT_TEX(i
))
227 COPY_4FV( IM
->TexCoord
[i
][start
], ctx
->Current
.Texcoord
[i
] );
233 void _tnl_fixup_input( GLcontext
*ctx
, struct immediate
*IM
)
235 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
236 GLuint start
= IM
->CopyStart
;
237 GLuint andflag
= IM
->CopyAndFlag
;
238 GLuint orflag
= IM
->CopyOrFlag
| IM
->Evaluated
;
241 IM
->CopyTexSize
= IM
->TexSize
;
243 /* fprintf(stderr, "Fixup input, Start: %u Count: %u LastData: %u\n", */
244 /* IM->Start, IM->Count, IM->LastData); */
245 /* _tnl_print_vert_flags("Orflag", orflag); */
246 /* _tnl_print_vert_flags("Andflag", andflag); */
249 fixup
= ~andflag
& VERT_FIXUP
;
251 if (!ctx
->CompileFlag
)
252 fixup
&= tnl
->pipeline
.inputs
;
254 if (!ctx
->ExecuteFlag
)
257 if ((orflag
& (VERT_OBJ
|VERT_EVAL_ANY
)) == 0)
261 GLuint copy
= fixup
& ~IM
->Flag
[start
];
264 /* Equivalent to a lazy copy-from-current when setting up the
267 if (ctx
->ExecuteFlag
&& copy
)
268 copy_from_current( ctx
, IM
, start
, copy
);
270 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
271 _tnl_print_vert_flags("fixup", fixup
);
273 if (fixup
& VERT_TEX_ANY
) {
275 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
276 if (fixup
& VERT_TEX(i
)) {
277 if (orflag
& VERT_TEX(i
))
278 _tnl_fixup_4f( IM
->TexCoord
[i
], IM
->Flag
, start
,
281 fixup_first_4f( IM
->TexCoord
[i
], IM
->Flag
, VERT_END_VB
, start
,
282 IM
->TexCoord
[i
][start
]);
288 if (fixup
& VERT_EDGE
) {
289 if (orflag
& VERT_EDGE
)
290 _tnl_fixup_1ub( IM
->EdgeFlag
, IM
->Flag
, start
, VERT_EDGE
);
292 fixup_first_1ub( IM
->EdgeFlag
, IM
->Flag
, VERT_END_VB
, start
,
293 IM
->EdgeFlag
[start
] );
296 if (fixup
& VERT_INDEX
) {
297 if (orflag
& VERT_INDEX
)
298 _tnl_fixup_1ui( IM
->Index
, IM
->Flag
, start
, VERT_INDEX
);
300 fixup_first_1ui( IM
->Index
, IM
->Flag
, VERT_END_VB
, start
,
304 if (fixup
& VERT_RGBA
) {
305 if (orflag
& VERT_RGBA
)
306 _tnl_fixup_4f( IM
->Color
, IM
->Flag
, start
, VERT_RGBA
);
307 /* No need for else case as the drivers understand stride
308 * zero here. (TODO - propogate this)
312 if (fixup
& VERT_SPEC_RGB
) {
313 if (orflag
& VERT_SPEC_RGB
)
314 _tnl_fixup_4f( IM
->SecondaryColor
, IM
->Flag
, start
,
317 fixup_first_4f( IM
->SecondaryColor
, IM
->Flag
, VERT_END_VB
, start
,
318 IM
->SecondaryColor
[start
] );
321 if (fixup
& VERT_FOG_COORD
) {
322 if (orflag
& VERT_FOG_COORD
)
323 _tnl_fixup_1f( IM
->FogCoord
, IM
->Flag
, start
, VERT_FOG_COORD
);
325 fixup_first_1f( IM
->FogCoord
, IM
->Flag
, VERT_END_VB
, start
,
326 IM
->FogCoord
[start
] );
329 if (fixup
& VERT_NORM
) {
330 if (orflag
& VERT_NORM
)
331 _tnl_fixup_3f( IM
->Normal
, IM
->Flag
, start
, VERT_NORM
);
333 fixup_first_3f( IM
->Normal
, IM
->Flag
, VERT_END_VB
, start
,
338 /* Prune possible half-filled slot.
340 IM
->Flag
[IM
->LastData
+1] &= ~VERT_END_VB
;
341 IM
->Flag
[IM
->Count
] |= VERT_END_VB
;
346 if (IM
->MaterialOrMask
& ~IM
->MaterialAndMask
) {
347 GLuint vulnerable
= IM
->MaterialOrMask
;
348 GLuint i
= IM
->Start
;
351 while (!(IM
->Flag
[i
] & VERT_MATERIAL
))
354 vulnerable
&= ~IM
->MaterialMask
[i
];
355 _mesa_copy_material_pairs( IM
->Material
[i
],
360 } while (vulnerable
);
367 static void copy_material( struct immediate
*next
,
368 struct immediate
*prev
,
369 GLuint dst
, GLuint src
)
371 if (next
->Material
== 0) {
372 next
->Material
= (GLmaterial (*)[2]) MALLOC( sizeof(GLmaterial
) *
374 next
->MaterialMask
= (GLuint
*) MALLOC( sizeof(GLuint
) * IMM_SIZE
);
377 next
->MaterialMask
[dst
] = prev
->MaterialOrMask
;
378 MEMCPY(next
->Material
[dst
], prev
->Material
[src
], 2*sizeof(GLmaterial
));
381 static GLboolean is_fan_like
[GL_POLYGON
+1] = {
384 GL_TRUE
, /* line loop */
388 GL_TRUE
, /* tri fan */
391 GL_TRUE
/* polygon */
395 /* Copy the untransformed data from the shared vertices of a primitive
396 * that wraps over two immediate structs. This is done prior to
397 * set_immediate so that prev and next may point to the same
398 * structure. In general it's difficult to avoid this copy on long
401 * Have to be careful with the transitions between display list
402 * replay, compile and normal execute modes.
404 void _tnl_copy_immediate_vertices( GLcontext
*ctx
, struct immediate
*next
)
406 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
407 struct immediate
*prev
= tnl
->ExecCopySource
;
408 struct vertex_arrays
*inputs
= &tnl
->imm_inputs
;
409 GLuint count
= tnl
->ExecCopyCount
;
410 GLuint
*elts
= tnl
->ExecCopyElts
;
411 GLuint offset
= IMM_MAX_COPIED_VERTS
- count
;
415 ASSERT(tnl
->ExecCopyCount
== 0);
419 next
->CopyStart
= next
->Start
- count
;
421 if ((prev
->CopyOrFlag
& VERT_DATA
) == VERT_ELT
&&
422 ctx
->Array
.LockCount
&&
423 ctx
->Array
.Vertex
.Enabled
)
425 /* Copy Elt values only
427 for (i
= 0 ; i
< count
; i
++)
429 GLuint src
= elts
[i
+offset
];
430 GLuint dst
= next
->CopyStart
+i
;
431 next
->Elt
[dst
] = prev
->Elt
[src
];
432 next
->Flag
[dst
] = VERT_ELT
;
434 /* fprintf(stderr, "ADDING VERT_ELT!\n"); */
435 next
->CopyOrFlag
|= VERT_ELT
;
436 next
->CopyAndFlag
&= VERT_ELT
;
439 GLuint copy
= tnl
->pipeline
.inputs
& (prev
->CopyOrFlag
|prev
->Evaluated
);
442 if (is_fan_like
[ctx
->Driver
.CurrentExecPrimitive
]) {
443 flag
= ((prev
->CopyOrFlag
|prev
->Evaluated
) & VERT_FIXUP
);
444 next
->CopyOrFlag
|= flag
;
447 /* Don't let an early 'glColor', etc. poison the elt path.
449 flag
= ((prev
->OrFlag
|prev
->Evaluated
) & VERT_FIXUP
);
452 next
->TexSize
|= tnl
->ExecCopyTexSize
;
453 next
->CopyAndFlag
&= flag
;
456 /* _tnl_print_vert_flags("copy vertex components", copy); */
457 /* _tnl_print_vert_flags("prev copyorflag", prev->CopyOrFlag); */
458 /* _tnl_print_vert_flags("flag", flag); */
460 /* Copy whole vertices
462 for (i
= 0 ; i
< count
; i
++)
464 GLuint src
= elts
[i
+offset
];
465 GLuint isrc
= src
- prev
->CopyStart
;
466 GLuint dst
= next
->CopyStart
+i
;
468 /* Values subject to eval must be copied out of the 'inputs'
469 * struct. (Copied rows should not be evaluated twice).
471 * Note these pointers are null when inactive.
473 COPY_4FV( next
->Obj
[dst
], inputs
->Obj
.data
[isrc
] );
475 if (copy
& VERT_NORM
) {
476 /* fprintf(stderr, "copy vert norm %d to %d (%p): %f %f %f\n", */
478 /* next->Normal[dst], */
479 /* inputs->Normal.data[isrc][0], */
480 /* inputs->Normal.data[isrc][1], */
481 /* inputs->Normal.data[isrc][2]); */
482 COPY_3FV( next
->Normal
[dst
], inputs
->Normal
.data
[isrc
] );
485 if (copy
& VERT_RGBA
)
486 COPY_4FV( next
->Color
[dst
],
487 ((GLfloat (*)[4])inputs
->Color
.Ptr
)[isrc
] );
489 if (copy
& VERT_INDEX
)
490 next
->Index
[dst
] = inputs
->Index
.data
[isrc
];
492 if (copy
& VERT_TEX_ANY
) {
494 for (i
= 0 ; i
< prev
->MaxTextureUnits
; i
++) {
495 if (copy
& VERT_TEX(i
))
496 COPY_4FV( next
->TexCoord
[i
][dst
],
497 inputs
->TexCoord
[i
].data
[isrc
] );
501 /* Remaining values should be the same in the 'input' struct and the
502 * original immediate.
504 if (copy
& (VERT_ELT
|VERT_EDGE
|VERT_SPEC_RGB
|VERT_FOG_COORD
|
507 if (prev
->Flag
[src
] & VERT_MATERIAL
)
508 copy_material(next
, prev
, dst
, src
);
510 next
->Elt
[dst
] = prev
->Elt
[src
];
511 next
->EdgeFlag
[dst
] = prev
->EdgeFlag
[src
];
512 COPY_4FV( next
->SecondaryColor
[dst
], prev
->SecondaryColor
[src
] );
513 next
->FogCoord
[dst
] = prev
->FogCoord
[src
];
516 next
->Flag
[dst
] = flag
;
517 next
->CopyOrFlag
|= prev
->Flag
[src
] & (VERT_FIXUP
|
523 if (--tnl
->ExecCopySource
->ref_count
== 0)
524 _tnl_free_immediate( tnl
->ExecCopySource
);
526 tnl
->ExecCopySource
= 0;
527 tnl
->ExecCopyCount
= 0;
532 /* Revive a compiled immediate struct - propogate new 'Current'
533 * values. Often this is redundant because the current values were
534 * known and fixed up at compile time (or in the first execution of
537 void _tnl_fixup_compiled_cassette( GLcontext
*ctx
, struct immediate
*IM
)
539 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
541 GLuint start
= IM
->Start
;
543 /* fprintf(stderr, "%s\n", __FUNCTION__); */
546 IM
->CopyOrFlag
= IM
->OrFlag
;
547 IM
->CopyAndFlag
= IM
->AndFlag
;
548 IM
->CopyTexSize
= IM
->TexSize
| tnl
->ExecCopyTexSize
;
550 _tnl_copy_immediate_vertices( ctx
, IM
);
552 if (ctx
->Driver
.CurrentExecPrimitive
== GL_POLYGON
+1) {
553 ASSERT(IM
->CopyStart
== IM
->Start
);
556 /* Naked array elements can be copied into the first cassette in a
557 * display list. Need to translate them away:
559 if (IM
->CopyOrFlag
& VERT_ELT
) {
560 GLuint copy
= tnl
->pipeline
.inputs
& ~ctx
->Array
._Enabled
;
563 ASSERT(IM
->CopyStart
< IM
->Start
);
565 _tnl_translate_array_elts( ctx
, IM
, IM
->CopyStart
, IM
->Start
);
567 for (i
= IM
->CopyStart
; i
< IM
->Start
; i
++)
568 copy_from_current( ctx
, IM
, i
, copy
);
570 _tnl_copy_to_current( ctx
, IM
, ctx
->Array
._Enabled
, IM
->Start
);
573 fixup
= tnl
->pipeline
.inputs
& ~IM
->Flag
[start
] & VERT_FIXUP
;
575 /* _tnl_print_vert_flags("fixup compiled", fixup); */
578 if (fixup
& VERT_TEX_ANY
) {
580 for (i
= 0 ; i
< ctx
->Const
.MaxTextureUnits
; i
++) {
581 if (fixup
& VERT_TEX(i
))
582 fixup_first_4f( IM
->TexCoord
[i
], IM
->Flag
, VERT_TEX(i
), start
,
583 ctx
->Current
.Texcoord
[i
] );
587 if (fixup
& VERT_EDGE
)
588 fixup_first_1ub(IM
->EdgeFlag
, IM
->Flag
, VERT_EDGE
, start
,
589 ctx
->Current
.EdgeFlag
);
591 if (fixup
& VERT_INDEX
)
592 fixup_first_1ui(IM
->Index
, IM
->Flag
, VERT_INDEX
, start
,
593 ctx
->Current
.Index
);
595 if (fixup
& VERT_RGBA
) {
596 if (IM
->CopyOrFlag
& VERT_RGBA
)
597 fixup_first_4f(IM
->Color
, IM
->Flag
, VERT_RGBA
, start
,
598 ctx
->Current
.Color
);
603 if (fixup
& VERT_SPEC_RGB
)
604 fixup_first_4f(IM
->SecondaryColor
, IM
->Flag
, VERT_SPEC_RGB
, start
,
605 ctx
->Current
.SecondaryColor
);
607 if (fixup
& VERT_FOG_COORD
)
608 fixup_first_1f(IM
->FogCoord
, IM
->Flag
, VERT_FOG_COORD
, start
,
609 ctx
->Current
.FogCoord
);
611 if (fixup
& VERT_NORM
) {
612 fixup_first_3f(IM
->Normal
, IM
->Flag
, VERT_NORM
, start
,
613 ctx
->Current
.Normal
);
616 IM
->CopyOrFlag
|= fixup
;
622 if (IM
->MaterialOrMask
& ~IM
->MaterialAndMask
) {
623 GLuint vulnerable
= IM
->MaterialOrMask
;
624 GLuint i
= IM
->Start
;
627 while (!(IM
->Flag
[i
] & VERT_MATERIAL
))
630 vulnerable
&= ~IM
->MaterialMask
[i
];
631 _mesa_copy_material_pairs( IM
->Material
[i
],
636 } while (vulnerable
);
645 static void copy_none( TNLcontext
*tnl
, GLuint start
, GLuint count
, GLuint ovf
)
647 (void) (start
&& ovf
&& tnl
&& count
);
650 static void copy_last( TNLcontext
*tnl
, GLuint start
, GLuint count
, GLuint ovf
)
652 (void) start
; (void) ovf
;
653 tnl
->ExecCopyCount
= 1;
654 tnl
->ExecCopyElts
[2] = count
-1;
657 static void copy_first_and_last( TNLcontext
*tnl
, GLuint start
, GLuint count
,
661 tnl
->ExecCopyCount
= 2;
662 tnl
->ExecCopyElts
[1] = start
;
663 tnl
->ExecCopyElts
[2] = count
-1;
666 static void copy_last_two( TNLcontext
*tnl
, GLuint start
, GLuint count
,
670 tnl
->ExecCopyCount
= 2+ovf
;
671 tnl
->ExecCopyElts
[0] = count
-3;
672 tnl
->ExecCopyElts
[1] = count
-2;
673 tnl
->ExecCopyElts
[2] = count
-1;
676 static void copy_overflow( TNLcontext
*tnl
, GLuint start
, GLuint count
,
680 tnl
->ExecCopyCount
= ovf
;
681 tnl
->ExecCopyElts
[0] = count
-3;
682 tnl
->ExecCopyElts
[1] = count
-2;
683 tnl
->ExecCopyElts
[2] = count
-1;
687 typedef void (*copy_func
)( TNLcontext
*tnl
, GLuint start
, GLuint count
,
690 static copy_func copy_tab
[GL_POLYGON
+2] =
709 /* Figure out what vertices need to be copied next time.
712 _tnl_get_exec_copy_verts( GLcontext
*ctx
, struct immediate
*IM
)
715 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
716 GLuint last
= IM
->LastPrimitive
;
717 GLuint prim
= ctx
->Driver
.CurrentExecPrimitive
;
718 GLuint pincr
= increment
[prim
];
719 GLuint pintro
= intro
[prim
];
722 /* fprintf(stderr, "_tnl_get_exec_copy_verts %s\n", */
723 /* _mesa_lookup_enum_by_nr(prim)); */
725 ASSERT(tnl
->ExecCopySource
== 0);
727 if (prim
== GL_POLYGON
+1) {
728 tnl
->ExecCopyCount
= 0;
729 tnl
->ExecCopyTexSize
= 0;
732 /* Remember this immediate as the one to copy from.
735 tnl
->ExecCopySource
= IM
;
736 tnl
->ExecCopyCount
= 0;
737 tnl
->ExecCopyTexSize
= IM
->CopyTexSize
;
739 if (IM
->LastPrimitive
!= IM
->CopyStart
)
742 tnl
->ExecParity
^= IM
->PrimitiveLength
[IM
->LastPrimitive
] & 1;
745 if (pincr
!= 1 && (IM
->Count
- last
- pintro
))
746 ovf
= (IM
->Count
- last
- pintro
) % pincr
;
748 if (last
< IM
->Count
)
749 copy_tab
[prim
]( tnl
, last
, IM
->Count
, ovf
);
754 /* Recalculate ExecCopyElts, ExecParity, etc.
757 _tnl_get_purged_copy_verts( GLcontext
*ctx
, struct immediate
*IM
)
759 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
761 if (ctx
->Driver
.CurrentExecPrimitive
!= GL_POLYGON
+1) {
762 GLuint last
= IM
->LastPrimitive
;
763 GLenum prim
= IM
->Primitive
[last
];
764 GLuint pincr
= increment
[prim
];
765 GLuint pintro
= intro
[prim
];
768 tnl
->ExecCopyCount
= 0;
769 if (IM
->LastPrimitive
!= IM
->CopyStart
)
772 tnl
->ExecParity
^= IM
->PrimitiveLength
[IM
->LastPrimitive
] & 1;
774 if (pincr
!= 1 && (IM
->Count
- last
- pintro
))
775 ovf
= (IM
->Count
- last
- pintro
) % pincr
;
777 if (last
< IM
->Count
)
778 copy_tab
[prim
]( tnl
, last
, IM
->Count
, ovf
);
780 for (i
= 0 ; i
< tnl
->ExecCopyCount
; i
++)
781 tnl
->ExecCopyElts
[i
] = IM
->Elt
[tnl
->ExecCopyElts
[i
]];
786 void _tnl_upgrade_current_data( GLcontext
*ctx
,
790 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
791 struct vertex_buffer
*VB
= &tnl
->vb
;
792 struct immediate
*IM
= (struct immediate
*)VB
->import_source
;
796 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
798 if ((required
& VERT_RGBA
) && (VB
->ColorPtr
[0]->Flags
& CA_CLIENT_DATA
)) {
799 struct gl_client_array
*tmp
= &tnl
->imm_inputs
.Color
;
800 GLuint start
= IM
->CopyStart
;
802 tmp
->Ptr
= IM
->Color
+ start
;
803 tmp
->StrideB
= 4 * sizeof(GLfloat
);
806 COPY_4FV( IM
->Color
[start
], ctx
->Current
.Color
);
809 ASSERT(IM->Flag[IM->LastData+1] & VERT_END_VB);
812 fixup_first_4f( IM
->Color
, IM
->Flag
, VERT_END_VB
, start
,
815 VB
->importable_data
&= ~VERT_RGBA
;