2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
25 * Keith Whitwell <keith@tungstengraphics.com>
33 #include "math/m_translate.h"
34 #include "array_cache/ac_context.h"
35 #include "math/m_translate.h"
37 #define STRIDE_ARRAY( array, offset ) \
39 GLubyte *tmp = ADD_POINTERS( (array).BufferObj->Data, (array).Ptr ) \
40 + (offset) * (array).StrideB; \
45 /* Set the array pointer back to its source when the cached data is
48 static void reset_texcoord( GLcontext
*ctx
, GLuint unit
)
50 ACcontext
*ac
= AC_CONTEXT(ctx
);
52 if (ctx
->Array
.TexCoord
[unit
].Enabled
) {
53 ac
->Raw
.TexCoord
[unit
] = ctx
->Array
.TexCoord
[unit
];
54 STRIDE_ARRAY(ac
->Raw
.TexCoord
[unit
], ac
->start
);
57 ac
->Raw
.TexCoord
[unit
] = ac
->Fallback
.TexCoord
[unit
];
59 if (ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+ unit
][3] != 1.0)
60 ac
->Raw
.TexCoord
[unit
].Size
= 4;
61 else if (ctx
->Current
.Attrib
[VERT_ATTRIB_TEX0
+ unit
][2] != 0.0)
62 ac
->Raw
.TexCoord
[unit
].Size
= 3;
64 ac
->Raw
.TexCoord
[unit
].Size
= 2;
67 ac
->IsCached
.TexCoord
[unit
] = GL_FALSE
;
68 ac
->NewArrayState
&= ~_NEW_ARRAY_TEXCOORD(unit
);
71 static void reset_vertex( GLcontext
*ctx
)
73 ACcontext
*ac
= AC_CONTEXT(ctx
);
74 ASSERT(ctx
->Array
.Vertex
.Enabled
75 || (ctx
->VertexProgram
.Enabled
&& ctx
->Array
.VertexAttrib
[0].Enabled
));
76 ac
->Raw
.Vertex
= ctx
->Array
.Vertex
;
77 STRIDE_ARRAY(ac
->Raw
.Vertex
, ac
->start
);
78 ac
->IsCached
.Vertex
= GL_FALSE
;
79 ac
->NewArrayState
&= ~_NEW_ARRAY_VERTEX
;
83 static void reset_normal( GLcontext
*ctx
)
85 ACcontext
*ac
= AC_CONTEXT(ctx
);
87 if (ctx
->Array
.Normal
.Enabled
) {
88 ac
->Raw
.Normal
= ctx
->Array
.Normal
;
89 STRIDE_ARRAY(ac
->Raw
.Normal
, ac
->start
);
92 ac
->Raw
.Normal
= ac
->Fallback
.Normal
;
95 ac
->IsCached
.Normal
= GL_FALSE
;
96 ac
->NewArrayState
&= ~_NEW_ARRAY_NORMAL
;
100 static void reset_color( GLcontext
*ctx
)
102 ACcontext
*ac
= AC_CONTEXT(ctx
);
105 if (ctx
->Array
.Color
.Enabled
) {
106 ac
->Raw
.Color
= ctx
->Array
.Color
;
107 STRIDE_ARRAY(ac
->Raw
.Color
, ac
->start
);
110 ac
->Raw
.Color
= ac
->Fallback
.Color
;
112 ac
->IsCached
.Color
= GL_FALSE
;
113 ac
->NewArrayState
&= ~_NEW_ARRAY_COLOR0
;
117 static void reset_secondarycolor( GLcontext
*ctx
)
119 ACcontext
*ac
= AC_CONTEXT(ctx
);
121 if (ctx
->Array
.SecondaryColor
.Enabled
& _NEW_ARRAY_COLOR1
) {
122 ac
->Raw
.SecondaryColor
= ctx
->Array
.SecondaryColor
;
123 STRIDE_ARRAY(ac
->Raw
.SecondaryColor
, ac
->start
);
126 ac
->Raw
.SecondaryColor
= ac
->Fallback
.SecondaryColor
;
128 ac
->IsCached
.SecondaryColor
= GL_FALSE
;
129 ac
->NewArrayState
&= ~_NEW_ARRAY_COLOR1
;
133 static void reset_index( GLcontext
*ctx
)
135 ACcontext
*ac
= AC_CONTEXT(ctx
);
137 if (ctx
->Array
.Index
.Enabled
& _NEW_ARRAY_INDEX
) {
138 ac
->Raw
.Index
= ctx
->Array
.Index
;
139 STRIDE_ARRAY(ac
->Raw
.Index
, ac
->start
);
142 ac
->Raw
.Index
= ac
->Fallback
.Index
;
144 ac
->IsCached
.Index
= GL_FALSE
;
145 ac
->NewArrayState
&= ~_NEW_ARRAY_INDEX
;
149 static void reset_fogcoord( GLcontext
*ctx
)
151 ACcontext
*ac
= AC_CONTEXT(ctx
);
153 if (ctx
->Array
.FogCoord
.Enabled
& _NEW_ARRAY_FOGCOORD
) {
154 ac
->Raw
.FogCoord
= ctx
->Array
.FogCoord
;
155 STRIDE_ARRAY(ac
->Raw
.FogCoord
, ac
->start
);
158 ac
->Raw
.FogCoord
= ac
->Fallback
.FogCoord
;
160 ac
->IsCached
.FogCoord
= GL_FALSE
;
161 ac
->NewArrayState
&= ~_NEW_ARRAY_FOGCOORD
;
165 static void reset_edgeflag( GLcontext
*ctx
)
167 ACcontext
*ac
= AC_CONTEXT(ctx
);
169 if (ctx
->Array
.EdgeFlag
.Enabled
& _NEW_ARRAY_EDGEFLAG
) {
170 ac
->Raw
.EdgeFlag
= ctx
->Array
.EdgeFlag
;
171 STRIDE_ARRAY(ac
->Raw
.EdgeFlag
, ac
->start
);
174 ac
->Raw
.EdgeFlag
= ac
->Fallback
.EdgeFlag
;
176 ac
->IsCached
.EdgeFlag
= GL_FALSE
;
177 ac
->NewArrayState
&= ~_NEW_ARRAY_EDGEFLAG
;
181 static void reset_attrib( GLcontext
*ctx
, GLuint index
)
183 ACcontext
*ac
= AC_CONTEXT(ctx
);
185 if (ctx
->Array
.VertexAttrib
[index
].Enabled
) {
186 ac
->Raw
.Attrib
[index
] = ctx
->Array
.VertexAttrib
[index
];
187 STRIDE_ARRAY(ac
->Raw
.Attrib
[index
], ac
->start
);
190 ac
->Raw
.Attrib
[index
] = ac
->Fallback
.Attrib
[index
];
192 ac
->IsCached
.Attrib
[index
] = GL_FALSE
;
193 ac
->NewArrayState
&= ~_NEW_ARRAY_ATTRIB(index
);
198 * Generic import function for color data
200 static void import( GLcontext
*ctx
,
202 struct gl_client_array
*to
,
203 struct gl_client_array
*from
)
207 ACcontext
*ac
= AC_CONTEXT(ctx
);
212 /* The dest and source data addresses are the sum of the buffer
213 * object's start plus the vertex array pointer/offset.
215 dest
= ADD_POINTERS(to
->BufferObj
->Data
, to
->Ptr
);
216 src
= ADD_POINTERS(from
->BufferObj
->Data
, from
->Ptr
);
220 _math_trans_4fc( (GLfloat (*)[4]) dest
,
226 ac
->count
- ac
->start
);
228 to
->StrideB
= 4 * sizeof(GLfloat
);
232 case GL_UNSIGNED_BYTE
:
233 _math_trans_4ub( (GLubyte (*)[4]) dest
,
239 ac
->count
- ac
->start
);
241 to
->StrideB
= 4 * sizeof(GLubyte
);
242 to
->Type
= GL_UNSIGNED_BYTE
;
245 case GL_UNSIGNED_SHORT
:
246 _math_trans_4us( (GLushort (*)[4]) dest
,
252 ac
->count
- ac
->start
);
254 to
->StrideB
= 4 * sizeof(GLushort
);
255 to
->Type
= GL_UNSIGNED_SHORT
;
267 * Functions to import array ranges with specified types and strides.
268 * For example, if the vertex data is GLshort[2] and we want GLfloat[3]
269 * we'll use an import function to do the data conversion.
272 static void import_texcoord( GLcontext
*ctx
, GLuint unit
,
273 GLenum type
, GLuint stride
)
275 ACcontext
*ac
= AC_CONTEXT(ctx
);
276 struct gl_client_array
*from
= &ac
->Raw
.TexCoord
[unit
];
277 struct gl_client_array
*to
= &ac
->Cache
.TexCoord
[unit
];
279 ASSERT(unit
< ctx
->Const
.MaxTextureCoordUnits
);
281 /* Limited choices at this stage:
283 ASSERT(type
== GL_FLOAT
);
284 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
285 ASSERT(ac
->count
- ac
->start
< ctx
->Const
.MaxArrayLockSize
);
287 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
293 ac
->count
- ac
->start
);
295 to
->Size
= from
->Size
;
296 to
->StrideB
= 4 * sizeof(GLfloat
);
298 ac
->IsCached
.TexCoord
[unit
] = GL_TRUE
;
301 static void import_vertex( GLcontext
*ctx
,
302 GLenum type
, GLuint stride
)
304 ACcontext
*ac
= AC_CONTEXT(ctx
);
305 struct gl_client_array
*from
= &ac
->Raw
.Vertex
;
306 struct gl_client_array
*to
= &ac
->Cache
.Vertex
;
308 /* Limited choices at this stage:
310 ASSERT(type
== GL_FLOAT
);
311 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
313 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
319 ac
->count
- ac
->start
);
321 to
->Size
= from
->Size
;
322 to
->StrideB
= 4 * sizeof(GLfloat
);
324 ac
->IsCached
.Vertex
= GL_TRUE
;
327 static void import_normal( GLcontext
*ctx
,
328 GLenum type
, GLuint stride
)
330 ACcontext
*ac
= AC_CONTEXT(ctx
);
331 struct gl_client_array
*from
= &ac
->Raw
.Normal
;
332 struct gl_client_array
*to
= &ac
->Cache
.Normal
;
334 /* Limited choices at this stage:
336 ASSERT(type
== GL_FLOAT
);
337 ASSERT(stride
== 3*sizeof(GLfloat
) || stride
== 0);
339 _math_trans_3f( (GLfloat (*)[3]) to
->Ptr
,
344 ac
->count
- ac
->start
);
346 to
->StrideB
= 3 * sizeof(GLfloat
);
348 ac
->IsCached
.Normal
= GL_TRUE
;
351 static void import_color( GLcontext
*ctx
,
352 GLenum type
, GLuint stride
)
354 ACcontext
*ac
= AC_CONTEXT(ctx
);
355 struct gl_client_array
*from
= &ac
->Raw
.Color
;
356 struct gl_client_array
*to
= &ac
->Cache
.Color
;
358 import( ctx
, type
, to
, from
);
360 ac
->IsCached
.Color
= GL_TRUE
;
363 static void import_index( GLcontext
*ctx
,
364 GLenum type
, GLuint stride
)
366 ACcontext
*ac
= AC_CONTEXT(ctx
);
367 struct gl_client_array
*from
= &ac
->Raw
.Index
;
368 struct gl_client_array
*to
= &ac
->Cache
.Index
;
370 /* Limited choices at this stage:
372 ASSERT(type
== GL_UNSIGNED_INT
);
373 ASSERT(stride
== sizeof(GLuint
) || stride
== 0);
375 _math_trans_1ui( (GLuint
*) to
->Ptr
,
380 ac
->count
- ac
->start
);
382 to
->StrideB
= sizeof(GLuint
);
383 to
->Type
= GL_UNSIGNED_INT
;
384 ac
->IsCached
.Index
= GL_TRUE
;
387 static void import_secondarycolor( GLcontext
*ctx
,
388 GLenum type
, GLuint stride
)
390 ACcontext
*ac
= AC_CONTEXT(ctx
);
391 struct gl_client_array
*from
= &ac
->Raw
.SecondaryColor
;
392 struct gl_client_array
*to
= &ac
->Cache
.SecondaryColor
;
394 import( ctx
, type
, to
, from
);
396 ac
->IsCached
.SecondaryColor
= GL_TRUE
;
399 static void import_fogcoord( GLcontext
*ctx
,
400 GLenum type
, GLuint stride
)
402 ACcontext
*ac
= AC_CONTEXT(ctx
);
403 struct gl_client_array
*from
= &ac
->Raw
.FogCoord
;
404 struct gl_client_array
*to
= &ac
->Cache
.FogCoord
;
406 /* Limited choices at this stage:
408 ASSERT(type
== GL_FLOAT
);
409 ASSERT(stride
== sizeof(GLfloat
) || stride
== 0);
411 _math_trans_1f( (GLfloat
*) to
->Ptr
,
416 ac
->count
- ac
->start
);
418 to
->StrideB
= sizeof(GLfloat
);
420 ac
->IsCached
.FogCoord
= GL_TRUE
;
423 static void import_edgeflag( GLcontext
*ctx
,
424 GLenum type
, GLuint stride
)
426 ACcontext
*ac
= AC_CONTEXT(ctx
);
427 struct gl_client_array
*from
= &ac
->Raw
.EdgeFlag
;
428 struct gl_client_array
*to
= &ac
->Cache
.EdgeFlag
;
430 /* Limited choices at this stage:
432 ASSERT(type
== GL_UNSIGNED_BYTE
);
433 ASSERT(stride
== sizeof(GLubyte
) || stride
== 0);
435 _math_trans_1ub( (GLubyte
*) to
->Ptr
,
440 ac
->count
- ac
->start
);
442 to
->StrideB
= sizeof(GLubyte
);
443 to
->Type
= GL_UNSIGNED_BYTE
;
444 ac
->IsCached
.EdgeFlag
= GL_TRUE
;
447 static void import_attrib( GLcontext
*ctx
, GLuint index
,
448 GLenum type
, GLuint stride
)
450 ACcontext
*ac
= AC_CONTEXT(ctx
);
451 struct gl_client_array
*from
= &ac
->Raw
.Attrib
[index
];
452 struct gl_client_array
*to
= &ac
->Cache
.Attrib
[index
];
454 ASSERT(index
< VERT_ATTRIB_MAX
);
456 /* Limited choices at this stage:
458 ASSERT(type
== GL_FLOAT
);
459 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
460 ASSERT(ac
->count
- ac
->start
< ctx
->Const
.MaxArrayLockSize
);
462 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
468 ac
->count
- ac
->start
);
470 to
->Size
= from
->Size
;
471 to
->StrideB
= 4 * sizeof(GLfloat
);
473 ac
->IsCached
.Attrib
[index
] = GL_TRUE
;
479 * Externals to request arrays with specific properties:
483 struct gl_client_array
*_ac_import_texcoord( GLcontext
*ctx
,
488 GLboolean reqwriteable
,
489 GLboolean
*writeable
)
491 ACcontext
*ac
= AC_CONTEXT(ctx
);
493 ASSERT(unit
< ctx
->Const
.MaxTextureCoordUnits
);
495 /* Can we keep the existing version?
497 if (ac
->NewArrayState
& _NEW_ARRAY_TEXCOORD(unit
))
498 reset_texcoord( ctx
, unit
);
500 /* Is the request impossible?
502 if (reqsize
!= 0 && ac
->Raw
.TexCoord
[unit
].Size
> (GLint
) reqsize
)
505 /* Do we need to pull in a copy of the client data:
507 if (ac
->Raw
.TexCoord
[unit
].Type
!= type
||
508 (reqstride
!= 0 && ac
->Raw
.TexCoord
[unit
].StrideB
!= (GLint
)reqstride
) ||
511 if (!ac
->IsCached
.TexCoord
[unit
])
512 import_texcoord(ctx
, unit
, type
, reqstride
);
513 *writeable
= GL_TRUE
;
514 return &ac
->Cache
.TexCoord
[unit
];
517 *writeable
= GL_FALSE
;
518 return &ac
->Raw
.TexCoord
[unit
];
522 struct gl_client_array
*_ac_import_vertex( GLcontext
*ctx
,
526 GLboolean reqwriteable
,
527 GLboolean
*writeable
)
529 ACcontext
*ac
= AC_CONTEXT(ctx
);
531 /* Can we keep the existing version?
533 if (ac
->NewArrayState
& _NEW_ARRAY_VERTEX
)
536 /* Is the request impossible?
538 if (reqsize
!= 0 && ac
->Raw
.Vertex
.Size
> (GLint
) reqsize
)
541 /* Do we need to pull in a copy of the client data:
543 if (ac
->Raw
.Vertex
.Type
!= type
||
544 (reqstride
!= 0 && ac
->Raw
.Vertex
.StrideB
!= (GLint
) reqstride
) ||
547 if (!ac
->IsCached
.Vertex
)
548 import_vertex(ctx
, type
, reqstride
);
549 *writeable
= GL_TRUE
;
550 return &ac
->Cache
.Vertex
;
553 *writeable
= GL_FALSE
;
554 return &ac
->Raw
.Vertex
;
558 struct gl_client_array
*_ac_import_normal( GLcontext
*ctx
,
561 GLboolean reqwriteable
,
562 GLboolean
*writeable
)
564 ACcontext
*ac
= AC_CONTEXT(ctx
);
566 /* Can we keep the existing version?
568 if (ac
->NewArrayState
& _NEW_ARRAY_NORMAL
)
571 /* Do we need to pull in a copy of the client data:
573 if (ac
->Raw
.Normal
.Type
!= type
||
574 (reqstride
!= 0 && ac
->Raw
.Normal
.StrideB
!= (GLint
) reqstride
) ||
577 if (!ac
->IsCached
.Normal
)
578 import_normal(ctx
, type
, reqstride
);
579 *writeable
= GL_TRUE
;
580 return &ac
->Cache
.Normal
;
583 *writeable
= GL_FALSE
;
584 return &ac
->Raw
.Normal
;
588 struct gl_client_array
*_ac_import_color( GLcontext
*ctx
,
592 GLboolean reqwriteable
,
593 GLboolean
*writeable
)
595 ACcontext
*ac
= AC_CONTEXT(ctx
);
597 /* Can we keep the existing version?
599 if (ac
->NewArrayState
& _NEW_ARRAY_COLOR0
)
602 /* Is the request impossible?
604 if (reqsize
!= 0 && ac
->Raw
.Color
.Size
> (GLint
) reqsize
) {
608 /* Do we need to pull in a copy of the client data:
610 if ((type
!= 0 && ac
->Raw
.Color
.Type
!= type
) ||
611 (reqstride
!= 0 && ac
->Raw
.Color
.StrideB
!= (GLint
) reqstride
) ||
614 if (!ac
->IsCached
.Color
)
615 import_color(ctx
, type
, reqstride
);
616 *writeable
= GL_TRUE
;
617 return &ac
->Cache
.Color
;
620 *writeable
= GL_FALSE
;
621 return &ac
->Raw
.Color
;
625 struct gl_client_array
*_ac_import_index( GLcontext
*ctx
,
628 GLboolean reqwriteable
,
629 GLboolean
*writeable
)
631 ACcontext
*ac
= AC_CONTEXT(ctx
);
633 /* Can we keep the existing version?
635 if (ac
->NewArrayState
& _NEW_ARRAY_INDEX
)
639 /* Do we need to pull in a copy of the client data:
641 if (ac
->Raw
.Index
.Type
!= type
||
642 (reqstride
!= 0 && ac
->Raw
.Index
.StrideB
!= (GLint
) reqstride
) ||
645 if (!ac
->IsCached
.Index
)
646 import_index(ctx
, type
, reqstride
);
647 *writeable
= GL_TRUE
;
648 return &ac
->Cache
.Index
;
651 *writeable
= GL_FALSE
;
652 return &ac
->Raw
.Index
;
656 struct gl_client_array
*_ac_import_secondarycolor( GLcontext
*ctx
,
660 GLboolean reqwriteable
,
661 GLboolean
*writeable
)
663 ACcontext
*ac
= AC_CONTEXT(ctx
);
665 /* Can we keep the existing version?
667 if (ac
->NewArrayState
& _NEW_ARRAY_COLOR1
)
668 reset_secondarycolor( ctx
);
670 /* Is the request impossible?
672 if (reqsize
!= 0 && ac
->Raw
.SecondaryColor
.Size
> (GLint
) reqsize
)
675 /* Do we need to pull in a copy of the client data:
677 if ((type
!= 0 && ac
->Raw
.SecondaryColor
.Type
!= type
) ||
678 (reqstride
!= 0 && ac
->Raw
.SecondaryColor
.StrideB
!= (GLint
)reqstride
) ||
681 if (!ac
->IsCached
.SecondaryColor
)
682 import_secondarycolor(ctx
, type
, reqstride
);
683 *writeable
= GL_TRUE
;
684 return &ac
->Cache
.SecondaryColor
;
687 *writeable
= GL_FALSE
;
688 return &ac
->Raw
.SecondaryColor
;
692 struct gl_client_array
*_ac_import_fogcoord( GLcontext
*ctx
,
695 GLboolean reqwriteable
,
696 GLboolean
*writeable
)
698 ACcontext
*ac
= AC_CONTEXT(ctx
);
700 /* Can we keep the existing version?
702 if (ac
->NewArrayState
& _NEW_ARRAY_FOGCOORD
)
703 reset_fogcoord( ctx
);
705 /* Do we need to pull in a copy of the client data:
707 if (ac
->Raw
.FogCoord
.Type
!= type
||
708 (reqstride
!= 0 && ac
->Raw
.FogCoord
.StrideB
!= (GLint
) reqstride
) ||
711 if (!ac
->IsCached
.FogCoord
)
712 import_fogcoord(ctx
, type
, reqstride
);
713 *writeable
= GL_TRUE
;
714 return &ac
->Cache
.FogCoord
;
717 *writeable
= GL_FALSE
;
718 return &ac
->Raw
.FogCoord
;
722 struct gl_client_array
*_ac_import_edgeflag( GLcontext
*ctx
,
725 GLboolean reqwriteable
,
726 GLboolean
*writeable
)
728 ACcontext
*ac
= AC_CONTEXT(ctx
);
730 /* Can we keep the existing version?
732 if (ac
->NewArrayState
& _NEW_ARRAY_EDGEFLAG
)
733 reset_edgeflag( ctx
);
735 /* Do we need to pull in a copy of the client data:
737 if (ac
->Raw
.EdgeFlag
.Type
!= type
||
738 (reqstride
!= 0 && ac
->Raw
.EdgeFlag
.StrideB
!= (GLint
) reqstride
) ||
741 if (!ac
->IsCached
.EdgeFlag
)
742 import_edgeflag(ctx
, type
, reqstride
);
743 *writeable
= GL_TRUE
;
744 return &ac
->Cache
.EdgeFlag
;
747 *writeable
= GL_FALSE
;
748 return &ac
->Raw
.EdgeFlag
;
752 /* GL_NV_vertex_program */
753 struct gl_client_array
*_ac_import_attrib( GLcontext
*ctx
,
758 GLboolean reqwriteable
,
759 GLboolean
*writeable
)
761 ACcontext
*ac
= AC_CONTEXT(ctx
);
763 ASSERT(index
< VERT_ATTRIB_MAX
);
765 /* Can we keep the existing version?
767 if (ac
->NewArrayState
& _NEW_ARRAY_ATTRIB(index
))
768 reset_attrib( ctx
, index
);
770 /* Is the request impossible?
772 if (reqsize
!= 0 && ac
->Raw
.Attrib
[index
].Size
> (GLint
) reqsize
)
775 /* Do we need to pull in a copy of the client data:
777 if (ac
->Raw
.Attrib
[index
].Type
!= type
||
778 (reqstride
!= 0 && ac
->Raw
.Attrib
[index
].StrideB
!= (GLint
)reqstride
) ||
781 if (!ac
->IsCached
.Attrib
[index
])
782 import_attrib(ctx
, index
, type
, reqstride
);
783 *writeable
= GL_TRUE
;
784 return &ac
->Cache
.Attrib
[index
];
787 *writeable
= GL_FALSE
;
788 return &ac
->Raw
.Attrib
[index
];
793 /* Clients must call this function to validate state and set bounds
794 * before importing any data:
796 void _ac_import_range( GLcontext
*ctx
, GLuint start
, GLuint count
)
798 ACcontext
*ac
= AC_CONTEXT(ctx
);
800 if (!ctx
->Array
.LockCount
) {
801 /* Not locked, discard cached data. Changes to lock
802 * status are caught via. _ac_invalidate_state().
804 ac
->NewArrayState
= _NEW_ARRAY_ALL
;
809 /* Locked, discard data for any disabled arrays. Require that
810 * the whole locked range always be dealt with, otherwise hard to
811 * maintain cached data in the face of clipping.
813 ac
->NewArrayState
|= ~ctx
->Array
._Enabled
;
814 ac
->start
= ctx
->Array
.LockFirst
;
815 ac
->count
= ctx
->Array
.LockCount
;
816 ASSERT(ac
->start
== start
); /* hmm? */
817 ASSERT(ac
->count
== count
);
823 /* Additional convienence function for importing the element list
824 * for glDrawElements() and glDrawRangeElements().
827 _ac_import_elements( GLcontext
*ctx
,
831 CONST
void *indices
)
833 ACcontext
*ac
= AC_CONTEXT(ctx
);
835 if (old_type
== new_type
)
838 if (ac
->elt_size
< count
* sizeof(GLuint
)) {
839 if (ac
->Elts
) FREE(ac
->Elts
);
840 while (ac
->elt_size
< count
* sizeof(GLuint
))
842 ac
->Elts
= (GLuint
*) MALLOC(ac
->elt_size
);
846 case GL_UNSIGNED_BYTE
:
849 case GL_UNSIGNED_SHORT
:
852 case GL_UNSIGNED_INT
: {
853 GLuint
*out
= (GLuint
*)ac
->Elts
;
857 case GL_UNSIGNED_BYTE
: {
858 CONST GLubyte
*in
= (CONST GLubyte
*)indices
;
859 for (i
= 0 ; i
< count
; i
++)
863 case GL_UNSIGNED_SHORT
: {
864 CONST GLushort
*in
= (CONST GLushort
*)indices
;
865 for (i
= 0 ; i
< count
; i
++)
873 return (CONST
void *)out
;