1 /* $Id: t_imm_eval.c,v 1.27 2002/10/29 20:29:02 brianp 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.
27 * Keith Whitwell <keith@tungstengraphics.com>
28 * Brian Paul - vertex program updates
39 #include "math/m_eval.h"
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"
49 static void eval_points1( GLfloat outcoord
[][4],
52 GLfloat du
, GLfloat u1
)
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
;
64 static void eval_points2( GLfloat outcoord
[][4],
67 GLfloat du
, GLfloat u1
,
68 GLfloat dv
, GLfloat v1
)
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
;
83 static const GLubyte dirty_flags
[5] = {
92 static void eval1_4f( GLvector4f
*dest
,
96 const struct gl_1d_map
*map
)
98 const GLfloat u1
= map
->u1
;
99 const GLfloat du
= map
->du
;
100 GLfloat (*to
)[4] = dest
->data
;
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
);
111 dest
->size
= MAX2(dest
->size
, dimension
);
112 dest
->flags
|= dirty_flags
[dimension
];
116 /* as above, but dest is a gl_client_array */
117 static void eval1_4f_ca( struct gl_client_array
*dest
,
121 const struct gl_1d_map
*map
)
123 const GLfloat u1
= map
->u1
;
124 const GLfloat du
= map
->du
;
125 GLfloat (*to
)[4] = (GLfloat (*)[4])dest
->Ptr
;
128 ASSERT(dest
->Type
== GL_FLOAT
);
129 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
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
);
139 dest
->Size
= MAX2(dest
->Size
, (GLint
) dimension
);
143 static void eval1_1ui( GLvector1ui
*dest
,
146 const struct gl_1d_map
*map
)
148 const GLfloat u1
= map
->u1
;
149 const GLfloat du
= map
->du
;
150 GLuint
*to
= dest
->data
;
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
;
157 _math_horner_bezier_curve(map
->Points
, &tmp
, u
, 1, map
->Order
);
158 to
[i
] = (GLuint
) (GLint
) tmp
;
163 static void eval1_norm( GLvector4f
*dest
,
166 const struct gl_1d_map
*map
)
168 const GLfloat u1
= map
->u1
;
169 const GLfloat du
= map
->du
;
170 GLfloat (*to
)[4] = dest
->data
;
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
);
181 static void eval2_obj_norm( GLvector4f
*obj_ptr
,
182 GLvector4f
*norm_ptr
,
186 const struct gl_2d_map
*map
)
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
;
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];
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
);
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];
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];
216 CROSS3(normal
[i
], du
, dv
);
217 NORMALIZE_3FV(normal
[i
]);
220 obj_ptr
->size
= MAX2(obj_ptr
->size
, dimension
);
221 obj_ptr
->flags
|= dirty_flags
[dimension
];
225 static void eval2_4f( GLvector4f
*dest
,
229 const struct gl_2d_map
*map
)
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
;
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
;
243 _math_horner_bezier_surf(map
->Points
, to
[i
], u
, v
, dimension
,
244 map
->Uorder
, map
->Vorder
);
247 dest
->size
= MAX2(dest
->size
, dimension
);
248 dest
->flags
|= dirty_flags
[dimension
];
252 /* as above, but dest is a gl_client_array */
253 static void eval2_4f_ca( struct gl_client_array
*dest
,
257 const struct gl_2d_map
*map
)
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
;
266 ASSERT(dest
->Type
== GL_FLOAT
);
267 ASSERT(dest
->StrideB
== 4 * sizeof(GLfloat
));
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
);
277 dest
->Size
= MAX2(dest
->Size
, (GLint
) dimension
);
281 static void eval2_norm( GLvector4f
*dest
,
284 const struct gl_2d_map
*map
)
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
;
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
);
304 static void eval2_1ui( GLvector1ui
*dest
,
307 const struct gl_2d_map
*map
)
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
;
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
;
321 _math_horner_bezier_surf(map
->Points
, &tmp
, u
, v
, 1,
322 map
->Uorder
, map
->Vorder
);
324 to
[i
] = (GLuint
) (GLint
) tmp
;
329 static void copy_4f( GLfloat to
[][4], GLfloat from
[][4], GLuint count
)
331 MEMCPY( to
, from
, count
* sizeof(to
[0]));
334 static void copy_4f_stride( GLfloat to
[][4], const GLfloat
*from
,
335 GLuint stride
, GLuint count
)
337 if (stride
== 4 * sizeof(GLfloat
))
338 MEMCPY( to
, from
, count
* sizeof(to
[0]));
341 for (i
= 0 ; i
< count
; i
++, STRIDE_F(from
, stride
))
342 COPY_4FV( to
[i
], from
);
346 static void copy_3f( GLfloat to
[][4], GLfloat from
[][4], GLuint count
)
349 for (i
= 0 ; i
< count
; i
++) {
350 COPY_3FV(to
[i
], from
[i
]);
355 static void copy_1ui( GLuint to
[], const GLuint from
[], GLuint count
)
357 MEMCPY( to
, from
, (count
) * sizeof(to
[0]));
362 /* Translate eval enabled flags to VERT_* flags.
364 static void update_eval( GLcontext
*ctx
)
366 TNLcontext
*tnl
= TNL_CONTEXT(ctx
);
367 GLuint eval1
= 0, eval2
= 0;
370 if (ctx
->Eval
.Map1Index
)
371 eval1
|= VERT_BIT_INDEX
;
373 if (ctx
->Eval
.Map2Index
)
374 eval2
|= VERT_BIT_INDEX
;
376 if (ctx
->Eval
.Map1Color4
)
377 eval1
|= VERT_BIT_COLOR0
;
379 if (ctx
->Eval
.Map2Color4
)
380 eval2
|= VERT_BIT_COLOR0
;
382 if (ctx
->Eval
.Map1Normal
)
383 eval1
|= VERT_BIT_NORMAL
;
385 if (ctx
->Eval
.Map2Normal
)
386 eval2
|= VERT_BIT_NORMAL
;
388 if (ctx
->Eval
.Map1TextureCoord4
||
389 ctx
->Eval
.Map1TextureCoord3
||
390 ctx
->Eval
.Map1TextureCoord2
||
391 ctx
->Eval
.Map1TextureCoord1
)
392 eval1
|= VERT_BIT_TEX0
;
394 if (ctx
->Eval
.Map2TextureCoord4
||
395 ctx
->Eval
.Map2TextureCoord3
||
396 ctx
->Eval
.Map2TextureCoord2
||
397 ctx
->Eval
.Map2TextureCoord1
)
398 eval2
|= VERT_BIT_TEX0
;
400 if (ctx
->Eval
.Map1Vertex4
)
401 eval1
|= VERT_BITS_OBJ_234
;
403 if (ctx
->Eval
.Map1Vertex3
)
404 eval1
|= VERT_BITS_OBJ_23
;
406 if (ctx
->Eval
.Map2Vertex4
) {
407 if (ctx
->Eval
.AutoNormal
)
408 eval2
|= VERT_BITS_OBJ_234
| VERT_BIT_NORMAL
;
410 eval2
|= VERT_BITS_OBJ_234
;
412 else if (ctx
->Eval
.Map2Vertex3
) {
413 if (ctx
->Eval
.AutoNormal
)
414 eval2
|= VERT_BITS_OBJ_23
| VERT_BIT_NORMAL
;
416 eval2
|= VERT_BITS_OBJ_23
;
419 tnl
->eval
.EvalMap1Flags
= eval1
;
420 tnl
->eval
.EvalMap2Flags
= eval2
;
422 /* GL_NV_vertex_program evaluators */
424 for (i
= 0; i
< VERT_ATTRIB_MAX
; i
++) {
425 if (ctx
->Eval
.Map1Attrib
[i
])
427 if (ctx
->Eval
.Map2Attrib
[i
])
430 tnl
->eval
.EvalMap1AttribFlags
= eval1
;
431 tnl
->eval
.EvalMap2AttribFlags
= eval2
;
433 tnl
->eval
.EvalNewState
= 0;
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.
441 * Really want to cache the results of this function in display lists,
442 * at least for EvalMesh commands.
444 void _tnl_eval_immediate( GLcontext
*ctx
, struct immediate
*IM
)
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
;
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
);
455 GLuint purge_flags
= 0;
456 GLfloat (*coord
)[4] = IM
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
458 if (IM
->AndFlag
& VERT_BITS_EVAL_ANY
)
459 copycount
= IM
->Start
- IM
->CopyStart
; /* just copy copied vertices */
461 copycount
= IM
->Count
- IM
->CopyStart
; /* copy all vertices */
464 store
= tnl
->eval
.im
= _tnl_alloc_immediate( ctx
);
466 if (tnl
->eval
.EvalNewState
& _NEW_EVAL
)
470 req
|= tnl
->pipeline
.inputs
471 & (tnl
->eval
.EvalMap1Flags
| tnl
->eval
.EvalMap1AttribFlags
);
473 if (!ctx
->Eval
.Map1Vertex4
&& !ctx
->Eval
.Map1Vertex3
&&
474 !ctx
->Eval
.Map1Attrib
[0])
475 purge_flags
= (VERT_BIT_EVAL_P1
|VERT_BIT_EVAL_C1
);
477 if (orflag
& VERT_BIT_EVAL_P1
) {
478 eval_points1( store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
,
480 ctx
->Eval
.MapGrid1du
,
481 ctx
->Eval
.MapGrid1u1
);
483 coord
= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
488 req
|= tnl
->pipeline
.inputs
489 & (tnl
->eval
.EvalMap2Flags
| tnl
->eval
.EvalMap2AttribFlags
);
491 if (!ctx
->Eval
.Map2Vertex4
&& !ctx
->Eval
.Map2Vertex3
&&
492 !ctx
->Eval
.Map2Attrib
[0])
493 purge_flags
|= (VERT_BIT_EVAL_P2
|VERT_BIT_EVAL_C2
);
495 if (orflag
& VERT_BIT_EVAL_P2
) {
496 eval_points2( store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
,
498 ctx
->Eval
.MapGrid2du
,
499 ctx
->Eval
.MapGrid2u1
,
500 ctx
->Eval
.MapGrid2dv
,
501 ctx
->Eval
.MapGrid2v1
);
503 coord
= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
507 /* Perform the evaluations on active data elements.
509 if (req
& VERT_BIT_INDEX
) {
510 GLuint generated
= 0;
513 copy_1ui( store
->Index
+ IM
->CopyStart
, tmp
->Index
.data
, copycount
);
515 tmp
->Index
.data
= store
->Index
+ IM
->CopyStart
;
516 tmp
->Index
.start
= store
->Index
+ IM
->CopyStart
;
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
;
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
;
529 if (req
& VERT_BIT_COLOR0
) {
530 GLuint generated
= 0;
533 copy_4f_stride( store
->Attrib
[VERT_ATTRIB_COLOR0
] + IM
->CopyStart
,
534 (GLfloat
*)tmp
->Color
.Ptr
,
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
;
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;
551 /* Vertex program maps have priority over conventional attribs */
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
;
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
;
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
;
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
;
581 if (req
& VERT_BIT_TEX0
) {
582 GLuint generated
= 0;
585 copy_4f( store
->Attrib
[VERT_ATTRIB_TEX0
] + IM
->CopyStart
,
586 tmp
->TexCoord
[0].data
, copycount
);
588 tmp
->TexCoord
[0].size
= 0;
590 tmp
->TexCoord
[0].data
= store
->Attrib
[VERT_ATTRIB_TEX0
] + IM
->CopyStart
;
591 tmp
->TexCoord
[0].start
= (GLfloat
*)tmp
->TexCoord
[0].data
;
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;
601 /* Vertex program maps have priority over conventional attribs */
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
661 if (req
& VERT_BIT_NORMAL
) {
662 GLuint generated
= 0;
665 copy_3f( store
->Attrib
[VERT_ATTRIB_NORMAL
] + IM
->CopyStart
,
666 tmp
->Normal
.data
, copycount
);
669 tmp
->Normal
.data
= store
->Attrib
[VERT_ATTRIB_NORMAL
] + IM
->CopyStart
;
670 tmp
->Normal
.start
= (GLfloat
*)tmp
->Normal
.data
;
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;
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
;
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
;
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
;
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
;
707 /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
710 if (req
& VERT_BIT_POS
) {
712 /* This copy may already have occurred when eliminating
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
);
724 tmp
->Obj
.data
= store
->Attrib
[VERT_ATTRIB_POS
] + IM
->CopyStart
;
725 tmp
->Obj
.start
= (GLfloat
*) tmp
->Obj
.data
;
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;
734 /* Note: Normal data is already prepared above.
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
] );
743 else if (ctx
->Eval
.Map1Vertex4
) {
744 eval1_4f( &tmp
->Obj
, coord
, flags
, 4,
745 &ctx
->EvalMap
.Map1Vertex4
);
747 else if (ctx
->Eval
.Map1Vertex3
) {
748 eval1_4f( &tmp
->Obj
, coord
, flags
, 3,
749 &ctx
->EvalMap
.Map1Vertex3
);
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
] );
760 eval2_4f( &tmp
->Obj
, coord
, flags
, 4,
761 &ctx
->EvalMap
.Map2Attrib
[VERT_ATTRIB_POS
] );
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
);
768 eval2_4f( &tmp
->Obj
, coord
, flags
, 4,
769 &ctx
->EvalMap
.Map2Vertex4
);
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
);
776 eval2_4f( &tmp
->Obj
, coord
, flags
, 3,
777 &ctx
->EvalMap
.Map2Vertex3
);
783 if (ctx
->VertexProgram
.Enabled
) {
784 /* We already evaluated position, normal, color and texture 0 above.
785 * now evaluate any other generic attributes.
787 const GLuint skipBits
= (VERT_BIT_POS
|
791 GLuint generated
= 0;
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
;
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
;
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
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
;
825 for (i
= 0, j
= 0 ; i
< count
; i
++) {
826 if (flags
[i
] & vertex
) {
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
];
838 VB
->Elts
= store
->Elt
;
839 _tnl_get_purged_copy_verts( ctx
, store
);
842 /* Produce new flags array:
845 const GLuint count
= tnl
->vb
.Count
+ 1;
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. */