Initial work for bounds checking of vertex arrays and vertex buffer objects.
[mesa.git] / src / mesa / tnl / t_imm_elt.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Keith Whitwell <keith@tungstengraphics.com>
26 */
27
28 #include "glheader.h"
29 #include "colormac.h"
30 #include "context.h"
31 #include "imports.h"
32 #include "mtypes.h"
33
34 #include "math/m_translate.h"
35
36 #include "t_context.h"
37 #include "t_imm_elt.h"
38
39
40
41 typedef void (*trans_elt_1ui_func)(GLuint *to,
42 CONST void *ptr,
43 GLuint stride,
44 const GLuint *flags,
45 const GLuint *elts,
46 GLuint match,
47 GLuint start,
48 GLuint n );
49
50 typedef void (*trans_elt_1ub_func)(GLubyte *to,
51 CONST void *ptr,
52 GLuint stride,
53 const GLuint *flags,
54 const GLuint *elts,
55 GLuint match,
56 GLuint start,
57 GLuint n );
58
59 typedef void (*trans_elt_4f_func)(GLfloat (*to)[4],
60 CONST void *ptr,
61 GLuint stride,
62 const GLuint *flags,
63 const GLuint *elts,
64 GLuint match,
65 GLuint start,
66 GLuint n );
67
68
69
70 static trans_elt_1ui_func _tnl_trans_elt_1ui_tab[MAX_TYPES];
71 static trans_elt_1ub_func _tnl_trans_elt_1ub_tab[MAX_TYPES];
72 static trans_elt_4f_func _tnl_trans_elt_4f_tab[5][MAX_TYPES];
73 static trans_elt_4f_func _tnl_trans_elt_4fc_tab[5][MAX_TYPES];
74
75
76 #define PTR_ELT(ptr, elt) (((SRC *)ptr)[elt])
77
78
79
80 /* Code specific to array element implementation. There is a small
81 * subtlety in the bits CHECK() tests, and the way bits are set in
82 * glArrayElement which ensures that if, eg, in the case that the
83 * vertex array is disabled and normal array is enabled, and we get
84 * either sequence:
85 *
86 * ArrayElement() OR Normal()
87 * Normal() ArrayElement()
88 * Vertex() Vertex()
89 *
90 * That the correct value for normal is used.
91 */
92 #define TAB(x) _tnl_trans_elt##x##_tab
93 #define ARGS const GLuint *flags, const GLuint *elts, GLuint match, \
94 GLuint start, GLuint n
95 #define SRC_START 0
96 #define DST_START start
97 #define CHECK if ((flags[i]&match) == VERT_BIT_ELT)
98 #define NEXT_F (void)1
99 #define NEXT_F2 f = first + elts[i] * stride;
100
101
102 /* GL_BYTE
103 */
104 #define SRC GLbyte
105 #define SRC_IDX TYPE_IDX(GL_BYTE)
106 #define TRX_4F(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) )
107 #define TRX_4FC(f,n) BYTE_TO_FLOAT( PTR_ELT(f,n) )
108 #define TRX_UB(ub, f,n) ub = BYTE_TO_UBYTE( PTR_ELT(f,n) )
109 #define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n))
110
111
112 #define SZ 4
113 #define INIT init_trans_4_GLbyte_elt
114 #define DEST_4F trans_4_GLbyte_4f_elt
115 #define DEST_4FC trans_4_GLbyte_4fc_elt
116 #include "math/m_trans_tmp.h"
117
118 #define SZ 3
119 #define INIT init_trans_3_GLbyte_elt
120 #define DEST_4F trans_3_GLbyte_4f_elt
121 #define DEST_4FC trans_3_GLbyte_4fc_elt
122 #include "math/m_trans_tmp.h"
123
124 #define SZ 2
125 #define INIT init_trans_2_GLbyte_elt
126 #define DEST_4F trans_2_GLbyte_4f_elt
127 #define DEST_4FC trans_2_GLbyte_4fc_elt
128 #include "math/m_trans_tmp.h"
129
130 #define SZ 1
131 #define INIT init_trans_1_GLbyte_elt
132 #define DEST_4F trans_1_GLbyte_4f_elt
133 #define DEST_4FC trans_1_GLbyte_4fc_elt
134 #define DEST_1UB trans_1_GLbyte_1ub_elt
135 #define DEST_1UI trans_1_GLbyte_1ui_elt
136 #include "math/m_trans_tmp.h"
137
138 #undef SRC
139 #undef TRX_4F
140 #undef TRX_4FC
141 #undef TRX_UB
142 #undef TRX_UI
143 #undef SRC_IDX
144
145 /* GL_UNSIGNED_BYTE
146 */
147 #define SRC GLubyte
148 #define SRC_IDX TYPE_IDX(GL_UNSIGNED_BYTE)
149 #define TRX_4F(f,n) UBYTE_TO_FLOAT( PTR_ELT(f,n) )
150 #define TRX_4FC(f,n) UBYTE_TO_FLOAT( PTR_ELT(f,n) )
151 #define TRX_UB(ub, f,n) ub = PTR_ELT(f,n)
152 #define TRX_UI(f,n) (GLuint)PTR_ELT(f,n)
153
154 /* 4ub->4ub handled in special case below.
155 */
156 #define SZ 4
157 #define INIT init_trans_4_GLubyte_elt
158 #define DEST_4F trans_4_GLubyte_4f_elt
159 #define DEST_4FC trans_4_GLubyte_4fc_elt
160 #include "math/m_trans_tmp.h"
161
162 #define SZ 3
163 #define INIT init_trans_3_GLubyte_elt
164 #define DEST_4F trans_3_GLubyte_4f_elt
165 #define DEST_4FC trans_3_GLubyte_4fc_elt
166 #include "math/m_trans_tmp.h"
167
168
169 #define SZ 1
170 #define INIT init_trans_1_GLubyte_elt
171 #define DEST_4F trans_1_GLubyte_4f_elt
172 #define DEST_4FC trans_1_GLubyte_4fc_elt
173 #define DEST_1UB trans_1_GLubyte_1ub_elt
174 #define DEST_1UI trans_1_GLubyte_1ui_elt
175 #include "math/m_trans_tmp.h"
176
177 #undef SRC
178 #undef SRC_IDX
179 #undef TRX_4F
180 #undef TRX_4FC
181 #undef TRX_UB
182 #undef TRX_UI
183
184
185 /* GL_SHORT
186 */
187 #define SRC GLshort
188 #define SRC_IDX TYPE_IDX(GL_SHORT)
189 #define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) )
190 #define TRX_4FC(f,n) SHORT_TO_FLOAT( PTR_ELT(f,n) )
191 #define TRX_UB(ub, f,n) ub = SHORT_TO_UBYTE(PTR_ELT(f,n))
192 #define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n))
193
194
195 #define SZ 4
196 #define INIT init_trans_4_GLshort_elt
197 #define DEST_4F trans_4_GLshort_4f_elt
198 #define DEST_4FC trans_4_GLshort_4fc_elt
199 #include "math/m_trans_tmp.h"
200
201 #define SZ 3
202 #define INIT init_trans_3_GLshort_elt
203 #define DEST_4F trans_3_GLshort_4f_elt
204 #define DEST_4FC trans_3_GLshort_4fc_elt
205 #include "math/m_trans_tmp.h"
206
207 #define SZ 2
208 #define INIT init_trans_2_GLshort_elt
209 #define DEST_4F trans_2_GLshort_4f_elt
210 #define DEST_4FC trans_2_GLshort_4fc_elt
211 #include "math/m_trans_tmp.h"
212
213 #define SZ 1
214 #define INIT init_trans_1_GLshort_elt
215 #define DEST_4F trans_1_GLshort_4f_elt
216 #define DEST_4FC trans_1_GLshort_4fc_elt
217 #define DEST_1UB trans_1_GLshort_1ub_elt
218 #define DEST_1UI trans_1_GLshort_1ui_elt
219 #include "math/m_trans_tmp.h"
220
221
222 #undef SRC
223 #undef SRC_IDX
224 #undef TRX_4F
225 #undef TRX_4FC
226 #undef TRX_UB
227 #undef TRX_UI
228
229
230 /* GL_UNSIGNED_SHORT
231 */
232 #define SRC GLushort
233 #define SRC_IDX TYPE_IDX(GL_UNSIGNED_SHORT)
234 #define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) )
235 #define TRX_4FC(f,n) USHORT_TO_FLOAT( PTR_ELT(f,n) )
236 #define TRX_UB(ub,f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 8)
237 #define TRX_UI(f,n) (GLuint) PTR_ELT(f,n)
238
239
240 #define SZ 4
241 #define INIT init_trans_4_GLushort_elt
242 #define DEST_4F trans_4_GLushort_4f_elt
243 #define DEST_4FC trans_4_GLushort_4fc_elt
244 #include "math/m_trans_tmp.h"
245
246 #define SZ 3
247 #define INIT init_trans_3_GLushort_elt
248 #define DEST_4F trans_3_GLushort_4f_elt
249 #define DEST_4FC trans_3_GLushort_4fc_elt
250 #include "math/m_trans_tmp.h"
251
252 #define SZ 2
253 #define INIT init_trans_2_GLushort_elt
254 #define DEST_4F trans_2_GLushort_4f_elt
255 #define DEST_4FC trans_2_GLushort_4fc_elt
256 #include "math/m_trans_tmp.h"
257
258 #define SZ 1
259 #define INIT init_trans_1_GLushort_elt
260 #define DEST_4F trans_1_GLushort_4f_elt
261 #define DEST_4FC trans_1_GLushort_4fc_elt
262 #define DEST_1UB trans_1_GLushort_1ub_elt
263 #define DEST_1UI trans_1_GLushort_1ui_elt
264 #include "math/m_trans_tmp.h"
265
266 #undef SRC
267 #undef SRC_IDX
268 #undef TRX_4F
269 #undef TRX_4FC
270 #undef TRX_UB
271 #undef TRX_UI
272
273
274 /* GL_INT
275 */
276 #define SRC GLint
277 #define SRC_IDX TYPE_IDX(GL_INT)
278 #define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) )
279 #define TRX_4FC(f,n) INT_TO_FLOAT( PTR_ELT(f,n) )
280 #define TRX_UB(ub, f,n) ub = INT_TO_UBYTE(PTR_ELT(f,n))
281 #define TRX_UI(f,n) (PTR_ELT(f,n) < 0 ? 0 : (GLuint) PTR_ELT(f,n))
282
283
284 #define SZ 4
285 #define INIT init_trans_4_GLint_elt
286 #define DEST_4F trans_4_GLint_4f_elt
287 #define DEST_4FC trans_4_GLint_4fc_elt
288 #include "math/m_trans_tmp.h"
289
290 #define SZ 3
291 #define INIT init_trans_3_GLint_elt
292 #define DEST_4F trans_3_GLint_4f_elt
293 #define DEST_4FC trans_3_GLint_4fc_elt
294 #include "math/m_trans_tmp.h"
295
296 #define SZ 2
297 #define INIT init_trans_2_GLint_elt
298 #define DEST_4F trans_2_GLint_4f_elt
299 #define DEST_4FC trans_2_GLint_4fc_elt
300 #include "math/m_trans_tmp.h"
301
302 #define SZ 1
303 #define INIT init_trans_1_GLint_elt
304 #define DEST_4F trans_1_GLint_4f_elt
305 #define DEST_4FC trans_1_GLint_4fc_elt
306 #define DEST_1UB trans_1_GLint_1ub_elt
307 #define DEST_1UI trans_1_GLint_1ui_elt
308 #include "math/m_trans_tmp.h"
309
310
311 #undef SRC
312 #undef SRC_IDX
313 #undef TRX_4F
314 #undef TRX_4FC
315 #undef TRX_UB
316 #undef TRX_UI
317
318
319 /* GL_UNSIGNED_INT
320 */
321 #define SRC GLuint
322 #define SRC_IDX TYPE_IDX(GL_UNSIGNED_INT)
323 #define TRX_4F(f,n) (GLfloat)( PTR_ELT(f,n) )
324 #define TRX_4FC(f,n) UINT_TO_FLOAT( PTR_ELT(f,n) )
325 #define TRX_UB(ub, f,n) ub = (GLubyte) (PTR_ELT(f,n) >> 24)
326 #define TRX_UI(f,n) PTR_ELT(f,n)
327
328
329 #define SZ 4
330 #define INIT init_trans_4_GLuint_elt
331 #define DEST_4F trans_4_GLuint_4f_elt
332 #define DEST_4FC trans_4_GLuint_4fc_elt
333 #include "math/m_trans_tmp.h"
334
335 #define SZ 3
336 #define INIT init_trans_3_GLuint_elt
337 #define DEST_4F trans_3_GLuint_4f_elt
338 #define DEST_4FC trans_3_GLuint_4fc_elt
339 #include "math/m_trans_tmp.h"
340
341 #define SZ 2
342 #define INIT init_trans_2_GLuint_elt
343 #define DEST_4F trans_2_GLuint_4f_elt
344 #define DEST_4FC trans_2_GLuint_4fc_elt
345 #include "math/m_trans_tmp.h"
346
347 #define SZ 1
348 #define INIT init_trans_1_GLuint_elt
349 #define DEST_4F trans_1_GLuint_4f_elt
350 #define DEST_4FC trans_1_GLuint_4fc_elt
351 #define DEST_1UB trans_1_GLuint_1ub_elt
352 #define DEST_1UI trans_1_GLuint_1ui_elt
353 #include "math/m_trans_tmp.h"
354
355 #undef SRC
356 #undef SRC_IDX
357 #undef TRX_4F
358 #undef TRX_4FC
359 #undef TRX_UB
360 #undef TRX_UI
361
362
363 /* GL_DOUBLE
364 */
365 #define SRC GLdouble
366 #define SRC_IDX TYPE_IDX(GL_DOUBLE)
367 #define TRX_4F(f,n) (GLfloat) PTR_ELT(f,n)
368 #define TRX_4FC(f,n) (GLfloat) PTR_ELT(f,n)
369 #define TRX_UB(ub,f,n) UNCLAMPED_FLOAT_TO_UBYTE(ub, PTR_ELT(f,n))
370 #define TRX_UI(f,n) (GLuint) (GLint) PTR_ELT(f,n)
371 #define TRX_1F(f,n) (GLfloat) PTR_ELT(f,n)
372
373
374 #define SZ 4
375 #define INIT init_trans_4_GLdouble_elt
376 #define DEST_4F trans_4_GLdouble_4f_elt
377 #define DEST_4FC trans_4_GLdouble_4fc_elt
378 #include "math/m_trans_tmp.h"
379
380 #define SZ 3
381 #define INIT init_trans_3_GLdouble_elt
382 #define DEST_4F trans_3_GLdouble_4f_elt
383 #define DEST_4FC trans_3_GLdouble_4fc_elt
384 #include "math/m_trans_tmp.h"
385
386 #define SZ 2
387 #define INIT init_trans_2_GLdouble_elt
388 #define DEST_4F trans_2_GLdouble_4f_elt
389 #define DEST_4FC trans_2_GLdouble_4fc_elt
390 #include "math/m_trans_tmp.h"
391
392 #define SZ 1
393 #define INIT init_trans_1_GLdouble_elt
394 #define DEST_4F trans_1_GLdouble_4f_elt
395 #define DEST_4FC trans_1_GLdouble_4fc_elt
396 #define DEST_1UB trans_1_GLdouble_1ub_elt
397 #define DEST_1UI trans_1_GLdouble_1ui_elt
398 #include "math/m_trans_tmp.h"
399
400 #undef SRC
401 #undef SRC_IDX
402 #undef TRX_4F
403 #undef TRX_4FC
404 #undef TRX_UB
405 #undef TRX_UI
406
407 /* GL_FLOAT
408 */
409 #define SRC GLfloat
410 #define SRC_IDX TYPE_IDX(GL_FLOAT)
411 #define TRX_4F(f,n) (GLfloat) PTR_ELT(f,n)
412 #define TRX_4FC(f,n) (GLfloat) PTR_ELT(f,n)
413 #define TRX_UB(ub,f,n) UNCLAMPED_FLOAT_TO_UBYTE(ub, PTR_ELT(f,n))
414 #define TRX_UI(f,n) (GLuint) (GLint) PTR_ELT(f,n)
415 #define TRX_1F(f,n) (GLfloat) PTR_ELT(f,n)
416
417
418 #define SZ 4
419 #define INIT init_trans_4_GLfloat_elt
420 #define DEST_4F trans_4_GLfloat_4f_elt
421 #define DEST_4FC trans_4_GLfloat_4fc_elt
422 #include "math/m_trans_tmp.h"
423
424 #define SZ 3
425 #define INIT init_trans_3_GLfloat_elt
426 #define DEST_4F trans_3_GLfloat_4f_elt
427 #define DEST_4FC trans_3_GLfloat_4fc_elt
428 #include "math/m_trans_tmp.h"
429
430 #define SZ 2
431 #define INIT init_trans_2_GLfloat_elt
432 #define DEST_4F trans_2_GLfloat_4f_elt
433 #define DEST_4FC trans_2_GLfloat_4fc_elt
434 #include "math/m_trans_tmp.h"
435
436 #define SZ 1
437 #define INIT init_trans_1_GLfloat_elt
438 #define DEST_4F trans_1_GLfloat_4f_elt
439 #define DEST_4FC trans_1_GLfloat_4fc_elt
440 #define DEST_1UB trans_1_GLfloat_1ub_elt
441 #define DEST_1UI trans_1_GLfloat_1ui_elt
442 #include "math/m_trans_tmp.h"
443
444 #undef SRC
445 #undef SRC_IDX
446 #undef TRX_4F
447 #undef TRX_4FC
448 #undef TRX_UB
449 #undef TRX_UI
450
451
452
453
454 static void init_translate_elt(void)
455 {
456 MEMSET( TAB(_1ui), 0, sizeof(TAB(_1ui)) );
457 MEMSET( TAB(_1ub), 0, sizeof(TAB(_1ub)) );
458 MEMSET( TAB(_4f), 0, sizeof(TAB(_4f)) );
459 MEMSET( TAB(_4fc), 0, sizeof(TAB(_4fc)) );
460
461 init_trans_4_GLbyte_elt();
462 init_trans_3_GLbyte_elt();
463 init_trans_2_GLbyte_elt();
464 init_trans_1_GLbyte_elt();
465 init_trans_1_GLubyte_elt();
466 init_trans_3_GLubyte_elt();
467 init_trans_4_GLubyte_elt();
468 init_trans_4_GLshort_elt();
469 init_trans_3_GLshort_elt();
470 init_trans_2_GLshort_elt();
471 init_trans_1_GLshort_elt();
472 init_trans_4_GLushort_elt();
473 init_trans_3_GLushort_elt();
474 init_trans_2_GLushort_elt();
475 init_trans_1_GLushort_elt();
476 init_trans_4_GLint_elt();
477 init_trans_3_GLint_elt();
478 init_trans_2_GLint_elt();
479 init_trans_1_GLint_elt();
480 init_trans_4_GLuint_elt();
481 init_trans_3_GLuint_elt();
482 init_trans_2_GLuint_elt();
483 init_trans_1_GLuint_elt();
484 init_trans_4_GLdouble_elt();
485 init_trans_3_GLdouble_elt();
486 init_trans_2_GLdouble_elt();
487 init_trans_1_GLdouble_elt();
488 init_trans_4_GLfloat_elt();
489 init_trans_3_GLfloat_elt();
490 init_trans_2_GLfloat_elt();
491 init_trans_1_GLfloat_elt();
492 }
493
494
495 #undef TAB
496 #undef CLASS
497 #undef ARGS
498 #undef CHECK
499 #ifdef START
500 #undef START
501 #endif
502
503
504
505 void _tnl_imm_elt_init( void )
506 {
507 init_translate_elt();
508 }
509
510
511 static void _tnl_trans_elt_1ui(GLuint *to,
512 const struct gl_client_array *from,
513 const GLuint *flags,
514 const GLuint *elts,
515 GLuint match,
516 GLuint start,
517 GLuint n )
518 {
519 const GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
520 _tnl_trans_elt_1ui_tab[TYPE_IDX(from->Type)]( to,
521 fromData,
522 from->StrideB,
523 flags,
524 elts,
525 match,
526 start,
527 n );
528
529 }
530
531
532 static void _tnl_trans_elt_1ub(GLubyte *to,
533 const struct gl_client_array *from,
534 const GLuint *flags,
535 const GLuint *elts,
536 GLuint match,
537 GLuint start,
538 GLuint n )
539 {
540 const GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
541 _tnl_trans_elt_1ub_tab[TYPE_IDX(from->Type)]( to,
542 fromData,
543 from->StrideB,
544 flags,
545 elts,
546 match,
547 start,
548 n );
549
550 }
551
552 static void _tnl_trans_elt_4f(GLfloat (*to)[4],
553 const struct gl_client_array *from,
554 const GLuint *flags,
555 const GLuint *elts,
556 GLuint match,
557 GLuint start,
558 GLuint n )
559 {
560 const GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
561 _tnl_trans_elt_4f_tab[from->Size][TYPE_IDX(from->Type)]( to,
562 fromData,
563 from->StrideB,
564 flags,
565 elts,
566 match,
567 start,
568 n );
569
570 }
571
572
573 static void _tnl_trans_elt_4fc(GLfloat (*to)[4],
574 const struct gl_client_array *from,
575 const GLuint *flags,
576 const GLuint *elts,
577 GLuint match,
578 GLuint start,
579 GLuint n )
580 {
581 const GLubyte *fromData = ADD_POINTERS( from->Ptr, from->BufferObj->Data );
582 _tnl_trans_elt_4fc_tab[from->Size][TYPE_IDX(from->Type)]( to,
583 fromData,
584 from->StrideB,
585 flags,
586 elts,
587 match,
588 start,
589 n );
590
591 }
592
593
594
595
596 /* Batch function to translate away all the array elements in the
597 * input buffer prior to transform. Done only the first time a vertex
598 * buffer is executed or compiled.
599 *
600 * KW: Have to do this after each glEnd if arrays aren't locked.
601 */
602 void _tnl_translate_array_elts( GLcontext *ctx, struct immediate *IM,
603 GLuint start, GLuint count )
604 {
605 GLuint *flags = IM->Flag;
606 const GLuint *elts = IM->Elt;
607 GLuint translate = ctx->Array._Enabled;
608 GLuint translateConventional;
609 GLuint attr;
610
611 if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
612 _mesa_debug(ctx, "exec_array_elements %d .. %d\n", start, count);
613
614 /* XXX It would be nice to replace this code with a loop over the vertex
615 * attributes but there's a fair number of special cases.
616 */
617
618 /* Allocate destination attribute arrays if needed */
619 ASSERT(IM->Attrib[VERT_ATTRIB_POS]);
620 for (attr = 1; attr < VERT_ATTRIB_MAX; attr++) {
621 if ((translate & (1 << attr)) && !IM->Attrib[attr]) {
622 IM->Attrib[attr] = (GLfloat (*)[4]) _mesa_malloc(IMM_SIZE * 4 * sizeof(GLfloat));
623 if (!IM->Attrib[attr]) {
624 _mesa_error(ctx, GL_OUT_OF_MEMORY, "vertex processing2");
625 return;
626 }
627 }
628 }
629
630 translateConventional = translate;
631
632 /*
633 * When vertex program mode is enabled, the generic vertex attribute arrays
634 * have priority over the conventional arrays. Process those arrays now.
635 * When we're done here, translateConventional will indicate which
636 * conventional arrays still have to be translated when we're done.
637 */
638 if (ctx->VertexProgram.Enabled) {
639 for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
640 const GLuint attrBit = 1 << attr;
641 if ((translate & attrBit) && ctx->Array.VertexAttrib[attr].Enabled) {
642 _tnl_trans_elt_4f( IM->Attrib[attr],
643 &ctx->Array.VertexAttrib[attr],
644 flags, elts, (VERT_BIT_ELT | attrBit),
645 start, count);
646 /* special case stuff */
647 if (attr == VERT_ATTRIB_POS) {
648 if (ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Size == 4)
649 translate |= VERT_BITS_OBJ_234;
650 else if (ctx->Array.VertexAttrib[VERT_ATTRIB_POS].Size == 3)
651 translate |= VERT_BITS_OBJ_23;
652 }
653 else if (attr >= VERT_ATTRIB_TEX0 && attr <= VERT_ATTRIB_TEX7) {
654 if (ctx->Array.VertexAttrib[attr].Size == 4)
655 IM->TexSize |= TEX_SIZE_4(attr - VERT_ATTRIB_TEX0);
656 else if (ctx->Array.VertexAttrib[attr].Size == 3)
657 IM->TexSize |= TEX_SIZE_3(attr - VERT_ATTRIB_TEX0);
658 }
659 /* override the conventional array */
660 translateConventional &= ~attrBit;
661 }
662 }
663 }
664
665 /*
666 * Check which conventional arrays are needed.
667 */
668 if (translateConventional & VERT_BIT_POS) {
669 _tnl_trans_elt_4f( IM->Attrib[VERT_ATTRIB_POS],
670 &ctx->Array.Vertex,
671 flags, elts, (VERT_BIT_ELT|VERT_BIT_POS),
672 start, count);
673
674 if (ctx->Array.Vertex.Size == 4)
675 translate |= VERT_BITS_OBJ_234;
676 else if (ctx->Array.Vertex.Size == 3)
677 translate |= VERT_BITS_OBJ_23;
678 }
679
680 if (translateConventional & VERT_BIT_NORMAL) {
681 _tnl_trans_elt_4f( IM->Attrib[VERT_ATTRIB_NORMAL],
682 &ctx->Array.Normal,
683 flags, elts, (VERT_BIT_ELT|VERT_BIT_NORMAL),
684 start, count);
685 }
686
687 if (translateConventional & VERT_BIT_COLOR0) {
688 _tnl_trans_elt_4fc( IM->Attrib[VERT_ATTRIB_COLOR0],
689 &ctx->Array.Color,
690 flags, elts, (VERT_BIT_ELT|VERT_BIT_COLOR0),
691 start, count);
692 }
693
694 if (translateConventional & VERT_BIT_COLOR1) {
695 _tnl_trans_elt_4fc( IM->Attrib[VERT_ATTRIB_COLOR1],
696 &ctx->Array.SecondaryColor,
697 flags, elts, (VERT_BIT_ELT|VERT_BIT_COLOR1),
698 start, count);
699 }
700
701 if (translateConventional & VERT_BIT_FOG) {
702 _tnl_trans_elt_4f( IM->Attrib[VERT_ATTRIB_FOG],
703 &ctx->Array.FogCoord,
704 flags, elts, (VERT_BIT_ELT|VERT_BIT_FOG),
705 start, count);
706 }
707
708 if (translateConventional & VERT_BITS_TEX_ANY) {
709 GLuint i;
710 for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
711 if (translateConventional & VERT_BIT_TEX(i)) {
712 _tnl_trans_elt_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i],
713 &ctx->Array.TexCoord[i],
714 flags, elts, (VERT_BIT_ELT|VERT_BIT_TEX(i)),
715 start, count);
716
717 if (ctx->Array.TexCoord[i].Size == 4)
718 IM->TexSize |= TEX_SIZE_4(i);
719 else if (ctx->Array.TexCoord[i].Size == 3)
720 IM->TexSize |= TEX_SIZE_3(i);
721 }
722 }
723
724 if (translate & VERT_BIT_INDEX)
725 _tnl_trans_elt_1ui( IM->Index,
726 &ctx->Array.Index,
727 flags, elts, (VERT_BIT_ELT|VERT_BIT_INDEX),
728 start, count);
729
730 if (translate & VERT_BIT_EDGEFLAG)
731 _tnl_trans_elt_1ub( IM->EdgeFlag,
732 &ctx->Array.EdgeFlag,
733 flags, elts, (VERT_BIT_ELT|VERT_BIT_EDGEFLAG),
734 start, count);
735
736 {
737 GLuint i;
738 for (i = start ; i < count ; i++)
739 if (flags[i] & VERT_BIT_ELT)
740 flags[i] |= translate;
741 }
742
743 IM->FlushElt = 0;
744 }