1 /* $Id: t_imm_fixup.c,v 1.35 2002/04/09 16:56:52 keithw Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 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_BIT_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_BIT_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_BIT_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_BIT_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_BIT_END_VB
) break;
138 fixup_first_4f( GLfloat data
[][4], GLuint flag
[], GLuint match
,
139 GLuint start
, GLfloat
*dflt
)
142 match
|= VERT_BIT_END_VB
;
144 while ((flag
[++i
]&match
) == 0)
145 COPY_4FV(data
[i
], dflt
);
150 fixup_first_3f( GLfloat data
[][3], GLuint flag
[], GLuint match
,
151 GLuint start
, GLfloat
*dflt
)
154 match
|= VERT_BIT_END_VB
;
156 /* fprintf(stderr, "fixup_first_3f default: %f %f %f start: %d\n", */
157 /* dflt[0], dflt[1], dflt[2], start); */
159 while ((flag
[++i
]&match
) == 0)
160 COPY_3FV(data
[i
], dflt
);
165 fixup_first_1ui( GLuint data
[], GLuint flag
[], GLuint match
,
166 GLuint start
, GLuint dflt
)
169 match
|= VERT_BIT_END_VB
;
171 while ((flag
[++i
]&match
) == 0)
177 fixup_first_1f( GLfloat data
[], GLuint flag
[], GLuint match
,
178 GLuint start
, GLfloat dflt
)
181 match
|= VERT_BIT_END_VB
;
183 while ((flag
[++i
]&match
) == 0)
189 fixup_first_1ub( GLubyte data
[], GLuint flag
[], GLuint match
,
190 GLuint start
, GLubyte dflt
)
193 match
|= VERT_BIT_END_VB
;
195 while ((flag
[++i
]&match
) == 0)
200 * Copy vertex attributes from the ctx->Current group into the immediate
201 * struct at the given position according to copyMask.
203 static void copy_from_current( GLcontext
*ctx
, struct immediate
*IM
,
204 GLuint pos
, GLuint copyMask
)
206 GLuint attrib
, attribBit
;
208 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
209 _tnl_print_vert_flags("copy from current", copyMask
);
212 if (copyMask
& VERT_BIT_NORMAL
) {
213 COPY_4V(IM
->Attrib
[VERT_ATTRIB_NORMAL
][pos
],
214 ctx
->Current
.Attrib
[VERT_ATTRIB_NORMAL
]);
217 if (copyMask
& VERT_BIT_COLOR0
) {
218 COPY_4FV( IM
->Attrib
[VERT_ATTRIB_COLOR0
][pos
],
219 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
]);
222 if (copyMask
& VERT_BIT_COLOR1
)
223 COPY_4FV( IM
->Attrib
[VERT_ATTRIB_COLOR1
][pos
],
224 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR1
]);
226 if (copyMask
& VERT_BIT_FOG
)
227 IM
->Attrib
[VERT_ATTRIB_FOG
][pos
][0] = ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
][0];
229 if (copyMask
& VERT_BITS_TEX_ANY
) {
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
]);
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
]);
245 if (copyMask
& VERT_BIT_INDEX
)
246 IM
->Index
[pos
] = ctx
->Current
.Index
;
248 if (copyMask
& VERT_BIT_EDGEFLAG
)
249 IM
->EdgeFlag
[pos
] = ctx
->Current
.EdgeFlag
;
253 void _tnl_fixup_input( GLcontext
*ctx
, struct immediate
*IM
)
255 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
256 GLuint start
= IM
->CopyStart
;
257 GLuint andflag
= IM
->CopyAndFlag
;
258 GLuint orflag
= IM
->CopyOrFlag
| IM
->Evaluated
;
261 IM
->CopyTexSize
= IM
->TexSize
;
263 /* fprintf(stderr, "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); */
269 fixup
= ~andflag
& VERT_BITS_FIXUP
;
271 if (!ctx
->CompileFlag
)
272 fixup
&= tnl
->pipeline
.inputs
;
274 if (!ctx
->ExecuteFlag
)
277 if ((orflag
& (VERT_BIT_POS
|VERT_BITS_EVAL_ANY
)) == 0)
281 GLuint copy
= fixup
& ~IM
->Flag
[start
];
284 /* Equivalent to a lazy copy-from-current when setting up the
287 if (ctx
->ExecuteFlag
&& copy
)
288 copy_from_current( ctx
, IM
, start
, copy
);
290 if (MESA_VERBOSE
&VERBOSE_IMMEDIATE
)
291 _tnl_print_vert_flags("fixup", fixup
);
293 /* XXX replace these conditionals with a loop over the 16
297 if (fixup
& VERT_BITS_TEX_ANY
) {
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
) );
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
]);
313 if (fixup
& VERT_BIT_EDGEFLAG
) {
314 if (orflag
& VERT_BIT_EDGEFLAG
)
315 _tnl_fixup_1ub( IM
->EdgeFlag
, IM
->Flag
, start
, VERT_BIT_EDGEFLAG
);
317 fixup_first_1ub( IM
->EdgeFlag
, IM
->Flag
, VERT_BIT_END_VB
, start
,
318 IM
->EdgeFlag
[start
] );
321 if (fixup
& VERT_BIT_INDEX
) {
322 if (orflag
& VERT_BIT_INDEX
)
323 _tnl_fixup_1ui( IM
->Index
, IM
->Flag
, start
, VERT_BIT_INDEX
);
325 fixup_first_1ui( IM
->Index
, IM
->Flag
, VERT_BIT_END_VB
, start
,
329 if (fixup
& VERT_BIT_COLOR0
) {
330 if (orflag
& VERT_BIT_COLOR0
)
331 _tnl_fixup_4f( IM
->Attrib
[VERT_ATTRIB_COLOR0
], IM
->Flag
, start
,
333 /* No need for else case as the drivers understand stride
334 * zero here. (TODO - propogate this)
338 if (fixup
& VERT_BIT_COLOR1
) {
339 if (orflag
& VERT_BIT_COLOR1
)
340 _tnl_fixup_4f( IM
->Attrib
[VERT_ATTRIB_COLOR1
], IM
->Flag
, start
,
343 fixup_first_4f( IM
->Attrib
[VERT_ATTRIB_COLOR1
], IM
->Flag
, VERT_BIT_END_VB
, start
,
344 IM
->Attrib
[VERT_ATTRIB_COLOR1
][start
] );
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
);
352 fixup_first_4f( IM
->Attrib
[VERT_ATTRIB_FOG
], IM
->Flag
, VERT_BIT_END_VB
,
353 start
, IM
->Attrib
[VERT_ATTRIB_FOG
][start
] );
356 if (fixup
& VERT_BIT_NORMAL
) {
357 if (orflag
& VERT_BIT_NORMAL
)
358 _tnl_fixup_4f( IM
->Attrib
[VERT_ATTRIB_NORMAL
], IM
->Flag
, start
,
361 fixup_first_4f( IM
->Attrib
[VERT_ATTRIB_NORMAL
], IM
->Flag
,
362 VERT_BIT_END_VB
, start
,
363 IM
->Attrib
[VERT_ATTRIB_NORMAL
][start
] );
367 /* Prune possible half-filled slot.
369 IM
->Flag
[IM
->LastData
+1] &= ~VERT_BIT_END_VB
;
370 IM
->Flag
[IM
->Count
] |= VERT_BIT_END_VB
;
375 if (IM
->MaterialOrMask
& ~IM
->MaterialAndMask
) {
376 GLuint vulnerable
= IM
->MaterialOrMask
;
377 GLuint i
= IM
->Start
;
380 while (!(IM
->Flag
[i
] & VERT_BIT_MATERIAL
))
383 vulnerable
&= ~IM
->MaterialMask
[i
];
384 _mesa_copy_material_pairs( IM
->Material
[i
],
390 } while (vulnerable
);
396 copy_material( struct immediate
*next
,
397 struct immediate
*prev
,
398 GLuint dst
, GLuint src
)
400 /* fprintf(stderr, "%s\n", __FUNCTION__); */
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
);
408 next
->MaterialMask
[dst
] = prev
->MaterialOrMask
;
409 MEMCPY(next
->Material
[dst
], prev
->Material
[src
],
410 2 * sizeof(struct gl_material
));
415 static GLboolean is_fan_like
[GL_POLYGON
+1] = {
418 GL_TRUE
, /* line loop */
422 GL_TRUE
, /* tri fan */
425 GL_TRUE
/* polygon */
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
435 * Have to be careful with the transitions between display list
436 * replay, compile and normal execute modes.
438 void _tnl_copy_immediate_vertices( GLcontext
*ctx
, struct immediate
*next
)
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
;
449 ASSERT(tnl
->ExecCopyCount
== 0);
453 next
->CopyStart
= next
->Start
- count
;
455 if ((prev
->CopyOrFlag
& VERT_BITS_DATA
) == VERT_BIT_ELT
&&
456 ctx
->Array
.LockCount
&&
457 ctx
->Array
.Vertex
.Enabled
)
459 /* Copy Elt values only
461 for (i
= 0 ; i
< count
; i
++)
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
;
469 /* fprintf(stderr, "ADDING VERT_BIT_ELT!\n"); */
470 next
->CopyOrFlag
|= VERT_BIT_ELT
;
471 next
->CopyAndFlag
&= VERT_BIT_ELT
;
474 GLuint copy
= tnl
->pipeline
.inputs
& (prev
->CopyOrFlag
|prev
->Evaluated
);
477 if (is_fan_like
[ctx
->Driver
.CurrentExecPrimitive
]) {
478 flag
= ((prev
->CopyOrFlag
|prev
->Evaluated
) & VERT_BITS_FIXUP
);
479 next
->CopyOrFlag
|= flag
;
482 /* Don't let an early 'glColor', etc. poison the elt path.
484 flag
= ((prev
->OrFlag
|prev
->Evaluated
) & VERT_BITS_FIXUP
);
487 next
->TexSize
|= tnl
->ExecCopyTexSize
;
488 next
->CopyAndFlag
&= flag
;
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); */
495 /* Copy whole vertices
497 for (i
= 0 ; i
< count
; i
++)
499 GLuint src
= elts
[i
+offset
];
500 GLuint isrc
= src
- prev
->CopyStart
;
501 GLuint dst
= next
->CopyStart
+i
;
503 /* Values subject to eval must be copied out of the 'inputs'
504 * struct. (Copied rows should not be evaluated twice).
506 * Note these pointers are null when inactive.
508 COPY_4FV( next
->Attrib
[VERT_ATTRIB_POS
][dst
],
509 inputs
->Obj
.data
[isrc
] );
511 if (copy
& VERT_BIT_NORMAL
) {
512 /* fprintf(stderr, "copy vert norm %d to %d (%p): %f %f %f\n", */
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
] );
521 if (copy
& VERT_BIT_COLOR0
)
522 COPY_4FV( next
->Attrib
[VERT_ATTRIB_COLOR0
][dst
],
523 ((GLfloat (*)[4])inputs
->Color
.Ptr
)[isrc
] );
525 if (copy
& VERT_BIT_INDEX
)
526 next
->Index
[dst
] = inputs
->Index
.data
[isrc
];
528 if (copy
& VERT_BITS_TEX_ANY
) {
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
] );
537 /* Remaining values should be the same in the 'input' struct and the
538 * original immediate.
540 if (copy
& (VERT_BIT_ELT
|VERT_BIT_EDGEFLAG
|VERT_BIT_COLOR1
|VERT_BIT_FOG
|
541 VERT_BIT_MATERIAL
)) {
543 if (prev
->Flag
[src
] & VERT_BIT_MATERIAL
)
544 copy_material(next
, prev
, dst
, src
);
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
] );
554 next
->Flag
[dst
] = flag
;
555 next
->CopyOrFlag
|= prev
->Flag
[src
] & (VERT_BITS_FIXUP
|
558 elts
[i
+offset
] = dst
;
562 if (--tnl
->ExecCopySource
->ref_count
== 0)
563 _tnl_free_immediate( tnl
->ExecCopySource
);
565 tnl
->ExecCopySource
= next
; next
->ref_count
++;
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
575 void _tnl_fixup_compiled_cassette( GLcontext
*ctx
, struct immediate
*IM
)
577 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
579 GLuint start
= IM
->Start
;
581 /* fprintf(stderr, "%s\n", __FUNCTION__); */
584 IM
->CopyOrFlag
= IM
->OrFlag
;
585 IM
->CopyAndFlag
= IM
->AndFlag
;
586 IM
->CopyTexSize
= IM
->TexSize
| tnl
->ExecCopyTexSize
;
588 _tnl_copy_immediate_vertices( ctx
, IM
);
590 if (ctx
->Driver
.CurrentExecPrimitive
== GL_POLYGON
+1) {
591 ASSERT(IM
->CopyStart
== IM
->Start
);
594 /* Naked array elements can be copied into the first cassette in a
595 * display list. Need to translate them away:
597 if (IM
->CopyOrFlag
& VERT_BIT_ELT
) {
598 GLuint copy
= tnl
->pipeline
.inputs
& ~ctx
->Array
._Enabled
;
601 ASSERT(IM
->CopyStart
< IM
->Start
);
603 _tnl_translate_array_elts( ctx
, IM
, IM
->CopyStart
, IM
->Start
);
605 for (i
= IM
->CopyStart
; i
< IM
->Start
; i
++)
606 copy_from_current( ctx
, IM
, i
, copy
);
608 _tnl_copy_to_current( ctx
, IM
, ctx
->Array
._Enabled
, IM
->Start
);
611 fixup
= tnl
->pipeline
.inputs
& ~IM
->Flag
[start
] & VERT_BITS_FIXUP
;
613 /* _tnl_print_vert_flags("fixup compiled", fixup); */
617 /* XXX try to replace this code with a loop over the 16 vertex
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
] );
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
] );
633 fixup
&= ~VERT_BIT_COLOR0
;
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
] );
641 if (fixup
& VERT_BIT_FOG
)
642 fixup_first_4f( IM
->Attrib
[VERT_ATTRIB_FOG
], IM
->Flag
,
644 ctx
->Current
.Attrib
[VERT_ATTRIB_FOG
] );
646 if (fixup
& VERT_BITS_TEX_ANY
) {
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
] );
656 if (fixup
& VERT_BIT_EDGEFLAG
)
657 fixup_first_1ub(IM
->EdgeFlag
, IM
->Flag
, VERT_BIT_EDGEFLAG
, start
,
658 ctx
->Current
.EdgeFlag
);
660 if (fixup
& VERT_BIT_INDEX
)
661 fixup_first_1ui(IM
->Index
, IM
->Flag
, VERT_BIT_INDEX
, start
,
662 ctx
->Current
.Index
);
664 IM
->CopyOrFlag
|= fixup
;
670 if (IM
->MaterialOrMask
& ~IM
->MaterialAndMask
) {
671 GLuint vulnerable
= IM
->MaterialOrMask
;
672 GLuint i
= IM
->Start
;
675 while (!(IM
->Flag
[i
] & VERT_BIT_MATERIAL
))
678 vulnerable
&= ~IM
->MaterialMask
[i
];
679 _mesa_copy_material_pairs( IM
->Material
[i
],
685 } while (vulnerable
);
694 static void copy_none( TNLcontext
*tnl
, GLuint start
, GLuint count
, GLuint ovf
)
696 (void) (start
&& ovf
&& tnl
&& count
);
699 static void copy_last( TNLcontext
*tnl
, GLuint start
, GLuint count
, GLuint ovf
)
701 (void) start
; (void) ovf
;
702 tnl
->ExecCopyCount
= 1;
703 tnl
->ExecCopyElts
[2] = count
-1;
706 static void copy_first_and_last( TNLcontext
*tnl
, GLuint start
, GLuint count
,
710 tnl
->ExecCopyCount
= 2;
711 tnl
->ExecCopyElts
[1] = start
;
712 tnl
->ExecCopyElts
[2] = count
-1;
715 static void copy_last_two( TNLcontext
*tnl
, GLuint start
, GLuint count
,
719 tnl
->ExecCopyCount
= 2+ovf
;
720 tnl
->ExecCopyElts
[0] = count
-3;
721 tnl
->ExecCopyElts
[1] = count
-2;
722 tnl
->ExecCopyElts
[2] = count
-1;
725 static void copy_overflow( TNLcontext
*tnl
, GLuint start
, GLuint count
,
729 tnl
->ExecCopyCount
= ovf
;
730 tnl
->ExecCopyElts
[0] = count
-3;
731 tnl
->ExecCopyElts
[1] = count
-2;
732 tnl
->ExecCopyElts
[2] = count
-1;
736 typedef void (*copy_func
)( TNLcontext
*tnl
, GLuint start
, GLuint count
,
739 static copy_func copy_tab
[GL_POLYGON
+2] =
758 /* Figure out what vertices need to be copied next time.
761 _tnl_get_exec_copy_verts( GLcontext
*ctx
, struct immediate
*IM
)
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
];
771 /* fprintf(stderr, "_tnl_get_exec_copy_verts %s\n", */
772 /* _mesa_lookup_enum_by_nr(prim)); */
774 if (tnl
->ExecCopySource
)
775 if (--tnl
->ExecCopySource
->ref_count
== 0)
776 _tnl_free_immediate( tnl
->ExecCopySource
);
778 if (prim
== GL_POLYGON
+1) {
779 tnl
->ExecCopySource
= 0;
780 tnl
->ExecCopyCount
= 0;
781 tnl
->ExecCopyTexSize
= 0;
784 /* Remember this immediate as the one to copy from.
786 tnl
->ExecCopySource
= IM
; IM
->ref_count
++;
787 tnl
->ExecCopyCount
= 0;
788 tnl
->ExecCopyTexSize
= IM
->CopyTexSize
;
790 if (IM
->LastPrimitive
!= IM
->CopyStart
)
793 tnl
->ExecParity
^= IM
->PrimitiveLength
[IM
->LastPrimitive
] & 1;
796 if (pincr
!= 1 && (IM
->Count
- last
- pintro
))
797 ovf
= (IM
->Count
- last
- pintro
) % pincr
;
799 if (last
< IM
->Count
)
800 copy_tab
[prim
]( tnl
, last
, IM
->Count
, ovf
);
805 /* Recalculate ExecCopyElts, ExecParity, etc.
808 _tnl_get_purged_copy_verts( GLcontext
*ctx
, struct immediate
*IM
)
810 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
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
];
819 tnl
->ExecCopyCount
= 0;
820 if (IM
->LastPrimitive
!= IM
->CopyStart
)
823 tnl
->ExecParity
^= IM
->PrimitiveLength
[IM
->LastPrimitive
] & 1;
825 if (pincr
!= 1 && (IM
->Count
- last
- pintro
))
826 ovf
= (IM
->Count
- last
- pintro
) % pincr
;
828 if (last
< IM
->Count
)
829 copy_tab
[prim
]( tnl
, last
, IM
->Count
, ovf
);
831 for (i
= 0 ; i
< tnl
->ExecCopyCount
; i
++)
832 tnl
->ExecCopyElts
[i
] = IM
->Elt
[tnl
->ExecCopyElts
[i
]];
837 void _tnl_upgrade_current_data( GLcontext
*ctx
,
841 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
842 struct vertex_buffer
*VB
= &tnl
->vb
;
843 struct immediate
*IM
= (struct immediate
*)VB
->import_source
;
847 /* _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
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
;
853 tmp
->Ptr
= IM
->Attrib
[VERT_ATTRIB_COLOR0
] + start
;
854 tmp
->StrideB
= 4 * sizeof(GLfloat
);
857 COPY_4FV( IM
->Attrib
[VERT_ATTRIB_COLOR0
][start
],
858 ctx
->Current
.Attrib
[VERT_ATTRIB_COLOR0
]);
861 ASSERT(IM->Flag[IM->LastData+1] & VERT_BIT_END_VB);
864 fixup_first_4f( IM
->Attrib
[VERT_ATTRIB_COLOR0
], IM
->Flag
,
866 start
, IM
->Attrib
[VERT_ATTRIB_COLOR0
][start
] );
868 VB
->importable_data
&= ~VERT_BIT_COLOR0
;