Details | 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 | } |