e7ffdaaeae324bb90249633a309cd4b074699276
[mesa.git] / src / mesa / tnl / t_imm_eval.c
1 /* $Id: t_imm_eval.c,v 1.25 2002/06/25 02:56:45 brianp 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 * Authors:
27 * Keith Whitwell <keithw@valinux.com>
28 * Brian Paul - vertex program updates
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 const 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
116 /* as above, but dest is a gl_client_array */
117 static void eval1_4f_ca( struct gl_client_array *dest,
118 GLfloat coord[][4],
119 const GLuint *flags,
120 GLuint dimension,
121 const struct gl_1d_map *map )
122 {
123 const GLfloat u1 = map->u1;
124 const GLfloat du = map->du;
125 GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
126 GLuint i;
127
128 ASSERT(dest->Type == GL_FLOAT);
129 ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
130
131 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
132 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
133 GLfloat u = (coord[i][0] - u1) * du;
134 ASSIGN_4V(to[i], 0,0,0,1);
135 _math_horner_bezier_curve(map->Points, to[i], u,
136 dimension, map->Order);
137 }
138
139 dest->Size = MAX2(dest->Size, (GLint) dimension);
140 }
141
142
143 static void eval1_1ui( GLvector1ui *dest,
144 GLfloat coord[][4],
145 const GLuint *flags,
146 const struct gl_1d_map *map )
147 {
148 const GLfloat u1 = map->u1;
149 const GLfloat du = map->du;
150 GLuint *to = dest->data;
151 GLuint i;
152
153 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
154 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
155 GLfloat u = (coord[i][0] - u1) * du;
156 GLfloat tmp;
157 _math_horner_bezier_curve(map->Points, &tmp, u, 1, map->Order);
158 to[i] = (GLuint) (GLint) tmp;
159 }
160
161 }
162
163 static void eval1_norm( GLvector4f *dest,
164 GLfloat coord[][4],
165 const GLuint *flags,
166 const struct gl_1d_map *map )
167 {
168 const GLfloat u1 = map->u1;
169 const GLfloat du = map->du;
170 GLfloat (*to)[4] = dest->data;
171 GLuint i;
172
173 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
174 if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
175 GLfloat u = (coord[i][0] - u1) * du;
176 _math_horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
177 }
178 }
179
180
181 static void eval2_obj_norm( GLvector4f *obj_ptr,
182 GLvector4f *norm_ptr,
183 GLfloat coord[][4],
184 GLuint *flags,
185 GLuint dimension,
186 const struct gl_2d_map *map )
187 {
188 const GLfloat u1 = map->u1;
189 const GLfloat du = map->du;
190 const GLfloat v1 = map->v1;
191 const GLfloat dv = map->dv;
192 GLfloat (*obj)[4] = obj_ptr->data;
193 GLfloat (*normal)[4] = norm_ptr->data;
194 GLuint i;
195
196 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
197 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
198 GLfloat u = (coord[i][0] - u1) * du;
199 GLfloat v = (coord[i][1] - v1) * dv;
200 GLfloat du[4], dv[4];
201
202 ASSIGN_4V(obj[i], 0,0,0,1);
203 _math_de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension,
204 map->Uorder, map->Vorder);
205
206 if (dimension == 4) {
207 du[0] = du[0]*obj[i][3] - du[3]*obj[i][0];
208 du[1] = du[1]*obj[i][3] - du[3]*obj[i][1];
209 du[2] = du[2]*obj[i][3] - du[3]*obj[i][2];
210
211 dv[0] = dv[0]*obj[i][3] - dv[3]*obj[i][0];
212 dv[1] = dv[1]*obj[i][3] - dv[3]*obj[i][1];
213 dv[2] = dv[2]*obj[i][3] - dv[3]*obj[i][2];
214 }
215
216 CROSS3(normal[i], du, dv);
217 NORMALIZE_3FV(normal[i]);
218 }
219
220 obj_ptr->size = MAX2(obj_ptr->size, dimension);
221 obj_ptr->flags |= dirty_flags[dimension];
222 }
223
224
225 static void eval2_4f( GLvector4f *dest,
226 GLfloat coord[][4],
227 const GLuint *flags,
228 GLuint dimension,
229 const struct gl_2d_map *map )
230 {
231 const GLfloat u1 = map->u1;
232 const GLfloat du = map->du;
233 const GLfloat v1 = map->v1;
234 const GLfloat dv = map->dv;
235 GLfloat (*to)[4] = dest->data;
236 GLuint i;
237
238 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
239 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
240 GLfloat u = (coord[i][0] - u1) * du;
241 GLfloat v = (coord[i][1] - v1) * dv;
242
243 _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
244 map->Uorder, map->Vorder);
245 }
246
247 dest->size = MAX2(dest->size, dimension);
248 dest->flags |= dirty_flags[dimension];
249 }
250
251
252 /* as above, but dest is a gl_client_array */
253 static void eval2_4f_ca( struct gl_client_array *dest,
254 GLfloat coord[][4],
255 const GLuint *flags,
256 GLuint dimension,
257 const struct gl_2d_map *map )
258 {
259 const GLfloat u1 = map->u1;
260 const GLfloat du = map->du;
261 const GLfloat v1 = map->v1;
262 const GLfloat dv = map->dv;
263 GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
264 GLuint i;
265
266 ASSERT(dest->Type == GL_FLOAT);
267 ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
268
269 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
270 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
271 GLfloat u = (coord[i][0] - u1) * du;
272 GLfloat v = (coord[i][1] - v1) * dv;
273 _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
274 map->Uorder, map->Vorder);
275 }
276
277 dest->Size = MAX2(dest->Size, (GLint) dimension);
278 }
279
280
281 static void eval2_norm( GLvector4f *dest,
282 GLfloat coord[][4],
283 GLuint *flags,
284 const struct gl_2d_map *map )
285 {
286 const GLfloat u1 = map->u1;
287 const GLfloat du = map->du;
288 const GLfloat v1 = map->v1;
289 const GLfloat dv = map->dv;
290 GLfloat (*to)[4] = dest->data;
291 GLuint i;
292
293 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++) {
294 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
295 GLfloat u = (coord[i][0] - u1) * du;
296 GLfloat v = (coord[i][1] - v1) * dv;
297 _math_horner_bezier_surf(map->Points, to[i], u, v, 3,
298 map->Uorder, map->Vorder);
299 }
300 }
301 }
302
303
304 static void eval2_1ui( GLvector1ui *dest,
305 GLfloat coord[][4],
306 const GLuint *flags,
307 const struct gl_2d_map *map )
308 {
309 const GLfloat u1 = map->u1;
310 const GLfloat du = map->du;
311 const GLfloat v1 = map->v1;
312 const GLfloat dv = map->dv;
313 GLuint *to = dest->data;
314 GLuint i;
315
316 for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
317 if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
318 GLfloat u = (coord[i][0] - u1) * du;
319 GLfloat v = (coord[i][1] - v1) * dv;
320 GLfloat tmp;
321 _math_horner_bezier_surf(map->Points, &tmp, u, v, 1,
322 map->Uorder, map->Vorder);
323
324 to[i] = (GLuint) (GLint) tmp;
325 }
326 }
327
328
329 static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count )
330 {
331 MEMCPY( to, from, count * sizeof(to[0]));
332 }
333
334 static void copy_4f_stride( GLfloat to[][4], const GLfloat *from,
335 GLuint stride, GLuint count )
336 {
337 if (stride == 4 * sizeof(GLfloat))
338 MEMCPY( to, from, count * sizeof(to[0]));
339 else {
340 GLuint i;
341 for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
342 COPY_4FV( to[i], from );
343 }
344 }
345
346 static void copy_3f( GLfloat to[][4], GLfloat from[][4], GLuint count )
347 {
348 GLuint i;
349 for (i = 0 ; i < count ; i++) {
350 COPY_3FV(to[i], from[i]);
351 }
352 }
353
354
355 static void copy_1ui( GLuint to[], const GLuint from[], GLuint count )
356 {
357 MEMCPY( to, from, (count) * sizeof(to[0]));
358 }
359
360
361
362 /* Translate eval enabled flags to VERT_* flags.
363 */
364 static void update_eval( GLcontext *ctx )
365 {
366 TNLcontext *tnl = TNL_CONTEXT(ctx);
367 GLuint eval1 = 0, eval2 = 0;
368 GLuint i;
369
370 if (ctx->Eval.Map1Index)
371 eval1 |= VERT_BIT_INDEX;
372
373 if (ctx->Eval.Map2Index)
374 eval2 |= VERT_BIT_INDEX;
375
376 if (ctx->Eval.Map1Color4)
377 eval1 |= VERT_BIT_COLOR0;
378
379 if (ctx->Eval.Map2Color4)
380 eval2 |= VERT_BIT_COLOR0;
381
382 if (ctx->Eval.Map1Normal)
383 eval1 |= VERT_BIT_NORMAL;
384
385 if (ctx->Eval.Map2Normal)
386 eval2 |= VERT_BIT_NORMAL;
387
388 if (ctx->Eval.Map1TextureCoord4 ||
389 ctx->Eval.Map1TextureCoord3 ||
390 ctx->Eval.Map1TextureCoord2 ||
391 ctx->Eval.Map1TextureCoord1)
392 eval1 |= VERT_BIT_TEX0;
393
394 if (ctx->Eval.Map2TextureCoord4 ||
395 ctx->Eval.Map2TextureCoord3 ||
396 ctx->Eval.Map2TextureCoord2 ||
397 ctx->Eval.Map2TextureCoord1)
398 eval2 |= VERT_BIT_TEX0;
399
400 if (ctx->Eval.Map1Vertex4)
401 eval1 |= VERT_BITS_OBJ_234;
402
403 if (ctx->Eval.Map1Vertex3)
404 eval1 |= VERT_BITS_OBJ_23;
405
406 if (ctx->Eval.Map2Vertex4) {
407 if (ctx->Eval.AutoNormal)
408 eval2 |= VERT_BITS_OBJ_234 | VERT_BIT_NORMAL;
409 else
410 eval2 |= VERT_BITS_OBJ_234;
411 }
412 else if (ctx->Eval.Map2Vertex3) {
413 if (ctx->Eval.AutoNormal)
414 eval2 |= VERT_BITS_OBJ_23 | VERT_BIT_NORMAL;
415 else
416 eval2 |= VERT_BITS_OBJ_23;
417 }
418
419 tnl->eval.EvalMap1Flags = eval1;
420 tnl->eval.EvalMap2Flags = eval2;
421
422 /* GL_NV_vertex_program evaluators */
423 eval1 = eval2 = 0;
424 for (i = 0; i < VERT_ATTRIB_MAX; i++) {
425 if (ctx->Eval.Map1Attrib[i])
426 eval1 |= (1 << i);
427 if (ctx->Eval.Map2Attrib[i])
428 eval2 |= (1 << i);
429 }
430 tnl->eval.EvalMap1AttribFlags = eval1;
431 tnl->eval.EvalMap2AttribFlags = eval2;
432
433 tnl->eval.EvalNewState = 0;
434 }
435
436
437 /* This looks a lot like a pipeline stage, but for various reasons is
438 * better handled outside the pipeline, and considered the final stage
439 * of fixing up an immediate struct for execution.
440 *
441 * Really want to cache the results of this function in display lists,
442 * at least for EvalMesh commands.
443 */
444 void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM )
445 {
446 TNLcontext *tnl = TNL_CONTEXT(ctx);
447 struct vertex_arrays *tmp = &tnl->imm_inputs;
448 struct immediate *store = tnl->eval.im;
449 GLuint *flags = IM->Flag + IM->CopyStart;
450 GLuint copycount;
451 GLuint orflag = IM->OrFlag;
452 GLuint any_eval1 = orflag & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1);
453 GLuint any_eval2 = orflag & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2);
454 GLuint req = 0;
455 GLuint purge_flags = 0;
456 GLfloat (*coord)[4] = IM->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
457
458 if (IM->AndFlag & VERT_BITS_EVAL_ANY)
459 copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */
460 else
461 copycount = IM->Count - IM->CopyStart; /* copy all vertices */
462
463 if (!store)
464 store = tnl->eval.im = _tnl_alloc_immediate( ctx );
465
466 if (tnl->eval.EvalNewState & _NEW_EVAL)
467 update_eval( ctx );
468
469 if (any_eval1) {
470 req |= tnl->pipeline.inputs
471 & (tnl->eval.EvalMap1Flags | tnl->eval.EvalMap1AttribFlags);
472
473 if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3 &&
474 !ctx->Eval.Map1Attrib[0])
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
489 & (tnl->eval.EvalMap2Flags | tnl->eval.EvalMap2AttribFlags);
490
491 if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3 &&
492 !ctx->Eval.Map2Attrib[0])
493 purge_flags |= (VERT_BIT_EVAL_P2|VERT_BIT_EVAL_C2);
494
495 if (orflag & VERT_BIT_EVAL_P2) {
496 eval_points2( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart,
497 coord, flags,
498 ctx->Eval.MapGrid2du,
499 ctx->Eval.MapGrid2u1,
500 ctx->Eval.MapGrid2dv,
501 ctx->Eval.MapGrid2v1 );
502
503 coord = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
504 }
505 }
506
507 /* Perform the evaluations on active data elements.
508 */
509 if (req & VERT_BIT_INDEX) {
510 GLuint generated = 0;
511
512 if (copycount)
513 copy_1ui( store->Index + IM->CopyStart, tmp->Index.data, copycount );
514
515 tmp->Index.data = store->Index + IM->CopyStart;
516 tmp->Index.start = store->Index + IM->CopyStart;
517
518 if (ctx->Eval.Map1Index && any_eval1) {
519 eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index );
520 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
521 }
522
523 if (ctx->Eval.Map2Index && any_eval2) {
524 eval2_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map2Index );
525 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
526 }
527 }
528
529 if (req & VERT_BIT_COLOR0) {
530 GLuint generated = 0;
531
532 if (copycount)
533 copy_4f_stride( store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart,
534 (GLfloat *)tmp->Color.Ptr,
535 tmp->Color.StrideB,
536 copycount );
537
538 tmp->Color.Ptr = store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart;
539 tmp->Color.StrideB = 4 * sizeof(GLfloat);
540 tmp->Color.Flags = 0;
541 tnl->vb.importable_data &= ~VERT_BIT_COLOR0;
542
543 if (ctx->VertexProgram.Enabled) {
544 tmp->Attribs[VERT_ATTRIB_COLOR0].data =
545 store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart;
546 tmp->Attribs[VERT_ATTRIB_COLOR0].start =
547 (GLfloat *) tmp->Attribs[VERT_ATTRIB_COLOR0].data;
548 tmp->Attribs[VERT_ATTRIB_COLOR0].size = 0;
549 }
550
551 /* Vertex program maps have priority over conventional attribs */
552 if (any_eval1) {
553 if (ctx->VertexProgram.Enabled
554 && ctx->Eval.Map1Attrib[VERT_ATTRIB_COLOR0]) {
555 eval1_4f_ca( &tmp->Color, coord, flags, 4,
556 &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_COLOR0] );
557 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
558 }
559 else if (ctx->Eval.Map1Color4) {
560 eval1_4f_ca( &tmp->Color, coord, flags, 4,
561 &ctx->EvalMap.Map1Color4 );
562 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
563 }
564 }
565
566 if (any_eval2) {
567 if (ctx->VertexProgram.Enabled
568 && ctx->Eval.Map2Attrib[VERT_ATTRIB_COLOR0]) {
569 eval2_4f_ca( &tmp->Color, coord, flags, 4,
570 &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_COLOR0] );
571 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
572 }
573 else if (ctx->Eval.Map2Color4) {
574 eval2_4f_ca( &tmp->Color, coord, flags, 4,
575 &ctx->EvalMap.Map2Color4 );
576 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
577 }
578 }
579 }
580
581 if (req & VERT_BIT_TEX0) {
582 GLuint generated = 0;
583
584 if (copycount)
585 copy_4f( store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart,
586 tmp->TexCoord[0].data, copycount );
587 else
588 tmp->TexCoord[0].size = 0;
589
590 tmp->TexCoord[0].data = store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart;
591 tmp->TexCoord[0].start = (GLfloat *)tmp->TexCoord[0].data;
592
593 if (ctx->VertexProgram.Enabled) {
594 tmp->Attribs[VERT_ATTRIB_TEX0].data =
595 store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart;
596 tmp->Attribs[VERT_ATTRIB_TEX0].start =
597 (GLfloat *) tmp->Attribs[VERT_ATTRIB_TEX0].data;
598 tmp->Attribs[VERT_ATTRIB_TEX0].size = 0;
599 }
600
601 /* Vertex program maps have priority over conventional attribs */
602 if (any_eval1) {
603 if (ctx->VertexProgram.Enabled
604 && ctx->Eval.Map1Attrib[VERT_ATTRIB_TEX0]) {
605 eval1_4f( &tmp->TexCoord[0], coord, flags, 4,
606 &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_TEX0] );
607 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
608 }
609 else if (ctx->Eval.Map1TextureCoord4) {
610 eval1_4f( &tmp->TexCoord[0], coord, flags, 4,
611 &ctx->EvalMap.Map1Texture4 );
612 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
613 }
614 else if (ctx->Eval.Map1TextureCoord3) {
615 eval1_4f( &tmp->TexCoord[0], coord, flags, 3,
616 &ctx->EvalMap.Map1Texture3 );
617 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
618 }
619 else if (ctx->Eval.Map1TextureCoord2) {
620 eval1_4f( &tmp->TexCoord[0], coord, flags, 2,
621 &ctx->EvalMap.Map1Texture2 );
622 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
623 }
624 else if (ctx->Eval.Map1TextureCoord1) {
625 eval1_4f( &tmp->TexCoord[0], coord, flags, 1,
626 &ctx->EvalMap.Map1Texture1 );
627 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
628 }
629 }
630
631 if (any_eval2) {
632 if (ctx->VertexProgram.Enabled
633 && ctx->Eval.Map2Attrib[VERT_ATTRIB_TEX0]) {
634 eval2_4f( &tmp->TexCoord[0], coord, flags, 4,
635 &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_TEX0] );
636 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
637 }
638 else if (ctx->Eval.Map2TextureCoord4) {
639 eval2_4f( &tmp->TexCoord[0], coord, flags, 4,
640 &ctx->EvalMap.Map2Texture4 );
641 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
642 }
643 else if (ctx->Eval.Map2TextureCoord3) {
644 eval2_4f( &tmp->TexCoord[0], coord, flags, 3,
645 &ctx->EvalMap.Map2Texture3 );
646 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
647 }
648 else if (ctx->Eval.Map2TextureCoord2) {
649 eval2_4f( &tmp->TexCoord[0], coord, flags, 2,
650 &ctx->EvalMap.Map2Texture2 );
651 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
652 }
653 else if (ctx->Eval.Map2TextureCoord1) {
654 eval2_4f( &tmp->TexCoord[0], coord, flags, 1,
655 &ctx->EvalMap.Map2Texture1 );
656 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
657 }
658 }
659 }
660
661 if (req & VERT_BIT_NORMAL) {
662 GLuint generated = 0;
663
664 if (copycount) {
665 copy_3f( store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart,
666 tmp->Normal.data, copycount );
667 }
668
669 tmp->Normal.data = store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart;
670 tmp->Normal.start = (GLfloat *)tmp->Normal.data;
671
672 if (ctx->VertexProgram.Enabled) {
673 tmp->Attribs[VERT_ATTRIB_NORMAL].data =
674 store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart;
675 tmp->Attribs[VERT_ATTRIB_NORMAL].start =
676 (GLfloat *) tmp->Attribs[VERT_ATTRIB_NORMAL].data;
677 tmp->Attribs[VERT_ATTRIB_NORMAL].size = 0;
678 }
679
680 if (any_eval1) {
681 if (ctx->VertexProgram.Enabled &&
682 ctx->Eval.Map1Attrib[VERT_ATTRIB_NORMAL]) {
683 eval1_norm( &tmp->Normal, coord, flags,
684 &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_NORMAL] );
685 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
686 }
687 else if (ctx->Eval.Map1Normal) {
688 eval1_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map1Normal );
689 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
690 }
691 }
692
693 if (any_eval2) {
694 if (ctx->VertexProgram.Enabled &&
695 ctx->Eval.Map2Attrib[VERT_ATTRIB_NORMAL]) {
696 eval2_norm( &tmp->Normal, coord, flags,
697 &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_NORMAL] );
698 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
699 }
700 else if (ctx->Eval.Map2Normal) {
701 eval2_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map2Normal );
702 generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
703 }
704 }
705 }
706
707 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
708 * are done above.
709 */
710 if (req & VERT_BIT_POS) {
711 if (copycount) {
712 /* This copy may already have occurred when eliminating
713 * glEvalPoint calls:
714 */
715 if (coord != store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart) {
716 copy_4f( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart,
717 tmp->Obj.data, copycount );
718 }
719 }
720 else {
721 tmp->Obj.size = 0;
722 }
723
724 tmp->Obj.data = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
725 tmp->Obj.start = (GLfloat *) tmp->Obj.data;
726
727 #if 1
728 /*tmp->Attribs[0].count = count;*/
729 tmp->Attribs[0].data = store->Attrib[0] + IM->CopyStart;
730 tmp->Attribs[0].start = (GLfloat *) tmp->Attribs[0].data;
731 tmp->Attribs[0].size = 0;
732 #endif
733
734 /* Note: Normal data is already prepared above.
735 */
736
737 if (any_eval1) {
738 if (ctx->VertexProgram.Enabled &&
739 ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]) {
740 eval1_4f( &tmp->Obj, coord, flags, 4,
741 &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_POS] );
742 }
743 else if (ctx->Eval.Map1Vertex4) {
744 eval1_4f( &tmp->Obj, coord, flags, 4,
745 &ctx->EvalMap.Map1Vertex4 );
746 }
747 else if (ctx->Eval.Map1Vertex3) {
748 eval1_4f( &tmp->Obj, coord, flags, 3,
749 &ctx->EvalMap.Map1Vertex3 );
750 }
751 }
752
753 if (any_eval2) {
754 if (ctx->VertexProgram.Enabled &&
755 ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]) {
756 if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
757 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4,
758 &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_POS] );
759 else
760 eval2_4f( &tmp->Obj, coord, flags, 4,
761 &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_POS] );
762 }
763 else if (ctx->Eval.Map2Vertex4) {
764 if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
765 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4,
766 &ctx->EvalMap.Map2Vertex4 );
767 else
768 eval2_4f( &tmp->Obj, coord, flags, 4,
769 &ctx->EvalMap.Map2Vertex4 );
770 }
771 else if (ctx->Eval.Map2Vertex3) {
772 if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
773 eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 3,
774 &ctx->EvalMap.Map2Vertex3 );
775 else
776 eval2_4f( &tmp->Obj, coord, flags, 3,
777 &ctx->EvalMap.Map2Vertex3 );
778 }
779 }
780 }
781
782
783 if (ctx->VertexProgram.Enabled) {
784 /* We already evaluated position, normal, color and texture 0 above.
785 * now evaluate any other generic attributes.
786 */
787 const GLuint skipBits = (VERT_BIT_POS |
788 VERT_BIT_NORMAL |
789 VERT_BIT_COLOR0 |
790 VERT_BIT_TEX0);
791 GLuint generated = 0;
792 GLuint attr;
793 for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
794 if ((1 << attr) & req & ~skipBits) {
795 if (any_eval1 && ctx->Eval.Map1Attrib[attr]) {
796 /* evaluate 1-D vertex attrib map [i] */
797 eval1_4f( &tmp->Attribs[attr], coord, flags, 4,
798 &ctx->EvalMap.Map1Attrib[attr] );
799 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
800 }
801 if (any_eval2 && ctx->Eval.Map2Attrib[attr]) {
802 /* evaluate 2-D vertex attrib map [i] */
803 eval2_4f( &tmp->Attribs[attr], coord, flags, 4,
804 &ctx->EvalMap.Map2Attrib[attr] );
805 generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
806 }
807 }
808 }
809 }
810
811 /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
812 * the case where vertex maps are not enabled for some received
813 * eval coordinates. In this case those slots in the immediate
814 * must be ignored.
815 */
816 if (purge_flags) {
817 const GLuint vertex = VERT_BIT_POS|(VERT_BITS_EVAL_ANY & ~purge_flags);
818 GLuint last_new_prim = 0;
819 GLuint new_prim_length = 0;
820 GLuint next_old_prim = 0;
821 struct vertex_buffer *VB = &tnl->vb;
822 const GLuint count = VB->Count;
823 GLuint i, j;
824
825 for (i = 0, j = 0 ; i < count ; i++) {
826 if (flags[i] & vertex) {
827 store->Elt[j++] = i;
828 new_prim_length++;
829 }
830 if (i == next_old_prim) {
831 next_old_prim += VB->PrimitiveLength[i];
832 VB->PrimitiveLength[last_new_prim] = new_prim_length;
833 VB->Primitive[j] = VB->Primitive[i];
834 last_new_prim = j;
835 }
836 }
837
838 VB->Elts = store->Elt;
839 _tnl_get_purged_copy_verts( ctx, store );
840 }
841
842 /* Produce new flags array:
843 */
844 {
845 const GLuint count = tnl->vb.Count + 1;
846 GLuint i;
847
848 copy_1ui( store->Flag, flags, count );
849 tnl->vb.Flag = store->Flag;
850 for (i = 0 ; i < count ; i++)
851 store->Flag[i] |= req;
852 IM->Evaluated = req; /* hack for copying. */
853 }
854 }