1 /* $Id: ac_import.c,v 1.22 2003/01/14 04:55:46 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Keith Whitwell <keith@tungstengraphics.com>
36 #include "math/m_translate.h"
37 #include "array_cache/ac_context.h"
38 #include "math/m_translate.h"
40 #define STRIDE_ARRAY( array, offset ) \
42 char *tmp = (char *) (array).Ptr; \
43 tmp += (offset) * (array).StrideB; \
47 /* Set the array pointer back to its source when the cached data is
51 static void reset_texcoord( GLcontext
*ctx
, GLuint unit
)
53 ACcontext
*ac
= AC_CONTEXT(ctx
);
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
);
60 ac
->Raw
.TexCoord
[unit
] = ac
->Fallback
.TexCoord
[unit
];
62 if (ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+ unit
][3] != 1.0)
63 ac
->Raw
.TexCoord
[unit
].Size
= 4;
64 else if (ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+ unit
][2] != 0.0)
65 ac
->Raw
.TexCoord
[unit
].Size
= 3;
67 ac
->Raw
.TexCoord
[unit
].Size
= 2;
70 ac
->IsCached
.TexCoord
[unit
] = GL_FALSE
;
71 ac
->NewArrayState
&= ~_NEW_ARRAY_TEXCOORD(unit
);
74 static void reset_vertex( GLcontext
*ctx
)
76 ACcontext
*ac
= AC_CONTEXT(ctx
);
77 ASSERT(ctx
->Array
.Vertex
.Enabled
78 || (ctx
->VertexProgram
.Enabled
&& ctx
->Array
.VertexAttrib
[0].Enabled
));
79 ac
->Raw
.Vertex
= ctx
->Array
.Vertex
;
80 STRIDE_ARRAY(ac
->Raw
.Vertex
, ac
->start
);
81 ac
->IsCached
.Vertex
= GL_FALSE
;
82 ac
->NewArrayState
&= ~_NEW_ARRAY_VERTEX
;
86 static void reset_normal( GLcontext
*ctx
)
88 ACcontext
*ac
= AC_CONTEXT(ctx
);
90 if (ctx
->Array
._Enabled
& _NEW_ARRAY_NORMAL
) {
91 ac
->Raw
.Normal
= ctx
->Array
.Normal
;
92 STRIDE_ARRAY(ac
->Raw
.Normal
, ac
->start
);
95 ac
->Raw
.Normal
= ac
->Fallback
.Normal
;
98 ac
->IsCached
.Normal
= GL_FALSE
;
99 ac
->NewArrayState
&= ~_NEW_ARRAY_NORMAL
;
103 static void reset_color( GLcontext
*ctx
)
105 ACcontext
*ac
= AC_CONTEXT(ctx
);
108 if (ctx
->Array
._Enabled
& _NEW_ARRAY_COLOR0
) {
109 ac
->Raw
.Color
= ctx
->Array
.Color
;
110 STRIDE_ARRAY(ac
->Raw
.Color
, ac
->start
);
113 ac
->Raw
.Color
= ac
->Fallback
.Color
;
115 ac
->IsCached
.Color
= GL_FALSE
;
116 ac
->NewArrayState
&= ~_NEW_ARRAY_COLOR0
;
120 static void reset_secondarycolor( GLcontext
*ctx
)
122 ACcontext
*ac
= AC_CONTEXT(ctx
);
124 if (ctx
->Array
._Enabled
& _NEW_ARRAY_COLOR1
) {
125 ac
->Raw
.SecondaryColor
= ctx
->Array
.SecondaryColor
;
126 STRIDE_ARRAY(ac
->Raw
.SecondaryColor
, ac
->start
);
129 ac
->Raw
.SecondaryColor
= ac
->Fallback
.SecondaryColor
;
131 ac
->IsCached
.SecondaryColor
= GL_FALSE
;
132 ac
->NewArrayState
&= ~_NEW_ARRAY_COLOR1
;
136 static void reset_index( GLcontext
*ctx
)
138 ACcontext
*ac
= AC_CONTEXT(ctx
);
140 if (ctx
->Array
._Enabled
& _NEW_ARRAY_INDEX
) {
141 ac
->Raw
.Index
= ctx
->Array
.Index
;
142 STRIDE_ARRAY(ac
->Raw
.Index
, ac
->start
);
145 ac
->Raw
.Index
= ac
->Fallback
.Index
;
147 ac
->IsCached
.Index
= GL_FALSE
;
148 ac
->NewArrayState
&= ~_NEW_ARRAY_INDEX
;
152 static void reset_fogcoord( GLcontext
*ctx
)
154 ACcontext
*ac
= AC_CONTEXT(ctx
);
156 if (ctx
->Array
._Enabled
& _NEW_ARRAY_FOGCOORD
) {
157 ac
->Raw
.FogCoord
= ctx
->Array
.FogCoord
;
158 STRIDE_ARRAY(ac
->Raw
.FogCoord
, ac
->start
);
161 ac
->Raw
.FogCoord
= ac
->Fallback
.FogCoord
;
163 ac
->IsCached
.FogCoord
= GL_FALSE
;
164 ac
->NewArrayState
&= ~_NEW_ARRAY_FOGCOORD
;
168 static void reset_edgeflag( GLcontext
*ctx
)
170 ACcontext
*ac
= AC_CONTEXT(ctx
);
172 if (ctx
->Array
._Enabled
& _NEW_ARRAY_EDGEFLAG
) {
173 ac
->Raw
.EdgeFlag
= ctx
->Array
.EdgeFlag
;
174 STRIDE_ARRAY(ac
->Raw
.EdgeFlag
, ac
->start
);
177 ac
->Raw
.EdgeFlag
= ac
->Fallback
.EdgeFlag
;
179 ac
->IsCached
.EdgeFlag
= GL_FALSE
;
180 ac
->NewArrayState
&= ~_NEW_ARRAY_EDGEFLAG
;
184 static void reset_attrib( GLcontext
*ctx
, GLuint index
)
186 ACcontext
*ac
= AC_CONTEXT(ctx
);
187 GLboolean fallback
= GL_FALSE
;
190 * The 16 NV vertex attribute arrays have top priority. If one of those
191 * is not enabled, look if a corresponding conventional array is enabled.
192 * If nothing else, use the fallback (ctx->Current.Attrib) values.
194 if (ctx
->Array
._Enabled
& _NEW_ARRAY_ATTRIB(index
)) {
195 ac
->Raw
.Attrib
[index
] = ctx
->Array
.VertexAttrib
[index
];
196 STRIDE_ARRAY(ac
->Raw
.Attrib
[index
], ac
->start
);
198 else if (ctx
->Array
._Enabled
& (1 << index
)) {
199 /* use conventional vertex array if possible */
200 if (index
== VERT_ATTRIB_POS
) {
201 ac
->Raw
.Attrib
[index
] = ctx
->Array
.Vertex
;
203 else if (index
== VERT_ATTRIB_NORMAL
) {
204 ac
->Raw
.Attrib
[index
] = ctx
->Array
.Normal
;
206 else if (index
== VERT_ATTRIB_COLOR0
) {
207 ac
->Raw
.Attrib
[index
] = ctx
->Array
.Color
;
209 else if (index
== VERT_ATTRIB_COLOR1
) {
210 ac
->Raw
.Attrib
[index
] = ctx
->Array
.SecondaryColor
;
212 else if (index
== VERT_ATTRIB_FOG
) {
213 ac
->Raw
.Attrib
[index
] = ctx
->Array
.FogCoord
;
215 else if (index
>= VERT_ATTRIB_TEX0
&& index
<= VERT_ATTRIB_TEX7
) {
216 GLuint unit
= index
- VERT_ATTRIB_TEX0
;
217 ASSERT(unit
< MAX_TEXTURE_COORD_UNITS
);
218 ac
->Raw
.Attrib
[index
] = ctx
->Array
.TexCoord
[unit
];
221 /* missing conventional array (vertex weight, for example) */
225 STRIDE_ARRAY(ac
->Raw
.Attrib
[index
], ac
->start
);
232 /* fallback to ctx->Current.Attrib values */
233 ac
->Raw
.Attrib
[index
] = ac
->Fallback
.Attrib
[index
];
235 if (ctx
->Current
.Attrib
[index
][3] != 1.0)
236 ac
->Raw
.Attrib
[index
].Size
= 4;
237 else if (ctx
->Current
.Attrib
[index
][2] != 0.0)
238 ac
->Raw
.Attrib
[index
].Size
= 3;
240 ac
->Raw
.Attrib
[index
].Size
= 2;
243 ac
->IsCached
.Attrib
[index
] = GL_FALSE
;
244 ac
->NewArrayState
&= ~_NEW_ARRAY_ATTRIB(index
);
249 * Generic import function for color data
251 static void import( GLcontext
*ctx
,
253 struct gl_client_array
*to
,
254 struct gl_client_array
*from
)
256 ACcontext
*ac
= AC_CONTEXT(ctx
);
263 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
269 ac
->count
- ac
->start
);
271 to
->StrideB
= 4 * sizeof(GLfloat
);
275 case GL_UNSIGNED_BYTE
:
276 _math_trans_4ub( (GLubyte (*)[4]) to
->Ptr
,
282 ac
->count
- ac
->start
);
284 to
->StrideB
= 4 * sizeof(GLubyte
);
285 to
->Type
= GL_UNSIGNED_BYTE
;
288 case GL_UNSIGNED_SHORT
:
289 _math_trans_4us( (GLushort (*)[4]) to
->Ptr
,
295 ac
->count
- ac
->start
);
297 to
->StrideB
= 4 * sizeof(GLushort
);
298 to
->Type
= GL_UNSIGNED_SHORT
;
310 * Functions to import array ranges with specified types and strides.
311 * For example, if the vertex data is GLshort[2] and we want GLfloat[3]
312 * we'll use an import function to do the data conversion.
315 static void import_texcoord( GLcontext
*ctx
, GLuint unit
,
316 GLenum type
, GLuint stride
)
318 ACcontext
*ac
= AC_CONTEXT(ctx
);
319 struct gl_client_array
*from
= &ac
->Raw
.TexCoord
[unit
];
320 struct gl_client_array
*to
= &ac
->Cache
.TexCoord
[unit
];
322 ASSERT(unit
< ctx
->Const
.MaxTextureUnits
);
324 /* Limited choices at this stage:
326 ASSERT(type
== GL_FLOAT
);
327 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
328 ASSERT(ac
->count
- ac
->start
< ctx
->Const
.MaxArrayLockSize
);
330 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
336 ac
->count
- ac
->start
);
338 to
->Size
= from
->Size
;
339 to
->StrideB
= 4 * sizeof(GLfloat
);
341 ac
->IsCached
.TexCoord
[unit
] = GL_TRUE
;
344 static void import_vertex( GLcontext
*ctx
,
345 GLenum type
, GLuint stride
)
347 ACcontext
*ac
= AC_CONTEXT(ctx
);
348 struct gl_client_array
*from
= &ac
->Raw
.Vertex
;
349 struct gl_client_array
*to
= &ac
->Cache
.Vertex
;
351 /* Limited choices at this stage:
353 ASSERT(type
== GL_FLOAT
);
354 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
356 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
362 ac
->count
- ac
->start
);
364 to
->Size
= from
->Size
;
365 to
->StrideB
= 4 * sizeof(GLfloat
);
367 ac
->IsCached
.Vertex
= GL_TRUE
;
370 static void import_normal( GLcontext
*ctx
,
371 GLenum type
, GLuint stride
)
373 ACcontext
*ac
= AC_CONTEXT(ctx
);
374 struct gl_client_array
*from
= &ac
->Raw
.Normal
;
375 struct gl_client_array
*to
= &ac
->Cache
.Normal
;
377 /* Limited choices at this stage:
379 ASSERT(type
== GL_FLOAT
);
380 ASSERT(stride
== 3*sizeof(GLfloat
) || stride
== 0);
382 _math_trans_3f( (GLfloat (*)[3]) to
->Ptr
,
387 ac
->count
- ac
->start
);
389 to
->StrideB
= 3 * sizeof(GLfloat
);
391 ac
->IsCached
.Normal
= GL_TRUE
;
394 static void import_color( GLcontext
*ctx
,
395 GLenum type
, GLuint stride
)
397 ACcontext
*ac
= AC_CONTEXT(ctx
);
398 struct gl_client_array
*from
= &ac
->Raw
.Color
;
399 struct gl_client_array
*to
= &ac
->Cache
.Color
;
401 import( ctx
, type
, to
, from
);
403 ac
->IsCached
.Color
= GL_TRUE
;
406 static void import_index( GLcontext
*ctx
,
407 GLenum type
, GLuint stride
)
409 ACcontext
*ac
= AC_CONTEXT(ctx
);
410 struct gl_client_array
*from
= &ac
->Raw
.Index
;
411 struct gl_client_array
*to
= &ac
->Cache
.Index
;
413 /* Limited choices at this stage:
415 ASSERT(type
== GL_UNSIGNED_INT
);
416 ASSERT(stride
== sizeof(GLuint
) || stride
== 0);
418 _math_trans_1ui( (GLuint
*) to
->Ptr
,
423 ac
->count
- ac
->start
);
425 to
->StrideB
= sizeof(GLuint
);
426 to
->Type
= GL_UNSIGNED_INT
;
427 ac
->IsCached
.Index
= GL_TRUE
;
430 static void import_secondarycolor( GLcontext
*ctx
,
431 GLenum type
, GLuint stride
)
433 ACcontext
*ac
= AC_CONTEXT(ctx
);
434 struct gl_client_array
*from
= &ac
->Raw
.SecondaryColor
;
435 struct gl_client_array
*to
= &ac
->Cache
.SecondaryColor
;
437 import( ctx
, type
, to
, from
);
439 ac
->IsCached
.SecondaryColor
= GL_TRUE
;
442 static void import_fogcoord( GLcontext
*ctx
,
443 GLenum type
, GLuint stride
)
445 ACcontext
*ac
= AC_CONTEXT(ctx
);
446 struct gl_client_array
*from
= &ac
->Raw
.FogCoord
;
447 struct gl_client_array
*to
= &ac
->Cache
.FogCoord
;
449 /* Limited choices at this stage:
451 ASSERT(type
== GL_FLOAT
);
452 ASSERT(stride
== sizeof(GLfloat
) || stride
== 0);
454 _math_trans_1f( (GLfloat
*) to
->Ptr
,
459 ac
->count
- ac
->start
);
461 to
->StrideB
= sizeof(GLfloat
);
463 ac
->IsCached
.FogCoord
= GL_TRUE
;
466 static void import_edgeflag( GLcontext
*ctx
,
467 GLenum type
, GLuint stride
)
469 ACcontext
*ac
= AC_CONTEXT(ctx
);
470 struct gl_client_array
*from
= &ac
->Raw
.EdgeFlag
;
471 struct gl_client_array
*to
= &ac
->Cache
.EdgeFlag
;
473 /* Limited choices at this stage:
475 ASSERT(type
== GL_UNSIGNED_BYTE
);
476 ASSERT(stride
== sizeof(GLubyte
) || stride
== 0);
478 _math_trans_1ub( (GLubyte
*) to
->Ptr
,
483 ac
->count
- ac
->start
);
485 to
->StrideB
= sizeof(GLubyte
);
486 to
->Type
= GL_UNSIGNED_BYTE
;
487 ac
->IsCached
.EdgeFlag
= GL_TRUE
;
490 static void import_attrib( GLcontext
*ctx
, GLuint index
,
491 GLenum type
, GLuint stride
)
493 ACcontext
*ac
= AC_CONTEXT(ctx
);
494 struct gl_client_array
*from
= &ac
->Raw
.Attrib
[index
];
495 struct gl_client_array
*to
= &ac
->Cache
.Attrib
[index
];
497 ASSERT(index
< VERT_ATTRIB_MAX
);
499 /* Limited choices at this stage:
501 ASSERT(type
== GL_FLOAT
);
502 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
503 ASSERT(ac
->count
- ac
->start
< ctx
->Const
.MaxArrayLockSize
);
505 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
511 ac
->count
- ac
->start
);
513 to
->Size
= from
->Size
;
514 to
->StrideB
= 4 * sizeof(GLfloat
);
516 ac
->IsCached
.Attrib
[index
] = GL_TRUE
;
522 * Externals to request arrays with specific properties:
526 struct gl_client_array
*_ac_import_texcoord( GLcontext
*ctx
,
531 GLboolean reqwriteable
,
532 GLboolean
*writeable
)
534 ACcontext
*ac
= AC_CONTEXT(ctx
);
536 ASSERT(unit
< ctx
->Const
.MaxTextureUnits
);
538 /* Can we keep the existing version?
540 if (ac
->NewArrayState
& _NEW_ARRAY_TEXCOORD(unit
))
541 reset_texcoord( ctx
, unit
);
543 /* Is the request impossible?
545 if (reqsize
!= 0 && ac
->Raw
.TexCoord
[unit
].Size
> (GLint
) reqsize
)
548 /* Do we need to pull in a copy of the client data:
550 if (ac
->Raw
.TexCoord
[unit
].Type
!= type
||
551 (reqstride
!= 0 && ac
->Raw
.TexCoord
[unit
].StrideB
!= (GLint
)reqstride
) ||
554 if (!ac
->IsCached
.TexCoord
[unit
])
555 import_texcoord(ctx
, unit
, type
, reqstride
);
556 *writeable
= GL_TRUE
;
557 return &ac
->Cache
.TexCoord
[unit
];
560 *writeable
= GL_FALSE
;
561 return &ac
->Raw
.TexCoord
[unit
];
565 struct gl_client_array
*_ac_import_vertex( GLcontext
*ctx
,
569 GLboolean reqwriteable
,
570 GLboolean
*writeable
)
572 ACcontext
*ac
= AC_CONTEXT(ctx
);
574 /* Can we keep the existing version?
576 if (ac
->NewArrayState
& _NEW_ARRAY_VERTEX
)
579 /* Is the request impossible?
581 if (reqsize
!= 0 && ac
->Raw
.Vertex
.Size
> (GLint
) reqsize
)
584 /* Do we need to pull in a copy of the client data:
586 if (ac
->Raw
.Vertex
.Type
!= type
||
587 (reqstride
!= 0 && ac
->Raw
.Vertex
.StrideB
!= (GLint
) reqstride
) ||
590 if (!ac
->IsCached
.Vertex
)
591 import_vertex(ctx
, type
, reqstride
);
592 *writeable
= GL_TRUE
;
593 return &ac
->Cache
.Vertex
;
596 *writeable
= GL_FALSE
;
597 return &ac
->Raw
.Vertex
;
601 struct gl_client_array
*_ac_import_normal( GLcontext
*ctx
,
604 GLboolean reqwriteable
,
605 GLboolean
*writeable
)
607 ACcontext
*ac
= AC_CONTEXT(ctx
);
609 /* Can we keep the existing version?
611 if (ac
->NewArrayState
& _NEW_ARRAY_NORMAL
)
614 /* Do we need to pull in a copy of the client data:
616 if (ac
->Raw
.Normal
.Type
!= type
||
617 (reqstride
!= 0 && ac
->Raw
.Normal
.StrideB
!= (GLint
) reqstride
) ||
620 if (!ac
->IsCached
.Normal
)
621 import_normal(ctx
, type
, reqstride
);
622 *writeable
= GL_TRUE
;
623 return &ac
->Cache
.Normal
;
626 *writeable
= GL_FALSE
;
627 return &ac
->Raw
.Normal
;
631 struct gl_client_array
*_ac_import_color( GLcontext
*ctx
,
635 GLboolean reqwriteable
,
636 GLboolean
*writeable
)
638 ACcontext
*ac
= AC_CONTEXT(ctx
);
640 /* Can we keep the existing version?
642 if (ac
->NewArrayState
& _NEW_ARRAY_COLOR0
)
645 /* Is the request impossible?
647 if (reqsize
!= 0 && ac
->Raw
.Color
.Size
> (GLint
) reqsize
) {
651 /* Do we need to pull in a copy of the client data:
653 if ((type
!= 0 && ac
->Raw
.Color
.Type
!= type
) ||
654 (reqstride
!= 0 && ac
->Raw
.Color
.StrideB
!= (GLint
) reqstride
) ||
657 if (!ac
->IsCached
.Color
)
658 import_color(ctx
, type
, reqstride
);
659 *writeable
= GL_TRUE
;
660 return &ac
->Cache
.Color
;
663 *writeable
= GL_FALSE
;
664 return &ac
->Raw
.Color
;
668 struct gl_client_array
*_ac_import_index( GLcontext
*ctx
,
671 GLboolean reqwriteable
,
672 GLboolean
*writeable
)
674 ACcontext
*ac
= AC_CONTEXT(ctx
);
676 /* Can we keep the existing version?
678 if (ac
->NewArrayState
& _NEW_ARRAY_INDEX
)
682 /* Do we need to pull in a copy of the client data:
684 if (ac
->Raw
.Index
.Type
!= type
||
685 (reqstride
!= 0 && ac
->Raw
.Index
.StrideB
!= (GLint
) reqstride
) ||
688 if (!ac
->IsCached
.Index
)
689 import_index(ctx
, type
, reqstride
);
690 *writeable
= GL_TRUE
;
691 return &ac
->Cache
.Index
;
694 *writeable
= GL_FALSE
;
695 return &ac
->Raw
.Index
;
699 struct gl_client_array
*_ac_import_secondarycolor( GLcontext
*ctx
,
703 GLboolean reqwriteable
,
704 GLboolean
*writeable
)
706 ACcontext
*ac
= AC_CONTEXT(ctx
);
708 /* Can we keep the existing version?
710 if (ac
->NewArrayState
& _NEW_ARRAY_COLOR1
)
711 reset_secondarycolor( ctx
);
713 /* Is the request impossible?
715 if (reqsize
!= 0 && ac
->Raw
.SecondaryColor
.Size
> (GLint
) reqsize
)
718 /* Do we need to pull in a copy of the client data:
720 if ((type
!= 0 && ac
->Raw
.SecondaryColor
.Type
!= type
) ||
721 (reqstride
!= 0 && ac
->Raw
.SecondaryColor
.StrideB
!= (GLint
)reqstride
) ||
724 if (!ac
->IsCached
.SecondaryColor
)
725 import_secondarycolor(ctx
, type
, reqstride
);
726 *writeable
= GL_TRUE
;
727 return &ac
->Cache
.SecondaryColor
;
730 *writeable
= GL_FALSE
;
731 return &ac
->Raw
.SecondaryColor
;
735 struct gl_client_array
*_ac_import_fogcoord( GLcontext
*ctx
,
738 GLboolean reqwriteable
,
739 GLboolean
*writeable
)
741 ACcontext
*ac
= AC_CONTEXT(ctx
);
743 /* Can we keep the existing version?
745 if (ac
->NewArrayState
& _NEW_ARRAY_FOGCOORD
)
746 reset_fogcoord( ctx
);
748 /* Do we need to pull in a copy of the client data:
750 if (ac
->Raw
.FogCoord
.Type
!= type
||
751 (reqstride
!= 0 && ac
->Raw
.FogCoord
.StrideB
!= (GLint
) reqstride
) ||
754 if (!ac
->IsCached
.FogCoord
)
755 import_fogcoord(ctx
, type
, reqstride
);
756 *writeable
= GL_TRUE
;
757 return &ac
->Cache
.FogCoord
;
760 *writeable
= GL_FALSE
;
761 return &ac
->Raw
.FogCoord
;
765 struct gl_client_array
*_ac_import_edgeflag( GLcontext
*ctx
,
768 GLboolean reqwriteable
,
769 GLboolean
*writeable
)
771 ACcontext
*ac
= AC_CONTEXT(ctx
);
773 /* Can we keep the existing version?
775 if (ac
->NewArrayState
& _NEW_ARRAY_EDGEFLAG
)
776 reset_edgeflag( ctx
);
778 /* Do we need to pull in a copy of the client data:
780 if (ac
->Raw
.EdgeFlag
.Type
!= type
||
781 (reqstride
!= 0 && ac
->Raw
.EdgeFlag
.StrideB
!= (GLint
) reqstride
) ||
784 if (!ac
->IsCached
.EdgeFlag
)
785 import_edgeflag(ctx
, type
, reqstride
);
786 *writeable
= GL_TRUE
;
787 return &ac
->Cache
.EdgeFlag
;
790 *writeable
= GL_FALSE
;
791 return &ac
->Raw
.EdgeFlag
;
795 /* GL_NV_vertex_program */
796 struct gl_client_array
*_ac_import_attrib( GLcontext
*ctx
,
801 GLboolean reqwriteable
,
802 GLboolean
*writeable
)
804 ACcontext
*ac
= AC_CONTEXT(ctx
);
806 ASSERT(index
< VERT_ATTRIB_MAX
);
808 /* Can we keep the existing version?
810 if (ac
->NewArrayState
& _NEW_ARRAY_ATTRIB(index
)) {
811 reset_attrib( ctx
, index
);
813 else if (ac
->NewArrayState
& (1 << index
)) {
814 /* Also need to check conventional attributes */
815 reset_attrib( ctx
, index
);
818 /* Is the request impossible?
820 if (reqsize
!= 0 && ac
->Raw
.Attrib
[index
].Size
> (GLint
) reqsize
)
823 /* Do we need to pull in a copy of the client data:
825 if (ac
->Raw
.Attrib
[index
].Type
!= type
||
826 (reqstride
!= 0 && ac
->Raw
.Attrib
[index
].StrideB
!= (GLint
)reqstride
) ||
829 if (!ac
->IsCached
.Attrib
[index
])
830 import_attrib(ctx
, index
, type
, reqstride
);
831 *writeable
= GL_TRUE
;
832 return &ac
->Cache
.Attrib
[index
];
835 *writeable
= GL_FALSE
;
836 return &ac
->Raw
.Attrib
[index
];
841 /* Clients must call this function to validate state and set bounds
842 * before importing any data:
844 void _ac_import_range( GLcontext
*ctx
, GLuint start
, GLuint count
)
846 ACcontext
*ac
= AC_CONTEXT(ctx
);
848 if (!ctx
->Array
.LockCount
) {
849 /* Not locked, discard cached data. Changes to lock
850 * status are caught via. _ac_invalidate_state().
852 ac
->NewArrayState
= _NEW_ARRAY_ALL
;
857 /* Locked, discard data for any disabled arrays. Require that
858 * the whole locked range always be dealt with, otherwise hard to
859 * maintain cached data in the face of clipping.
861 ac
->NewArrayState
|= ~ctx
->Array
._Enabled
;
862 ac
->start
= ctx
->Array
.LockFirst
;
863 ac
->count
= ctx
->Array
.LockCount
;
864 ASSERT(ac
->start
== start
); /* hmm? */
865 ASSERT(ac
->count
== count
);
871 /* Additional convienence function for importing the element list
872 * for glDrawElements() and glDrawRangeElements().
875 _ac_import_elements( GLcontext
*ctx
,
879 CONST
void *indices
)
881 ACcontext
*ac
= AC_CONTEXT(ctx
);
883 if (old_type
== new_type
)
886 if (ac
->elt_size
< count
* sizeof(GLuint
)) {
887 if (ac
->Elts
) FREE(ac
->Elts
);
888 while (ac
->elt_size
< count
* sizeof(GLuint
))
890 ac
->Elts
= (GLuint
*) MALLOC(ac
->elt_size
);
894 case GL_UNSIGNED_BYTE
:
897 case GL_UNSIGNED_SHORT
:
900 case GL_UNSIGNED_INT
: {
901 GLuint
*out
= (GLuint
*)ac
->Elts
;
905 case GL_UNSIGNED_BYTE
: {
906 CONST GLubyte
*in
= (CONST GLubyte
*)indices
;
907 for (i
= 0 ; i
< count
; i
++)
911 case GL_UNSIGNED_SHORT
: {
912 CONST GLushort
*in
= (CONST GLushort
*)indices
;
913 for (i
= 0 ; i
< count
; i
++)
921 return (CONST
void *)out
;