a4efb068ac3faa6294d4d4207b1a6467bfb21bc4
[mesa.git] / src / mesa / array_cache / ac_import.c
1 /* $Id: ac_import.c,v 1.12 2001/04/17 20:37:44 brianp Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Keith Whitwell <keithw@valinux.com>
28 */
29
30 #include "glheader.h"
31 #include "macros.h"
32 #include "mem.h"
33 #include "mmath.h"
34 #include "mtypes.h"
35
36 #include "math/m_translate.h"
37 #include "array_cache/ac_context.h"
38 #include "math/m_translate.h"
39
40 #define STRIDE_ARRAY( array, offset ) \
41 do { \
42 char *tmp = (char *) (array).Ptr; \
43 tmp += (offset) * (array).StrideB; \
44 (array).Ptr = tmp; \
45 } while (0)
46
47 /* Set the array pointer back to its source when the cached data is
48 * invalidated:
49 */
50
51 static void reset_texcoord( GLcontext *ctx, GLuint unit )
52 {
53 ACcontext *ac = AC_CONTEXT(ctx);
54
55 if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) {
56 ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit];
57 STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start);
58 }
59 else {
60 ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit];
61
62 if (ctx->Current.Texcoord[unit][3] != 1.0)
63 ac->Raw.TexCoord[unit].Size = 4;
64 else if (ctx->Current.Texcoord[unit][2] != 0.0)
65 ac->Raw.TexCoord[unit].Size = 3;
66 else
67 ac->Raw.TexCoord[unit].Size = 2;
68 }
69
70 ac->IsCached.TexCoord[unit] = GL_FALSE;
71 ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit);
72 }
73
74 static void reset_vertex( GLcontext *ctx )
75 {
76 ACcontext *ac = AC_CONTEXT(ctx);
77 ASSERT(ctx->Array.Vertex.Enabled);
78 ac->Raw.Vertex = ctx->Array.Vertex;
79 STRIDE_ARRAY(ac->Raw.Vertex, ac->start);
80 ac->IsCached.Vertex = GL_FALSE;
81 ac->NewArrayState &= ~_NEW_ARRAY_VERTEX;
82 }
83
84
85 static void reset_normal( GLcontext *ctx )
86 {
87 ACcontext *ac = AC_CONTEXT(ctx);
88
89 if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) {
90 ac->Raw.Normal = ctx->Array.Normal;
91 STRIDE_ARRAY(ac->Raw.Normal, ac->start);
92 }
93 else {
94 ac->Raw.Normal = ac->Fallback.Normal;
95 }
96
97 ac->IsCached.Normal = GL_FALSE;
98 ac->NewArrayState &= ~_NEW_ARRAY_NORMAL;
99 }
100
101
102 static void reset_color( GLcontext *ctx )
103 {
104 ACcontext *ac = AC_CONTEXT(ctx);
105
106
107 if (ctx->Array._Enabled & _NEW_ARRAY_COLOR) {
108 ac->Raw.Color = ctx->Array.Color;
109 STRIDE_ARRAY(ac->Raw.Color, ac->start);
110 }
111 else
112 ac->Raw.Color = ac->Fallback.Color;
113
114 ac->IsCached.Color = GL_FALSE;
115 ac->NewArrayState &= ~_NEW_ARRAY_COLOR;
116 }
117
118
119 static void reset_secondarycolor( GLcontext *ctx )
120 {
121 ACcontext *ac = AC_CONTEXT(ctx);
122
123 if (ctx->Array._Enabled & _NEW_ARRAY_SECONDARYCOLOR) {
124 ac->Raw.SecondaryColor = ctx->Array.SecondaryColor;
125 STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start);
126 }
127 else
128 ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
129
130 ac->IsCached.SecondaryColor = GL_FALSE;
131 ac->NewArrayState &= ~_NEW_ARRAY_SECONDARYCOLOR;
132 }
133
134
135 static void reset_index( GLcontext *ctx )
136 {
137 ACcontext *ac = AC_CONTEXT(ctx);
138
139 if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) {
140 ac->Raw.Index = ctx->Array.Index;
141 STRIDE_ARRAY(ac->Raw.Index, ac->start);
142 }
143 else
144 ac->Raw.Index = ac->Fallback.Index;
145
146 ac->IsCached.Index = GL_FALSE;
147 ac->NewArrayState &= ~_NEW_ARRAY_INDEX;
148 }
149
150 static void reset_fogcoord( GLcontext *ctx )
151 {
152 ACcontext *ac = AC_CONTEXT(ctx);
153
154 if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) {
155 ac->Raw.FogCoord = ctx->Array.FogCoord;
156 STRIDE_ARRAY(ac->Raw.FogCoord, ac->start);
157 }
158 else
159 ac->Raw.FogCoord = ac->Fallback.FogCoord;
160
161 ac->IsCached.FogCoord = GL_FALSE;
162 ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD;
163 }
164
165 static void reset_edgeflag( GLcontext *ctx )
166 {
167 ACcontext *ac = AC_CONTEXT(ctx);
168
169 if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) {
170 ac->Raw.EdgeFlag = ctx->Array.EdgeFlag;
171 STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start);
172 }
173 else
174 ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
175
176 ac->IsCached.EdgeFlag = GL_FALSE;
177 ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG;
178 }
179
180
181 /* Functions to import array ranges with specified types and strides.
182 */
183 static void import_texcoord( GLcontext *ctx, GLuint unit,
184 GLenum type, GLuint stride )
185 {
186 ACcontext *ac = AC_CONTEXT(ctx);
187 struct gl_client_array *from = &ac->Raw.TexCoord[unit];
188 struct gl_client_array *to = &ac->Cache.TexCoord[unit];
189
190 /* Limited choices at this stage:
191 */
192 ASSERT(type == GL_FLOAT);
193 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
194 ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
195
196 _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
197 from->Ptr,
198 from->StrideB,
199 from->Type,
200 from->Size,
201 ac->start,
202 ac->count - ac->start);
203
204 to->Size = from->Size;
205 to->StrideB = 4 * sizeof(GLfloat);
206 to->Type = GL_FLOAT;
207 ac->IsCached.TexCoord[unit] = GL_TRUE;
208 }
209
210 static void import_vertex( GLcontext *ctx,
211 GLenum type, GLuint stride )
212 {
213 ACcontext *ac = AC_CONTEXT(ctx);
214 struct gl_client_array *from = &ac->Raw.Vertex;
215 struct gl_client_array *to = &ac->Cache.Vertex;
216
217 /* Limited choices at this stage:
218 */
219 ASSERT(type == GL_FLOAT);
220 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
221
222 _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
223 from->Ptr,
224 from->StrideB,
225 from->Type,
226 from->Size,
227 0,
228 ac->count - ac->start);
229
230 to->Size = from->Size;
231 to->StrideB = 4 * sizeof(GLfloat);
232 to->Type = GL_FLOAT;
233 ac->IsCached.Vertex = GL_TRUE;
234 }
235
236 static void import_normal( GLcontext *ctx,
237 GLenum type, GLuint stride )
238 {
239 ACcontext *ac = AC_CONTEXT(ctx);
240 struct gl_client_array *from = &ac->Raw.Normal;
241 struct gl_client_array *to = &ac->Cache.Normal;
242
243 /* Limited choices at this stage:
244 */
245 ASSERT(type == GL_FLOAT);
246 ASSERT(stride == 3*sizeof(GLfloat) || stride == 0);
247
248 _math_trans_3f( (GLfloat (*)[3]) to->Ptr,
249 from->Ptr,
250 from->StrideB,
251 from->Type,
252 0,
253 ac->count - ac->start);
254
255 to->StrideB = 3 * sizeof(GLfloat);
256 to->Type = GL_FLOAT;
257 ac->IsCached.Normal = GL_TRUE;
258 }
259
260 static void import_color( GLcontext *ctx,
261 GLenum type, GLuint stride )
262 {
263 ACcontext *ac = AC_CONTEXT(ctx);
264 struct gl_client_array *from = &ac->Raw.Color;
265 struct gl_client_array *to = &ac->Cache.Color;
266
267 /* Limited choices at this stage:
268 */
269 ASSERT(type == CHAN_TYPE);
270 ASSERT(stride == 4 * sizeof(GLchan) || stride == 0);
271
272 _math_trans_4chan( (GLchan (*)[4]) to->Ptr,
273 from->Ptr,
274 from->StrideB,
275 from->Type,
276 from->Size,
277 0,
278 ac->count - ac->start);
279
280 to->Size = from->Size;
281 to->StrideB = 4 * sizeof(GLchan);
282 to->Type = CHAN_TYPE;
283 ac->IsCached.Color = GL_TRUE;
284 }
285
286 static void import_index( GLcontext *ctx,
287 GLenum type, GLuint stride )
288 {
289 ACcontext *ac = AC_CONTEXT(ctx);
290 struct gl_client_array *from = &ac->Raw.Index;
291 struct gl_client_array *to = &ac->Cache.Index;
292
293 /* Limited choices at this stage:
294 */
295 ASSERT(type == GL_UNSIGNED_INT);
296 ASSERT(stride == sizeof(GLuint) || stride == 0);
297
298 _math_trans_1ui( (GLuint *) to->Ptr,
299 from->Ptr,
300 from->StrideB,
301 from->Type,
302 0,
303 ac->count - ac->start);
304
305 to->StrideB = sizeof(GLuint);
306 to->Type = GL_UNSIGNED_INT;
307 ac->IsCached.Index = GL_TRUE;
308 }
309
310 static void import_secondarycolor( GLcontext *ctx,
311 GLenum type, GLuint stride )
312 {
313 ACcontext *ac = AC_CONTEXT(ctx);
314 struct gl_client_array *from = &ac->Raw.SecondaryColor;
315 struct gl_client_array *to = &ac->Cache.SecondaryColor;
316
317 /* Limited choices at this stage:
318 */
319 ASSERT(type == CHAN_TYPE);
320 ASSERT(stride == 4 * sizeof(GLchan) || stride == 0);
321
322 _math_trans_4chan( (GLchan (*)[4]) to->Ptr,
323 from->Ptr,
324 from->StrideB,
325 from->Type,
326 from->Size,
327 0,
328 ac->count - ac->start);
329
330 to->StrideB = 4 * sizeof(GLchan);
331 to->Type = CHAN_TYPE;
332 ac->IsCached.SecondaryColor = GL_TRUE;
333 }
334
335 static void import_fogcoord( GLcontext *ctx,
336 GLenum type, GLuint stride )
337 {
338 ACcontext *ac = AC_CONTEXT(ctx);
339 struct gl_client_array *from = &ac->Raw.FogCoord;
340 struct gl_client_array *to = &ac->Cache.FogCoord;
341
342 /* Limited choices at this stage:
343 */
344 ASSERT(type == GL_FLOAT);
345 ASSERT(stride == sizeof(GLfloat) || stride == 0);
346
347 _math_trans_1f( (GLfloat *) to->Ptr,
348 from->Ptr,
349 from->StrideB,
350 from->Type,
351 0,
352 ac->count - ac->start);
353
354 to->StrideB = sizeof(GLfloat);
355 to->Type = GL_FLOAT;
356 ac->IsCached.FogCoord = GL_TRUE;
357 }
358
359 static void import_edgeflag( GLcontext *ctx,
360 GLenum type, GLuint stride )
361 {
362 ACcontext *ac = AC_CONTEXT(ctx);
363 struct gl_client_array *from = &ac->Raw.EdgeFlag;
364 struct gl_client_array *to = &ac->Cache.EdgeFlag;
365
366 /* Limited choices at this stage:
367 */
368 ASSERT(type == GL_UNSIGNED_BYTE);
369 ASSERT(stride == sizeof(GLubyte) || stride == 0);
370
371 _math_trans_1ub( (GLubyte *) to->Ptr,
372 from->Ptr,
373 from->StrideB,
374 from->Type,
375 0,
376 ac->count - ac->start);
377
378 to->StrideB = sizeof(GLubyte);
379 to->Type = GL_UNSIGNED_BYTE;
380 ac->IsCached.EdgeFlag = GL_TRUE;
381 }
382
383
384
385 /* Externals to request arrays with specific properties:
386 */
387 struct gl_client_array *_ac_import_texcoord( GLcontext *ctx,
388 GLuint unit,
389 GLenum type,
390 GLuint reqstride,
391 GLuint reqsize,
392 GLboolean reqwriteable,
393 GLboolean *writeable )
394 {
395 ACcontext *ac = AC_CONTEXT(ctx);
396
397 /* Can we keep the existing version?
398 */
399 if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit))
400 reset_texcoord( ctx, unit );
401
402 /* Is the request impossible?
403 */
404 if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize)
405 return 0;
406
407 /* Do we need to pull in a copy of the client data:
408 */
409 if (ac->Raw.TexCoord[unit].Type != type ||
410 (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) ||
411 reqwriteable)
412 {
413 if (!ac->IsCached.TexCoord[unit])
414 import_texcoord(ctx, unit, type, reqstride );
415 *writeable = GL_TRUE;
416 return &ac->Cache.TexCoord[unit];
417 }
418 else {
419 *writeable = GL_FALSE;
420 return &ac->Raw.TexCoord[unit];
421 }
422 }
423
424 struct gl_client_array *_ac_import_vertex( GLcontext *ctx,
425 GLenum type,
426 GLuint reqstride,
427 GLuint reqsize,
428 GLboolean reqwriteable,
429 GLboolean *writeable )
430 {
431 ACcontext *ac = AC_CONTEXT(ctx);
432
433 /* Can we keep the existing version?
434 */
435 if (ac->NewArrayState & _NEW_ARRAY_VERTEX)
436 reset_vertex( ctx );
437
438 /* Is the request impossible?
439 */
440 if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize)
441 return 0;
442
443 /* Do we need to pull in a copy of the client data:
444 */
445 if (ac->Raw.Vertex.Type != type ||
446 (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) ||
447 reqwriteable)
448 {
449 if (!ac->IsCached.Vertex)
450 import_vertex(ctx, type, reqstride );
451 *writeable = GL_TRUE;
452 return &ac->Cache.Vertex;
453 }
454 else {
455 *writeable = GL_FALSE;
456 return &ac->Raw.Vertex;
457 }
458 }
459
460 struct gl_client_array *_ac_import_normal( GLcontext *ctx,
461 GLenum type,
462 GLuint reqstride,
463 GLboolean reqwriteable,
464 GLboolean *writeable )
465 {
466 ACcontext *ac = AC_CONTEXT(ctx);
467
468 /* Can we keep the existing version?
469 */
470 if (ac->NewArrayState & _NEW_ARRAY_NORMAL)
471 reset_normal( ctx );
472
473 /* Do we need to pull in a copy of the client data:
474 */
475 if (ac->Raw.Normal.Type != type ||
476 (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) ||
477 reqwriteable)
478 {
479 if (!ac->IsCached.Normal)
480 import_normal(ctx, type, reqstride );
481 *writeable = GL_TRUE;
482 return &ac->Cache.Normal;
483 }
484 else {
485 *writeable = GL_FALSE;
486 return &ac->Raw.Normal;
487 }
488 }
489
490 struct gl_client_array *_ac_import_color( GLcontext *ctx,
491 GLenum type,
492 GLuint reqstride,
493 GLuint reqsize,
494 GLboolean reqwriteable,
495 GLboolean *writeable )
496 {
497 ACcontext *ac = AC_CONTEXT(ctx);
498
499 /* Can we keep the existing version?
500 */
501 if (ac->NewArrayState & _NEW_ARRAY_COLOR)
502 reset_color( ctx );
503
504 /* Is the request impossible?
505 */
506 if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) {
507 return 0;
508 }
509
510 /* Do we need to pull in a copy of the client data:
511 */
512 if (ac->Raw.Color.Type != type ||
513 (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) ||
514 reqwriteable)
515 {
516 if (!ac->IsCached.Color)
517 import_color(ctx, type, reqstride );
518 *writeable = GL_TRUE;
519 return &ac->Cache.Color;
520 }
521 else {
522 *writeable = GL_FALSE;
523 return &ac->Raw.Color;
524 }
525 }
526
527 struct gl_client_array *_ac_import_index( GLcontext *ctx,
528 GLenum type,
529 GLuint reqstride,
530 GLboolean reqwriteable,
531 GLboolean *writeable )
532 {
533 ACcontext *ac = AC_CONTEXT(ctx);
534
535 /* Can we keep the existing version?
536 */
537 if (ac->NewArrayState & _NEW_ARRAY_INDEX)
538 reset_index( ctx );
539
540
541 /* Do we need to pull in a copy of the client data:
542 */
543 if (ac->Raw.Index.Type != type ||
544 (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) ||
545 reqwriteable)
546 {
547 if (!ac->IsCached.Index)
548 import_index(ctx, type, reqstride );
549 *writeable = GL_TRUE;
550 return &ac->Cache.Index;
551 }
552 else {
553 *writeable = GL_FALSE;
554 return &ac->Raw.Index;
555 }
556 }
557
558 struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx,
559 GLenum type,
560 GLuint reqstride,
561 GLuint reqsize,
562 GLboolean reqwriteable,
563 GLboolean *writeable )
564 {
565 ACcontext *ac = AC_CONTEXT(ctx);
566
567 /* Can we keep the existing version?
568 */
569 if (ac->NewArrayState & _NEW_ARRAY_SECONDARYCOLOR)
570 reset_secondarycolor( ctx );
571
572 /* Is the request impossible?
573 */
574 if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize)
575 return 0;
576
577 /* Do we need to pull in a copy of the client data:
578 */
579 if (ac->Raw.SecondaryColor.Type != type ||
580 (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) ||
581 reqwriteable)
582 {
583 if (!ac->IsCached.SecondaryColor)
584 import_secondarycolor(ctx, type, reqstride );
585 *writeable = GL_TRUE;
586 return &ac->Cache.SecondaryColor;
587 }
588 else {
589 *writeable = GL_FALSE;
590 return &ac->Raw.SecondaryColor;
591 }
592 }
593
594 struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx,
595 GLenum type,
596 GLuint reqstride,
597 GLboolean reqwriteable,
598 GLboolean *writeable )
599 {
600 ACcontext *ac = AC_CONTEXT(ctx);
601
602 /* Can we keep the existing version?
603 */
604 if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD)
605 reset_fogcoord( ctx );
606
607 /* Do we need to pull in a copy of the client data:
608 */
609 if (ac->Raw.FogCoord.Type != type ||
610 (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) ||
611 reqwriteable)
612 {
613 if (!ac->IsCached.FogCoord)
614 import_fogcoord(ctx, type, reqstride );
615 *writeable = GL_TRUE;
616 return &ac->Cache.FogCoord;
617 }
618 else {
619 *writeable = GL_FALSE;
620 return &ac->Raw.FogCoord;
621 }
622 }
623
624
625
626
627 struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx,
628 GLenum type,
629 GLuint reqstride,
630 GLboolean reqwriteable,
631 GLboolean *writeable )
632 {
633 ACcontext *ac = AC_CONTEXT(ctx);
634
635 /* Can we keep the existing version?
636 */
637 if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG)
638 reset_edgeflag( ctx );
639
640 /* Do we need to pull in a copy of the client data:
641 */
642 if (ac->Raw.EdgeFlag.Type != type ||
643 (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) ||
644 reqwriteable)
645 {
646 if (!ac->IsCached.EdgeFlag)
647 import_edgeflag(ctx, type, reqstride );
648 *writeable = GL_TRUE;
649 return &ac->Cache.EdgeFlag;
650 }
651 else {
652 *writeable = GL_FALSE;
653 return &ac->Raw.EdgeFlag;
654 }
655 }
656
657
658
659
660
661 /* Clients must call this function to validate state and set bounds
662 * before importing any data:
663 */
664 void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count )
665 {
666 ACcontext *ac = AC_CONTEXT(ctx);
667
668 if (!ctx->Array.LockCount) {
669 /* Not locked, discard cached data. Changes to lock
670 * status are caught via. _ac_invalidate_state().
671 */
672 ac->NewArrayState = _NEW_ARRAY_ALL;
673 ac->start = start;
674 ac->count = count;
675 }
676 else {
677 /* Locked, discard data for any disabled arrays. Require that
678 * the whole locked range always be dealt with, otherwise hard to
679 * maintain cached data in the face of clipping.
680 */
681 ac->NewArrayState |= ~ctx->Array._Enabled;
682 ac->start = ctx->Array.LockFirst;
683 ac->count = ctx->Array.LockCount;
684 ASSERT(ac->start == start); /* hmm? */
685 ASSERT(ac->count == count);
686 }
687 }
688
689
690
691 /* Additional convienence function for importing a the element list
692 * for drawelements, drawrangeelements:
693 */
694 CONST void *
695 _ac_import_elements( GLcontext *ctx,
696 GLenum new_type,
697 GLuint count,
698 GLenum old_type,
699 CONST void *indices )
700 {
701 ACcontext *ac = AC_CONTEXT(ctx);
702
703 if (old_type == new_type)
704 return indices;
705
706 if (ac->elt_size < count * sizeof(GLuint)) {
707 if (ac->Elts) FREE(ac->Elts);
708 while (ac->elt_size < count * sizeof(GLuint))
709 ac->elt_size *= 2;
710 ac->Elts = (GLuint *) MALLOC(ac->elt_size);
711 }
712
713 switch (new_type) {
714 case GL_UNSIGNED_BYTE:
715 ASSERT(0);
716 return 0;
717 case GL_UNSIGNED_SHORT:
718 ASSERT(0);
719 return 0;
720 case GL_UNSIGNED_INT: {
721 GLuint *out = (GLuint *)ac->Elts;
722 GLuint i;
723
724 switch (old_type) {
725 case GL_UNSIGNED_BYTE: {
726 CONST GLubyte *in = (CONST GLubyte *)indices;
727 for (i = 0 ; i < count ; i++)
728 out[i] = in[i];
729 break;
730 }
731 case GL_UNSIGNED_SHORT: {
732 CONST GLushort *in = (CONST GLushort *)indices;
733 for (i = 0 ; i < count ; i++)
734 out[i] = in[i];
735 break;
736 }
737 default:
738 ASSERT(0);
739 }
740
741 return (CONST void *)out;
742 }
743 default:
744 ASSERT(0);
745 break;
746 }
747
748 return 0;
749 }