Clean-up/renaming of the per-vertex attribute bits, specifically, the
[mesa.git] / src / mesa / tnl / t_imm_eval.c
1 /* $Id: t_imm_eval.c,v 1.21 2002/01/22 14:35:16 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
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 <keithw@valinux.com>
28 *
29 */
30
31
32 #include "glheader.h"
33 #include "colormac.h"
34 #include "context.h"
35 #include "macros.h"
36 #include "mem.h"
37 #include "mmath.h"
38 #include "mtypes.h"
39 #include "math/m_eval.h"
40
41 #include "t_context.h"
42 #include "t_imm_debug.h"
43 #include "t_imm_eval.h"
44 #include "t_imm_exec.h"
45 #include "t_imm_fixup.h"
46 #include "t_imm_alloc.h"
47
48
49 static void eval_points1( GLfloat outcoord[][4],
50 GLfloat coord[][4],
51 const GLuint *flags,
52 GLfloat du, GLfloat u1 )
53 {
54 GLuint i;
55 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
56 if (flags[i] & VERT_BITS_EVAL_ANY) {
57 outcoord[i][0] = coord[i][0];
58 outcoord[i][1] = coord[i][1];
59 if (flags[i] & VERT_BIT_EVAL_P1)
60 outcoord[i][0] = coord[i][0] * du + u1;
61 }
62 }
63
64 static void eval_points2( GLfloat outcoord[][4],
65 GLfloat coord[][4],
66 const GLuint *flags,
67 GLfloat du, GLfloat u1,
68 GLfloat dv, GLfloat v1 )
69 {
70 GLuint i;
71 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++) {
72 if (flags[i] & VERT_BITS_EVAL_ANY) {
73 outcoord[i][0] = coord[i][0];
74 outcoord[i][1] = coord[i][1];
75 if (flags[i] & VERT_BIT_EVAL_P2) {
76 outcoord[i][0] = coord[i][0] * du + u1;
77 outcoord[i][1] = coord[i][1] * dv + v1;
78 }
79 }
80 }
81 }
82
83 static const GLubyte dirty_flags[5] = {
84 0, /* not possible */
85 VEC_DIRTY_0,
86 VEC_DIRTY_1,
87 VEC_DIRTY_2,
88 VEC_DIRTY_3
89 };
90
91
92 static void eval1_4f( GLvector4f *dest,
93 GLfloat coord[][4],
94 const GLuint *flags,
95 GLuint dimension,
96 struct gl_1d_map *map )
97 {
98 const GLfloat u1 = map->u1;
99 const GLfloat du = map->du;
100 GLfloat (*to)[4] = dest->data;
101 GLuint i;
102
103 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
104 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
105 GLfloat u = (coord[i][0] - u1) * du;
106 ASSIGN_4V(to[i], 0,0,0,1);
107 _math_horner_bezier_curve(map->Points, to[i], u,
108 dimension, map->Order);
109 }
110
111 dest->size = MAX2(dest->size, dimension);
112 dest->flags |= dirty_flags[dimension];
113 }
114
115 static void eval1_4f_ca( struct gl_client_array *dest,
116 GLfloat coord[][4],
117 const GLuint *flags,
118 GLuint dimension,
119 struct gl_1d_map *map )
120 {
121 const GLfloat u1 = map->u1;
122 const GLfloat du = map->du;
123 GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
124 GLuint i;
125
126 ASSERT(dest->Type == GL_FLOAT);
127 ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
128
129 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
130 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
131 GLfloat u = (coord[i][0] - u1) * du;
132 ASSIGN_4V(to[i], 0,0,0,1);
133 _math_horner_bezier_curve(map->Points, to[i], u,
134 dimension, map->Order);
135 }
136
137 dest->Size = MAX2(dest->Size, (GLint) dimension);
138 }
139
140
141 static void eval1_1ui( GLvector1ui *dest,
142 GLfloat coord[][4],
143 const GLuint *flags,
144 struct gl_1d_map *map )
145 {
146 const GLfloat u1 = map->u1;
147 const GLfloat du = map->du;
148 GLuint *to = dest->data;
149 GLuint i;
150
151 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
152 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
153 GLfloat u = (coord[i][0] - u1) * du;
154 GLfloat tmp;
155 _math_horner_bezier_curve(map->Points, &tmp, u, 1, map->Order);
156 to[i] = (GLuint) (GLint) tmp;
157 }
158
159 }
160
161 static void eval1_norm( GLvector4f *dest,
162 GLfloat coord[][4],
163 const GLuint *flags,
164 struct gl_1d_map *map )
165 {
166 const GLfloat u1 = map->u1;
167 const GLfloat du = map->du;
168 GLfloat (*to)[4] = dest->data;
169 GLuint i;
170
171 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
172 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
173 GLfloat u = (coord[i][0] - u1) * du;
174 _math_horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
175 }
176 }
177
178
179
180
181
182 static void eval2_obj_norm( GLvector4f *obj_ptr,
183 GLvector4f *norm_ptr,
184 GLfloat coord[][4],
185 GLuint *flags,
186 GLuint dimension,
187 struct gl_2d_map *map )
188 {
189 const GLfloat u1 = map->u1;
190 const GLfloat du = map->du;
191 const GLfloat v1 = map->v1;
192 const GLfloat dv = map->dv;
193 GLfloat (*obj)[4] = obj_ptr->data;
194 GLfloat (*normal)[4] = norm_ptr->data;
195 GLuint i;
196
197 /* fprintf(stderr, "%s\n", __FUNCTION__); */
198
199 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
200 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
201 GLfloat u = (coord[i][0] - u1) * du;
202 GLfloat v = (coord[i][1] - v1) * dv;
203 GLfloat du[4], dv[4];
204
205 ASSIGN_4V(obj[i], 0,0,0,1);
206 _math_de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension,
207 map->Uorder, map->Vorder);
208
209 if (dimension == 4) {
210 du[0] = du[0]*obj[i][3] - du[3]*obj[i][0];
211 du[1] = du[1]*obj[i][3] - du[3]*obj[i][1];
212 du[2] = du[2]*obj[i][3] - du[3]*obj[i][2];
213
214 dv[0] = dv[0]*obj[i][3] - dv[3]*obj[i][0];
215 dv[1] = dv[1]*obj[i][3] - dv[3]*obj[i][1];
216 dv[2] = dv[2]*obj[i][3] - dv[3]*obj[i][2];
217 }
218
219 CROSS3(normal[i], du, dv);
220 NORMALIZE_3FV(normal[i]);
221 }
222
223 obj_ptr->size = MAX2(obj_ptr->size, dimension);
224 obj_ptr->flags |= dirty_flags[dimension];
225 }
226
227
228 static void eval2_4f( GLvector4f *dest,
229 GLfloat coord[][4],
230 const GLuint *flags,
231 GLuint dimension,
232 struct gl_2d_map *map )
233 {
234 const GLfloat u1 = map->u1;
235 const GLfloat du = map->du;
236 const GLfloat v1 = map->v1;
237 const GLfloat dv = map->dv;
238 GLfloat (*to)[4] = dest->data;
239 GLuint i;
240
241 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
242 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
243 GLfloat u = (coord[i][0] - u1) * du;
244 GLfloat v = (coord[i][1] - v1) * dv;
245 /* fprintf(stderr, "coord %d: %f %f\n", i, coord[i][0], coord[i][1]); */
246
247 _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
248 map->Uorder, map->Vorder);
249 }
250
251 dest->size = MAX2(dest->size, dimension);
252 dest->flags |= dirty_flags[dimension];
253 }
254
255 static void eval2_4f_ca( struct gl_client_array *dest,
256 GLfloat coord[][4],
257 const GLuint *flags,
258 GLuint dimension,
259 struct gl_2d_map *map )
260 {
261 const GLfloat u1 = map->u1;
262 const GLfloat du = map->du;
263 const GLfloat v1 = map->v1;
264 const GLfloat dv = map->dv;
265 GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
266 GLuint i;
267
268 ASSERT(dest->Type == GL_FLOAT);
269 ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
270
271 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
272 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
273 GLfloat u = (coord[i][0] - u1) * du;
274 GLfloat v = (coord[i][1] - v1) * dv;
275 _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
276 map->Uorder, map->Vorder);
277 }
278
279 dest->Size = MAX2(dest->Size, (GLint) dimension);
280 }
281
282
283 static void eval2_norm( GLvector4f *dest,
284 GLfloat coord[][4],
285 GLuint *flags,
286 struct gl_2d_map *map )
287 {
288 const GLfloat u1 = map->u1;
289 const GLfloat du = map->du;
290 const GLfloat v1 = map->v1;
291 const GLfloat dv = map->dv;
292 GLfloat (*to)[4] = dest->data;
293 GLuint i;
294
295 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++) {
296 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
297 GLfloat u = (coord[i][0] - u1) * du;
298 GLfloat v = (coord[i][1] - v1) * dv;
299 _math_horner_bezier_surf(map->Points, to[i], u, v, 3,
300 map->Uorder, map->Vorder);
301 }
302 }
303 }
304
305
306 static void eval2_1ui( GLvector1ui *dest,
307 GLfloat coord[][4],
308 const GLuint *flags,
309 struct gl_2d_map *map )
310 {
311 const GLfloat u1 = map->u1;
312 const GLfloat du = map->du;
313 const GLfloat v1 = map->v1;
314 const GLfloat dv = map->dv;
315 GLuint *to = dest->data;
316 GLuint i;
317
318 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
319 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
320 GLfloat u = (coord[i][0] - u1) * du;
321 GLfloat v = (coord[i][1] - v1) * dv;
322 GLfloat tmp;
323 _math_horner_bezier_surf(map->Points, &tmp, u, v, 1,
324 map->Uorder, map->Vorder);
325
326 to[i] = (GLuint) (GLint) tmp;
327 }
328 }
329
330
331
332
333
334
335 static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count )
336 {
337 MEMCPY( to, from, count * sizeof(to[0]));
338 }
339
340 static void copy_4f_stride( GLfloat to[][4], GLfloat *from,
341 GLuint stride, GLuint count )
342 {
343 if (stride == 4 * sizeof(GLfloat))
344 MEMCPY( to, from, count * sizeof(to[0]));
345 else {
346 GLuint i;
347 /* fprintf(stderr, "%s stride %d count %d\n", __FUNCTION__, */
348 /* stride, count); */
349 for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
350 COPY_4FV( to[i], from );
351 }
352 }
353
354 static void copy_3f( GLfloat to[][4], GLfloat from[][4], GLuint count )
355 {
356 GLuint i;
357 /* MEMCPY( to, from, (count) * sizeof(to[0])); */
358 for (i = 0 ; i < count ; i++) {
359 /* fprintf(stderr, "copy norm %d from %p: %f %f %f\n", i, */
360 /* from[i], */
361 /* from[i][0], from[i][1], from[i][2]); */
362 COPY_3FV(to[i], from[i]);
363 }
364 }
365
366
367 static void copy_1ui( GLuint to[], GLuint from[], GLuint count )
368 {
369 MEMCPY( to, from, (count) * sizeof(to[0]));
370 }
371
372
373
374 /* Translate eval enabled flags to VERT_* flags.
375 */
376 static void update_eval( GLcontext *ctx )
377 {
378 TNLcontext *tnl = TNL_CONTEXT(ctx);
379 GLuint eval1 = 0, eval2 = 0;
380
381 if (ctx->Eval.Map1Index)
382 eval1 |= VERT_BIT_INDEX;
383
384 if (ctx->Eval.Map2Index)
385 eval2 |= VERT_BIT_INDEX;
386
387 if (ctx->Eval.Map1Color4)
388 eval1 |= VERT_BIT_COLOR0;
389
390 if (ctx->Eval.Map2Color4)
391 eval2 |= VERT_BIT_COLOR0;
392
393 if (ctx->Eval.Map1Normal)
394 eval1 |= VERT_BIT_NORMAL;
395
396 if (ctx->Eval.Map2Normal)
397 eval2 |= VERT_BIT_NORMAL;
398
399 if (ctx->Eval.Map1TextureCoord4 ||
400 ctx->Eval.Map1TextureCoord3 ||
401 ctx->Eval.Map1TextureCoord2 ||
402 ctx->Eval.Map1TextureCoord1)
403 eval1 |= VERT_BIT_TEX0;
404
405 if (ctx->Eval.Map2TextureCoord4 ||
406 ctx->Eval.Map2TextureCoord3 ||
407 ctx->Eval.Map2TextureCoord2 ||
408 ctx->Eval.Map2TextureCoord1)
409 eval2 |= VERT_BIT_TEX0;
410
411 if (ctx->Eval.Map1Vertex4)
412 eval1 |= VERT_BITS_OBJ_234;
413
414 if (ctx->Eval.Map1Vertex3)
415 eval1 |= VERT_BITS_OBJ_23;
416
417 if (ctx->Eval.Map2Vertex4) {
418 if (ctx->Eval.AutoNormal)
419 eval2 |= VERT_BITS_OBJ_234 | VERT_BIT_NORMAL;
420 else
421 eval2 |= VERT_BITS_OBJ_234;
422 }
423 else if (ctx->Eval.Map2Vertex3) {
424 if (ctx->Eval.AutoNormal)
425 eval2 |= VERT_BITS_OBJ_23 | VERT_BIT_NORMAL;
426 else
427 eval2 |= VERT_BITS_OBJ_23;
428 }
429
430 tnl->eval.EvalMap1Flags = eval1;
431 tnl->eval.EvalMap2Flags = eval2;
432 tnl->eval.EvalNewState = 0;
433 }
434
435
436 /* This looks a lot like a pipeline stage, but for various reasons is
437 * better handled outside the pipeline, and considered the final stage
438 * of fixing up an immediate struct for execution.
439 *
440 * Really want to cache the results of this function in display lists,
441 * at least for EvalMesh commands.
442 */
443 void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM )
444 {
445 TNLcontext *tnl = TNL_CONTEXT(ctx);
446 struct vertex_arrays *tmp = &tnl->imm_inputs;
447 struct immediate *store = tnl->eval.im;
448 GLuint *flags = IM->Flag + IM->CopyStart;
449 GLuint copycount;
450 GLuint orflag = IM->OrFlag;
451 GLuint any_eval1 = orflag & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1);
452 GLuint any_eval2 = orflag & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2);
453 GLuint req = 0;
454 GLuint purge_flags = 0;
455 GLfloat (*coord)[4] = IM->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
456
457 if (IM->AndFlag & VERT_BITS_EVAL_ANY)
458 copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */
459 else
460 copycount = IM->Count - IM->CopyStart; /* copy all vertices */
461
462 /* fprintf(stderr, "%s copystart %d start %d count %d copycount %d\n", */
463 /* __FUNCTION__, IM->CopyStart, IM->Start, IM->Count, copycount); */
464
465 if (!store)
466 store = tnl->eval.im = _tnl_alloc_immediate( ctx );
467
468 if (tnl->eval.EvalNewState & _NEW_EVAL)
469 update_eval( ctx );
470
471 if (any_eval1) {
472 req |= tnl->pipeline.inputs & tnl->eval.EvalMap1Flags;
473
474 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
475 purge_flags = (VERT_BIT_EVAL_P1|VERT_BIT_EVAL_C1);
476
477 if (orflag & VERT_BIT_EVAL_P1) {
478 eval_points1( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart,
479 coord, flags,
480 ctx->Eval.MapGrid1du,
481 ctx->Eval.MapGrid1u1);
482
483 coord = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
484 }
485 }
486
487 if (any_eval2) {
488 req |= tnl->pipeline.inputs & tnl->eval.EvalMap2Flags;
489
490 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
491 purge_flags |= (VERT_BIT_EVAL_P2|VERT_BIT_EVAL_C2);
492
493 if (orflag & VERT_BIT_EVAL_P2) {
494 eval_points2( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart,
495 coord, flags,
496 ctx->Eval.MapGrid2du,
497 ctx->Eval.MapGrid2u1,
498 ctx->Eval.MapGrid2dv,
499 ctx->Eval.MapGrid2v1 );
500
501 coord = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
502 }
503 }
504
505
506 /* _tnl_print_vert_flags(__FUNCTION__, req); */
507
508 /* Perform the evaluations on active data elements.
509 */
510 if (req & VERT_BIT_INDEX)
511 {
512 GLuint generated = 0;
513
514 if (copycount)
515 copy_1ui( store->Index + IM->CopyStart, tmp->Index.data, copycount );
516
517 tmp->Index.data = store->Index + IM->CopyStart;
518 tmp->Index.start = store->Index + IM->CopyStart;
519
520 if (ctx->Eval.Map1Index && any_eval1) {
521 eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index );
522 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
523 }
524
525 if (ctx->Eval.Map2Index && any_eval2) {
526 eval2_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map2Index );
527 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
528 }
529 }
530
531 if (req & VERT_BIT_COLOR0)
532 {
533 GLuint generated = 0;
534
535 if (copycount)
536 copy_4f_stride( store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart,
537 (GLfloat *)tmp->Color.Ptr,
538 tmp->Color.StrideB,
539 copycount );
540
541 tmp->Color.Ptr = store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart;
542 tmp->Color.StrideB = 4 * sizeof(GLfloat);
543 tmp->Color.Flags = 0;
544 tnl->vb.importable_data &= ~VERT_BIT_COLOR0;
545
546 if (ctx->Eval.Map1Color4 && any_eval1) {
547 eval1_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map1Color4 );
548 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
549 }
550
551 if (ctx->Eval.Map2Color4 && any_eval2) {
552 eval2_4f_ca( &tmp->Color, coord, flags, 4, &ctx->EvalMap.Map2Color4 );
553 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
554 }
555 }
556
557
558 if (req & VERT_BIT_TEX(0))
559 {
560 GLuint generated = 0;
561
562 if (copycount)
563 copy_4f( store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart,
564 tmp->TexCoord[0].data, copycount );
565 else
566 tmp->TexCoord[0].size = 0;
567
568 tmp->TexCoord[0].data = store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart;
569 tmp->TexCoord[0].start = (GLfloat *)tmp->TexCoord[0].data;
570
571 if (any_eval1) {
572 if (ctx->Eval.Map1TextureCoord4) {
573 eval1_4f( &tmp->TexCoord[0], coord, flags, 4,
574 &ctx->EvalMap.Map1Texture4 );
575 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
576 }
577 else if (ctx->Eval.Map1TextureCoord3) {
578 eval1_4f( &tmp->TexCoord[0], coord, flags, 3,
579 &ctx->EvalMap.Map1Texture3 );
580 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
581 }
582 else if (ctx->Eval.Map1TextureCoord2) {
583 eval1_4f( &tmp->TexCoord[0], coord, flags, 2,
584 &ctx->EvalMap.Map1Texture2 );
585 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
586 }
587 else if (ctx->Eval.Map1TextureCoord1) {
588 eval1_4f( &tmp->TexCoord[0], coord, flags, 1,
589 &ctx->EvalMap.Map1Texture1 );
590 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
591 }
592 }
593
594 if (any_eval2) {
595 if (ctx->Eval.Map2TextureCoord4) {
596 eval2_4f( &tmp->TexCoord[0], coord, flags, 4,
597 &ctx->EvalMap.Map2Texture4 );
598 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
599 }
600 else if (ctx->Eval.Map2TextureCoord3) {
601 eval2_4f( &tmp->TexCoord[0], coord, flags, 3,
602 &ctx->EvalMap.Map2Texture3 );
603 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
604 }
605 else if (ctx->Eval.Map2TextureCoord2) {
606 eval2_4f( &tmp->TexCoord[0], coord, flags, 2,
607 &ctx->EvalMap.Map2Texture2 );
608 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
609 }
610 else if (ctx->Eval.Map2TextureCoord1) {
611 eval2_4f( &tmp->TexCoord[0], coord, flags, 1,
612 &ctx->EvalMap.Map2Texture1 );
613 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
614 }
615 }
616 }
617
618
619 if (req & VERT_BIT_NORMAL)
620 {
621 GLuint generated = 0;
622
623 if (copycount) {
624 /* fprintf(stderr, "%s: Copy normals\n", __FUNCTION__); */
625 copy_3f( store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart,
626 tmp->Normal.data, copycount );
627 }
628
629 tmp->Normal.data = store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart;
630 tmp->Normal.start = (GLfloat *)tmp->Normal.data;
631
632 if (ctx->Eval.Map1Normal && any_eval1) {
633 eval1_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map1Normal );
634 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
635 }
636
637 if (ctx->Eval.Map2Normal && any_eval2) {
638 eval2_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map2Normal );
639 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
640 }
641 }
642
643
644
645 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
646 * are done above.
647 */
648 if (req & VERT_BIT_POS)
649 {
650 if (copycount) {
651 /* This copy may already have occurred when eliminating
652 * glEvalPoint calls:
653 */
654 if (coord != store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart) {
655 copy_4f( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart,
656 tmp->Obj.data, copycount );
657 }
658 }
659 else {
660 tmp->Obj.size = 0;
661 }
662
663 tmp->Obj.data = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
664 tmp->Obj.start = (GLfloat *)tmp->Obj.data;
665
666 /* Note: Normal data is already prepared above.
667 */
668
669 if (any_eval1) {
670 if (ctx->Eval.Map1Vertex4) {
671 eval1_4f( &tmp->Obj, coord, flags, 4,
672 &ctx->EvalMap.Map1Vertex4 );
673 }
674 else if (ctx->Eval.Map1Vertex3) {
675 eval1_4f( &tmp->Obj, coord, flags, 3,
676 &ctx->EvalMap.Map1Vertex3 );
677 }
678 }
679
680 if (any_eval2) {
681 if (ctx->Eval.Map2Vertex4) {
682 if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
683 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4,
684 &ctx->EvalMap.Map2Vertex4 );
685 else
686 eval2_4f( &tmp->Obj, coord, flags, 4,
687 &ctx->EvalMap.Map2Vertex4 );
688 }
689 else if (ctx->Eval.Map2Vertex3) {
690 if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
691 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 3,
692 &ctx->EvalMap.Map2Vertex3 );
693 else
694 eval2_4f( &tmp->Obj, coord, flags, 3,
695 &ctx->EvalMap.Map2Vertex3 );
696 }
697 }
698 }
699
700
701 /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
702 * the case where vertex maps are not enabled for some received
703 * eval coordinates. In this case those slots in the immediate
704 * must be ignored.
705 */
706 if (purge_flags) {
707 GLuint vertex = VERT_BIT_POS|(VERT_BITS_EVAL_ANY & ~purge_flags);
708 GLuint last_new_prim = 0;
709 GLuint new_prim_length = 0;
710 GLuint next_old_prim = 0;
711 struct vertex_buffer *VB = &tnl->vb;
712 GLuint i,j,count = VB->Count;
713
714 /* fprintf(stderr, "PURGING\n"); */
715
716 for (i = 0, j = 0 ; i < count ; i++) {
717 if (flags[i] & vertex) {
718 store->Elt[j++] = i;
719 new_prim_length++;
720 }
721 if (i == next_old_prim) {
722 next_old_prim += VB->PrimitiveLength[i];
723 VB->PrimitiveLength[last_new_prim] = new_prim_length;
724 VB->Primitive[j] = VB->Primitive[i];
725 last_new_prim = j;
726 }
727 }
728
729 VB->Elts = store->Elt;
730 _tnl_get_purged_copy_verts( ctx, store );
731 }
732
733 /* Produce new flags array:
734 */
735 {
736 GLuint i;
737 GLuint count = tnl->vb.Count + 1;
738
739 copy_1ui( store->Flag, flags, count );
740 tnl->vb.Flag = store->Flag;
741 for (i = 0 ; i < count ; i++)
742 store->Flag[i] |= req;
743 IM->Evaluated = req; /* hack for copying. */
744 }
745 }