fix a variety of warnings/errors
[mesa.git] / src / mesa / array_cache / ac_import.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.1
4 *
5 * Copyright (C) 1999-2004 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 "macros.h"
30 #include "imports.h"
31 #include "mtypes.h"
32
33 #include "math/m_translate.h"
34 #include "array_cache/ac_context.h"
35 #include "math/m_translate.h"
36
37 #define STRIDE_ARRAY( array, offset ) \
38 do { \
39 GLubyte *tmp = ADD_POINTERS( (array).BufferObj->Data, (array).Ptr ) \
40 + (offset) * (array).StrideB; \
41 (array).Ptr = tmp; \
42 } while (0)
43
44
45 /* Set the array pointer back to its source when the cached data is
46 * invalidated:
47 */
48 static void
49 reset_texcoord( GLcontext *ctx, GLuint unit )
50 {
51 ACcontext *ac = AC_CONTEXT(ctx);
52
53 if (ctx->Array.TexCoord[unit].Enabled) {
54 ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit];
55 STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start);
56 }
57 else {
58 ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit];
59
60 if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3] != 1.0)
61 ac->Raw.TexCoord[unit].Size = 4;
62 else if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2] != 0.0)
63 ac->Raw.TexCoord[unit].Size = 3;
64 else
65 ac->Raw.TexCoord[unit].Size = 2;
66 }
67
68 ac->IsCached.TexCoord[unit] = GL_FALSE;
69 ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit);
70 }
71
72 static void
73 reset_vertex( GLcontext *ctx )
74 {
75 ACcontext *ac = AC_CONTEXT(ctx);
76 ASSERT(ctx->Array.Vertex.Enabled
77 || (ctx->VertexProgram._Enabled && ctx->Array.VertexAttrib[0].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
86 reset_normal( GLcontext *ctx )
87 {
88 ACcontext *ac = AC_CONTEXT(ctx);
89
90 if (ctx->Array.Normal.Enabled) {
91 ac->Raw.Normal = ctx->Array.Normal;
92 STRIDE_ARRAY(ac->Raw.Normal, ac->start);
93 }
94 else {
95 ac->Raw.Normal = ac->Fallback.Normal;
96 }
97
98 ac->IsCached.Normal = GL_FALSE;
99 ac->NewArrayState &= ~_NEW_ARRAY_NORMAL;
100 }
101
102
103 static void
104 reset_color( GLcontext *ctx )
105 {
106 ACcontext *ac = AC_CONTEXT(ctx);
107
108 if (ctx->Array.Color.Enabled) {
109 ac->Raw.Color = ctx->Array.Color;
110 STRIDE_ARRAY(ac->Raw.Color, ac->start);
111 }
112 else
113 ac->Raw.Color = ac->Fallback.Color;
114
115 ac->IsCached.Color = GL_FALSE;
116 ac->NewArrayState &= ~_NEW_ARRAY_COLOR0;
117 }
118
119
120 static void
121 reset_secondarycolor( GLcontext *ctx )
122 {
123 ACcontext *ac = AC_CONTEXT(ctx);
124
125 if (ctx->Array.SecondaryColor.Enabled) {
126 ac->Raw.SecondaryColor = ctx->Array.SecondaryColor;
127 STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start);
128 }
129 else
130 ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
131
132 ac->IsCached.SecondaryColor = GL_FALSE;
133 ac->NewArrayState &= ~_NEW_ARRAY_COLOR1;
134 }
135
136
137 static void
138 reset_index( GLcontext *ctx )
139 {
140 ACcontext *ac = AC_CONTEXT(ctx);
141
142 if (ctx->Array.Index.Enabled) {
143 ac->Raw.Index = ctx->Array.Index;
144 STRIDE_ARRAY(ac->Raw.Index, ac->start);
145 }
146 else
147 ac->Raw.Index = ac->Fallback.Index;
148
149 ac->IsCached.Index = GL_FALSE;
150 ac->NewArrayState &= ~_NEW_ARRAY_INDEX;
151 }
152
153
154 static void
155 reset_fogcoord( GLcontext *ctx )
156 {
157 ACcontext *ac = AC_CONTEXT(ctx);
158
159 if (ctx->Array.FogCoord.Enabled) {
160 ac->Raw.FogCoord = ctx->Array.FogCoord;
161 STRIDE_ARRAY(ac->Raw.FogCoord, ac->start);
162 }
163 else
164 ac->Raw.FogCoord = ac->Fallback.FogCoord;
165
166 ac->IsCached.FogCoord = GL_FALSE;
167 ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD;
168 }
169
170
171 static void
172 reset_edgeflag( GLcontext *ctx )
173 {
174 ACcontext *ac = AC_CONTEXT(ctx);
175
176 if (ctx->Array.EdgeFlag.Enabled) {
177 ac->Raw.EdgeFlag = ctx->Array.EdgeFlag;
178 STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start);
179 }
180 else
181 ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
182
183 ac->IsCached.EdgeFlag = GL_FALSE;
184 ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG;
185 }
186
187
188 static void
189 reset_attrib( GLcontext *ctx, GLuint index )
190 {
191 ACcontext *ac = AC_CONTEXT(ctx);
192
193 if (ctx->Array.VertexAttrib[index].Enabled) {
194 ac->Raw.Attrib[index] = ctx->Array.VertexAttrib[index];
195 STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
196 }
197 else
198 ac->Raw.Attrib[index] = ac->Fallback.Attrib[index];
199
200 ac->IsCached.Attrib[index] = GL_FALSE;
201 ac->NewArrayState &= ~_NEW_ARRAY_ATTRIB(index);
202 }
203
204
205 /**
206 * Generic import function for color data
207 */
208 static void
209 import( const GLcontext *ctx,
210 GLenum destType,
211 struct gl_client_array *to,
212 const struct gl_client_array *from )
213 {
214 const ACcontext *ac = AC_CONTEXT(ctx);
215
216 if (destType == 0)
217 destType = from->Type;
218
219 switch (destType) {
220 case GL_FLOAT:
221 _math_trans_4fc( (GLfloat (*)[4]) to->Ptr,
222 from->Ptr,
223 from->StrideB,
224 from->Type,
225 from->Size,
226 0,
227 ac->count - ac->start);
228
229 to->StrideB = 4 * sizeof(GLfloat);
230 to->Type = GL_FLOAT;
231 break;
232
233 case GL_UNSIGNED_BYTE:
234 _math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
235 from->Ptr,
236 from->StrideB,
237 from->Type,
238 from->Size,
239 0,
240 ac->count - ac->start);
241
242 to->StrideB = 4 * sizeof(GLubyte);
243 to->Type = GL_UNSIGNED_BYTE;
244 break;
245
246 case GL_UNSIGNED_SHORT:
247 _math_trans_4us( (GLushort (*)[4]) to->Ptr,
248 from->Ptr,
249 from->StrideB,
250 from->Type,
251 from->Size,
252 0,
253 ac->count - ac->start);
254
255 to->StrideB = 4 * sizeof(GLushort);
256 to->Type = GL_UNSIGNED_SHORT;
257 break;
258
259 default:
260 _mesa_problem(ctx, "Unexpected dest format in import()");
261 break;
262 }
263 }
264
265
266
267 /*
268 * Functions to import array ranges with specified types and strides.
269 * For example, if the vertex data is GLshort[2] and we want GLfloat[3]
270 * we'll use an import function to do the data conversion.
271 */
272
273 static void
274 import_texcoord( GLcontext *ctx, GLuint unit, GLenum type, GLuint stride )
275 {
276 ACcontext *ac = AC_CONTEXT(ctx);
277 const struct gl_client_array *from = &ac->Raw.TexCoord[unit];
278 struct gl_client_array *to = &ac->Cache.TexCoord[unit];
279 (void) type; (void) stride;
280
281 ASSERT(unit < ctx->Const.MaxTextureCoordUnits);
282
283 /* Limited choices at this stage:
284 */
285 ASSERT(type == GL_FLOAT);
286 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
287 ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
288
289 _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
290 from->Ptr,
291 from->StrideB,
292 from->Type,
293 from->Size,
294 0,
295 ac->count - ac->start);
296
297 to->Size = from->Size;
298 to->StrideB = 4 * sizeof(GLfloat);
299 to->Type = GL_FLOAT;
300 ac->IsCached.TexCoord[unit] = GL_TRUE;
301 }
302
303 static void
304 import_vertex( GLcontext *ctx, GLenum type, GLuint stride )
305 {
306 ACcontext *ac = AC_CONTEXT(ctx);
307 const struct gl_client_array *from = &ac->Raw.Vertex;
308 struct gl_client_array *to = &ac->Cache.Vertex;
309 (void) type; (void) stride;
310
311 /* Limited choices at this stage:
312 */
313 ASSERT(type == GL_FLOAT);
314 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
315
316 _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
317 from->Ptr,
318 from->StrideB,
319 from->Type,
320 from->Size,
321 0,
322 ac->count - ac->start);
323
324 to->Size = from->Size;
325 to->StrideB = 4 * sizeof(GLfloat);
326 to->Type = GL_FLOAT;
327 ac->IsCached.Vertex = GL_TRUE;
328 }
329
330 static void
331 import_normal( GLcontext *ctx, GLenum type, GLuint stride )
332 {
333 ACcontext *ac = AC_CONTEXT(ctx);
334 const struct gl_client_array *from = &ac->Raw.Normal;
335 struct gl_client_array *to = &ac->Cache.Normal;
336 (void) type; (void) stride;
337
338 /* Limited choices at this stage:
339 */
340 ASSERT(type == GL_FLOAT);
341 ASSERT(stride == 3*sizeof(GLfloat) || stride == 0);
342
343 _math_trans_3f( (GLfloat (*)[3]) to->Ptr,
344 from->Ptr,
345 from->StrideB,
346 from->Type,
347 0,
348 ac->count - ac->start);
349
350 to->StrideB = 3 * sizeof(GLfloat);
351 to->Type = GL_FLOAT;
352 ac->IsCached.Normal = GL_TRUE;
353 }
354
355 static void
356 import_color( GLcontext *ctx, GLenum type, GLuint stride )
357 {
358 ACcontext *ac = AC_CONTEXT(ctx);
359 const struct gl_client_array *from = &ac->Raw.Color;
360 struct gl_client_array *to = &ac->Cache.Color;
361 (void) stride;
362
363 import( ctx, type, to, from );
364
365 ac->IsCached.Color = GL_TRUE;
366 }
367
368 static void
369 import_index( GLcontext *ctx, GLenum type, GLuint stride )
370 {
371 ACcontext *ac = AC_CONTEXT(ctx);
372 const struct gl_client_array *from = &ac->Raw.Index;
373 struct gl_client_array *to = &ac->Cache.Index;
374 (void) type; (void) stride;
375
376 /* Limited choices at this stage:
377 */
378 ASSERT(type == GL_UNSIGNED_INT);
379 ASSERT(stride == sizeof(GLuint) || stride == 0);
380
381 _math_trans_1ui( (GLuint *) to->Ptr,
382 from->Ptr,
383 from->StrideB,
384 from->Type,
385 0,
386 ac->count - ac->start);
387
388 to->StrideB = sizeof(GLuint);
389 to->Type = GL_UNSIGNED_INT;
390 ac->IsCached.Index = GL_TRUE;
391 }
392
393 static void
394 import_secondarycolor( GLcontext *ctx, GLenum type, GLuint stride )
395 {
396 ACcontext *ac = AC_CONTEXT(ctx);
397 const struct gl_client_array *from = &ac->Raw.SecondaryColor;
398 struct gl_client_array *to = &ac->Cache.SecondaryColor;
399 (void) stride;
400
401 import( ctx, type, to, from );
402
403 ac->IsCached.SecondaryColor = GL_TRUE;
404 }
405
406 static void
407 import_fogcoord( GLcontext *ctx, GLenum type, GLuint stride )
408 {
409 ACcontext *ac = AC_CONTEXT(ctx);
410 const struct gl_client_array *from = &ac->Raw.FogCoord;
411 struct gl_client_array *to = &ac->Cache.FogCoord;
412 (void) type; (void) stride;
413
414 /* Limited choices at this stage:
415 */
416 ASSERT(type == GL_FLOAT);
417 ASSERT(stride == sizeof(GLfloat) || stride == 0);
418
419 _math_trans_1f( (GLfloat *) to->Ptr,
420 from->Ptr,
421 from->StrideB,
422 from->Type,
423 0,
424 ac->count - ac->start);
425
426 to->StrideB = sizeof(GLfloat);
427 to->Type = GL_FLOAT;
428 ac->IsCached.FogCoord = GL_TRUE;
429 }
430
431 static void
432 import_edgeflag( GLcontext *ctx, GLenum type, GLuint stride )
433 {
434 ACcontext *ac = AC_CONTEXT(ctx);
435 const struct gl_client_array *from = &ac->Raw.EdgeFlag;
436 struct gl_client_array *to = &ac->Cache.EdgeFlag;
437 (void) type; (void) stride;
438
439 /* Limited choices at this stage:
440 */
441 ASSERT(type == GL_UNSIGNED_BYTE);
442 ASSERT(stride == sizeof(GLubyte) || stride == 0);
443
444 _math_trans_1ub( (GLubyte *) to->Ptr,
445 from->Ptr,
446 from->StrideB,
447 from->Type,
448 0,
449 ac->count - ac->start);
450
451 to->StrideB = sizeof(GLubyte);
452 to->Type = GL_UNSIGNED_BYTE;
453 ac->IsCached.EdgeFlag = GL_TRUE;
454 }
455
456 static void
457 import_attrib( GLcontext *ctx, GLuint index, GLenum type, GLuint stride )
458 {
459 ACcontext *ac = AC_CONTEXT(ctx);
460 const struct gl_client_array *from = &ac->Raw.Attrib[index];
461 struct gl_client_array *to = &ac->Cache.Attrib[index];
462 (void) type; (void) stride;
463
464 ASSERT(index < MAX_VERTEX_PROGRAM_ATTRIBS);
465
466 /* Limited choices at this stage:
467 */
468 ASSERT(type == GL_FLOAT);
469 ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
470 ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
471
472 _math_trans_4f( (GLfloat (*)[4]) to->Ptr,
473 from->Ptr,
474 from->StrideB,
475 from->Type,
476 from->Size,
477 0,
478 ac->count - ac->start);
479
480 to->Size = from->Size;
481 to->StrideB = 4 * sizeof(GLfloat);
482 to->Type = GL_FLOAT;
483 ac->IsCached.Attrib[index] = GL_TRUE;
484 }
485
486
487
488 /*
489 * Externals to request arrays with specific properties:
490 */
491
492
493 struct gl_client_array *
494 _ac_import_texcoord( GLcontext *ctx,
495 GLuint unit,
496 GLenum type,
497 GLuint reqstride,
498 GLuint reqsize,
499 GLboolean reqwriteable,
500 GLboolean *writeable )
501 {
502 ACcontext *ac = AC_CONTEXT(ctx);
503
504 ASSERT(unit < ctx->Const.MaxTextureCoordUnits);
505
506 /* Can we keep the existing version?
507 */
508 if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit))
509 reset_texcoord( ctx, unit );
510
511 /* Is the request impossible?
512 */
513 if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize)
514 return NULL;
515
516 /* Do we need to pull in a copy of the client data:
517 */
518 if (ac->Raw.TexCoord[unit].Type != type ||
519 (reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) ||
520 reqwriteable)
521 {
522 if (!ac->IsCached.TexCoord[unit])
523 import_texcoord(ctx, unit, type, reqstride );
524 *writeable = GL_TRUE;
525 return &ac->Cache.TexCoord[unit];
526 }
527 else {
528 *writeable = GL_FALSE;
529 return &ac->Raw.TexCoord[unit];
530 }
531 }
532
533 struct gl_client_array *
534 _ac_import_vertex( GLcontext *ctx,
535 GLenum type,
536 GLuint reqstride,
537 GLuint reqsize,
538 GLboolean reqwriteable,
539 GLboolean *writeable )
540 {
541 ACcontext *ac = AC_CONTEXT(ctx);
542
543 /* Can we keep the existing version?
544 */
545 if (ac->NewArrayState & _NEW_ARRAY_VERTEX)
546 reset_vertex( ctx );
547
548 /* Is the request impossible?
549 */
550 if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize)
551 return NULL;
552
553 /* Do we need to pull in a copy of the client data:
554 */
555 if (ac->Raw.Vertex.Type != type ||
556 (reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) ||
557 reqwriteable)
558 {
559 if (!ac->IsCached.Vertex)
560 import_vertex(ctx, type, reqstride );
561 *writeable = GL_TRUE;
562 return &ac->Cache.Vertex;
563 }
564 else {
565 *writeable = GL_FALSE;
566 return &ac->Raw.Vertex;
567 }
568 }
569
570 struct gl_client_array *
571 _ac_import_normal( GLcontext *ctx,
572 GLenum type,
573 GLuint reqstride,
574 GLboolean reqwriteable,
575 GLboolean *writeable )
576 {
577 ACcontext *ac = AC_CONTEXT(ctx);
578
579 /* Can we keep the existing version?
580 */
581 if (ac->NewArrayState & _NEW_ARRAY_NORMAL)
582 reset_normal( ctx );
583
584 /* Do we need to pull in a copy of the client data:
585 */
586 if (ac->Raw.Normal.Type != type ||
587 (reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) ||
588 reqwriteable)
589 {
590 if (!ac->IsCached.Normal)
591 import_normal(ctx, type, reqstride );
592 *writeable = GL_TRUE;
593 return &ac->Cache.Normal;
594 }
595 else {
596 *writeable = GL_FALSE;
597 return &ac->Raw.Normal;
598 }
599 }
600
601 struct gl_client_array *
602 _ac_import_color( GLcontext *ctx,
603 GLenum type,
604 GLuint reqstride,
605 GLuint reqsize,
606 GLboolean reqwriteable,
607 GLboolean *writeable )
608 {
609 ACcontext *ac = AC_CONTEXT(ctx);
610
611 /* Can we keep the existing version?
612 */
613 if (ac->NewArrayState & _NEW_ARRAY_COLOR0)
614 reset_color( ctx );
615
616 /* Is the request impossible?
617 */
618 if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) {
619 return NULL;
620 }
621
622 /* Do we need to pull in a copy of the client data:
623 */
624 if ((type != 0 && ac->Raw.Color.Type != type) ||
625 (reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) ||
626 reqwriteable)
627 {
628 if (!ac->IsCached.Color) {
629 import_color(ctx, type, reqstride );
630 }
631 *writeable = GL_TRUE;
632 return &ac->Cache.Color;
633 }
634 else {
635 *writeable = GL_FALSE;
636 return &ac->Raw.Color;
637 }
638 }
639
640 struct gl_client_array *
641 _ac_import_index( GLcontext *ctx,
642 GLenum type,
643 GLuint reqstride,
644 GLboolean reqwriteable,
645 GLboolean *writeable )
646 {
647 ACcontext *ac = AC_CONTEXT(ctx);
648
649 /* Can we keep the existing version?
650 */
651 if (ac->NewArrayState & _NEW_ARRAY_INDEX)
652 reset_index( ctx );
653
654
655 /* Do we need to pull in a copy of the client data:
656 */
657 if (ac->Raw.Index.Type != type ||
658 (reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) ||
659 reqwriteable)
660 {
661 if (!ac->IsCached.Index)
662 import_index(ctx, type, reqstride );
663 *writeable = GL_TRUE;
664 return &ac->Cache.Index;
665 }
666 else {
667 *writeable = GL_FALSE;
668 return &ac->Raw.Index;
669 }
670 }
671
672 struct gl_client_array *
673 _ac_import_secondarycolor( GLcontext *ctx,
674 GLenum type,
675 GLuint reqstride,
676 GLuint reqsize,
677 GLboolean reqwriteable,
678 GLboolean *writeable )
679 {
680 ACcontext *ac = AC_CONTEXT(ctx);
681
682 /* Can we keep the existing version?
683 */
684 if (ac->NewArrayState & _NEW_ARRAY_COLOR1)
685 reset_secondarycolor( ctx );
686
687 /* Is the request impossible?
688 */
689 if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize)
690 return NULL;
691
692 /* Do we need to pull in a copy of the client data:
693 */
694 if ((type != 0 && ac->Raw.SecondaryColor.Type != type) ||
695 (reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) ||
696 reqwriteable)
697 {
698 if (!ac->IsCached.SecondaryColor)
699 import_secondarycolor(ctx, type, reqstride );
700 *writeable = GL_TRUE;
701 return &ac->Cache.SecondaryColor;
702 }
703 else {
704 *writeable = GL_FALSE;
705 return &ac->Raw.SecondaryColor;
706 }
707 }
708
709 struct gl_client_array *
710 _ac_import_fogcoord( GLcontext *ctx,
711 GLenum type,
712 GLuint reqstride,
713 GLboolean reqwriteable,
714 GLboolean *writeable )
715 {
716 ACcontext *ac = AC_CONTEXT(ctx);
717
718 /* Can we keep the existing version?
719 */
720 if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD)
721 reset_fogcoord( ctx );
722
723 /* Do we need to pull in a copy of the client data:
724 */
725 if (ac->Raw.FogCoord.Type != type ||
726 (reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) ||
727 reqwriteable)
728 {
729 if (!ac->IsCached.FogCoord)
730 import_fogcoord(ctx, type, reqstride );
731 *writeable = GL_TRUE;
732 return &ac->Cache.FogCoord;
733 }
734 else {
735 *writeable = GL_FALSE;
736 return &ac->Raw.FogCoord;
737 }
738 }
739
740 struct gl_client_array *
741 _ac_import_edgeflag( GLcontext *ctx,
742 GLenum type,
743 GLuint reqstride,
744 GLboolean reqwriteable,
745 GLboolean *writeable )
746 {
747 ACcontext *ac = AC_CONTEXT(ctx);
748
749 /* Can we keep the existing version?
750 */
751 if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG)
752 reset_edgeflag( ctx );
753
754 /* Do we need to pull in a copy of the client data:
755 */
756 if (ac->Raw.EdgeFlag.Type != type ||
757 (reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) ||
758 reqwriteable)
759 {
760 if (!ac->IsCached.EdgeFlag)
761 import_edgeflag(ctx, type, reqstride );
762 *writeable = GL_TRUE;
763 return &ac->Cache.EdgeFlag;
764 }
765 else {
766 *writeable = GL_FALSE;
767 return &ac->Raw.EdgeFlag;
768 }
769 }
770
771 /* GL_NV_vertex_program */
772 struct gl_client_array *
773 _ac_import_attrib( GLcontext *ctx,
774 GLuint index,
775 GLenum type,
776 GLuint reqstride,
777 GLuint reqsize,
778 GLboolean reqwriteable,
779 GLboolean *writeable )
780 {
781 ACcontext *ac = AC_CONTEXT(ctx);
782
783 ASSERT(index < VERT_ATTRIB_MAX);
784
785 /* Can we keep the existing version?
786 */
787 if (ac->NewArrayState & _NEW_ARRAY_ATTRIB(index))
788 reset_attrib( ctx, index );
789
790 /* Is the request impossible?
791 */
792 if (reqsize != 0 && ac->Raw.Attrib[index].Size > (GLint) reqsize)
793 return NULL;
794
795 /* Do we need to pull in a copy of the client data:
796 */
797 if (ac->Raw.Attrib[index].Type != type ||
798 (reqstride != 0 && ac->Raw.Attrib[index].StrideB != (GLint)reqstride) ||
799 reqwriteable)
800 {
801 if (!ac->IsCached.Attrib[index])
802 import_attrib(ctx, index, type, reqstride );
803 *writeable = GL_TRUE;
804 return &ac->Cache.Attrib[index];
805 }
806 else {
807 *writeable = GL_FALSE;
808 return &ac->Raw.Attrib[index];
809 }
810 }
811
812
813 /* Clients must call this function to validate state and set bounds
814 * before importing any data:
815 */
816 void
817 _ac_import_range( GLcontext *ctx, GLuint start, GLuint count )
818 {
819 ACcontext *ac = AC_CONTEXT(ctx);
820
821 if (!ctx->Array.LockCount) {
822 /* Not locked, discard cached data. Changes to lock
823 * status are caught via. _ac_invalidate_state().
824 */
825 ac->NewArrayState = _NEW_ARRAY_ALL;
826 ac->start = start;
827 ac->count = count;
828 }
829 else {
830 /* Locked, discard data for any disabled arrays. Require that
831 * the whole locked range always be dealt with, otherwise hard to
832 * maintain cached data in the face of clipping.
833 */
834 ac->NewArrayState |= ~ctx->Array._Enabled;
835 ac->start = ctx->Array.LockFirst;
836 ac->count = ctx->Array.LockCount;
837 ASSERT(ac->start == start); /* hmm? */
838 ASSERT(ac->count == count);
839 }
840 }
841
842
843
844 /* Additional convienence function for importing the element list
845 * for glDrawElements() and glDrawRangeElements().
846 */
847 CONST void *
848 _ac_import_elements( GLcontext *ctx,
849 GLenum new_type,
850 GLuint count,
851 GLenum old_type,
852 CONST void *indices )
853 {
854 ACcontext *ac = AC_CONTEXT(ctx);
855
856 if (old_type == new_type)
857 return indices;
858
859 if (ac->elt_size < count * sizeof(GLuint)) {
860 if (ac->Elts) FREE(ac->Elts);
861 while (ac->elt_size < count * sizeof(GLuint))
862 ac->elt_size *= 2;
863 ac->Elts = (GLuint *) MALLOC(ac->elt_size);
864 }
865
866 switch (new_type) {
867 case GL_UNSIGNED_BYTE:
868 ASSERT(0);
869 return NULL;
870 case GL_UNSIGNED_SHORT:
871 ASSERT(0);
872 return NULL;
873 case GL_UNSIGNED_INT: {
874 GLuint *out = (GLuint *)ac->Elts;
875 GLuint i;
876
877 switch (old_type) {
878 case GL_UNSIGNED_BYTE: {
879 CONST GLubyte *in = (CONST GLubyte *)indices;
880 for (i = 0 ; i < count ; i++)
881 out[i] = in[i];
882 break;
883 }
884 case GL_UNSIGNED_SHORT: {
885 CONST GLushort *in = (CONST GLushort *)indices;
886 for (i = 0 ; i < count ; i++)
887 out[i] = in[i];
888 break;
889 }
890 default:
891 ASSERT(0);
892 }
893
894 return (CONST void *)out;
895 }
896 default:
897 ASSERT(0);
898 break;
899 }
900
901 return NULL;
902 }