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_eval.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
 * Authors:
27
 *    Keith Whitwell <keith@tungstengraphics.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 "imports.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
}