2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 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
49 reset_texcoord( GLcontext
*ctx
, GLuint unit
)
51 ACcontext
*ac
= AC_CONTEXT(ctx
);
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
);
58 ac
->Raw
.TexCoord
[unit
] = ac
->Fallback
.TexCoord
[unit
];
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;
65 ac
->Raw
.TexCoord
[unit
].Size
= 2;
68 ac
->IsCached
.TexCoord
[unit
] = GL_FALSE
;
69 ac
->NewArrayState
&= ~_NEW_ARRAY_TEXCOORD(unit
);
73 reset_vertex( GLcontext
*ctx
)
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
;
86 reset_normal( GLcontext
*ctx
)
88 ACcontext
*ac
= AC_CONTEXT(ctx
);
90 if (ctx
->Array
.Normal
.Enabled
) {
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
;
104 reset_color( GLcontext
*ctx
)
106 ACcontext
*ac
= AC_CONTEXT(ctx
);
108 if (ctx
->Array
.Color
.Enabled
) {
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
;
121 reset_secondarycolor( GLcontext
*ctx
)
123 ACcontext
*ac
= AC_CONTEXT(ctx
);
125 if (ctx
->Array
.SecondaryColor
.Enabled
) {
126 ac
->Raw
.SecondaryColor
= ctx
->Array
.SecondaryColor
;
127 STRIDE_ARRAY(ac
->Raw
.SecondaryColor
, ac
->start
);
130 ac
->Raw
.SecondaryColor
= ac
->Fallback
.SecondaryColor
;
132 ac
->IsCached
.SecondaryColor
= GL_FALSE
;
133 ac
->NewArrayState
&= ~_NEW_ARRAY_COLOR1
;
138 reset_index( GLcontext
*ctx
)
140 ACcontext
*ac
= AC_CONTEXT(ctx
);
142 if (ctx
->Array
.Index
.Enabled
) {
143 ac
->Raw
.Index
= ctx
->Array
.Index
;
144 STRIDE_ARRAY(ac
->Raw
.Index
, ac
->start
);
147 ac
->Raw
.Index
= ac
->Fallback
.Index
;
149 ac
->IsCached
.Index
= GL_FALSE
;
150 ac
->NewArrayState
&= ~_NEW_ARRAY_INDEX
;
155 reset_fogcoord( GLcontext
*ctx
)
157 ACcontext
*ac
= AC_CONTEXT(ctx
);
159 if (ctx
->Array
.FogCoord
.Enabled
) {
160 ac
->Raw
.FogCoord
= ctx
->Array
.FogCoord
;
161 STRIDE_ARRAY(ac
->Raw
.FogCoord
, ac
->start
);
164 ac
->Raw
.FogCoord
= ac
->Fallback
.FogCoord
;
166 ac
->IsCached
.FogCoord
= GL_FALSE
;
167 ac
->NewArrayState
&= ~_NEW_ARRAY_FOGCOORD
;
172 reset_edgeflag( GLcontext
*ctx
)
174 ACcontext
*ac
= AC_CONTEXT(ctx
);
176 if (ctx
->Array
.EdgeFlag
.Enabled
) {
177 ac
->Raw
.EdgeFlag
= ctx
->Array
.EdgeFlag
;
178 STRIDE_ARRAY(ac
->Raw
.EdgeFlag
, ac
->start
);
181 ac
->Raw
.EdgeFlag
= ac
->Fallback
.EdgeFlag
;
183 ac
->IsCached
.EdgeFlag
= GL_FALSE
;
184 ac
->NewArrayState
&= ~_NEW_ARRAY_EDGEFLAG
;
189 reset_attrib( GLcontext
*ctx
, GLuint index
)
191 ACcontext
*ac
= AC_CONTEXT(ctx
);
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
);
198 ac
->Raw
.Attrib
[index
] = ac
->Fallback
.Attrib
[index
];
200 ac
->IsCached
.Attrib
[index
] = GL_FALSE
;
201 ac
->NewArrayState
&= ~_NEW_ARRAY_ATTRIB(index
);
206 * Generic import function for color data
209 import( const GLcontext
*ctx
,
211 struct gl_client_array
*to
,
212 const struct gl_client_array
*from
)
214 const ACcontext
*ac
= AC_CONTEXT(ctx
);
217 destType
= from
->Type
;
221 _math_trans_4fc( (GLfloat (*)[4]) to
->Ptr
,
227 ac
->count
- ac
->start
);
229 to
->StrideB
= 4 * sizeof(GLfloat
);
233 case GL_UNSIGNED_BYTE
:
234 _math_trans_4ub( (GLubyte (*)[4]) to
->Ptr
,
240 ac
->count
- ac
->start
);
242 to
->StrideB
= 4 * sizeof(GLubyte
);
243 to
->Type
= GL_UNSIGNED_BYTE
;
246 case GL_UNSIGNED_SHORT
:
247 _math_trans_4us( (GLushort (*)[4]) to
->Ptr
,
253 ac
->count
- ac
->start
);
255 to
->StrideB
= 4 * sizeof(GLushort
);
256 to
->Type
= GL_UNSIGNED_SHORT
;
260 _mesa_problem(ctx
, "Unexpected dest format in import()");
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.
274 import_texcoord( GLcontext
*ctx
, GLuint unit
, GLenum type
, GLuint stride
)
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
;
281 ASSERT(unit
< ctx
->Const
.MaxTextureCoordUnits
);
283 /* Limited choices at this stage:
285 ASSERT(type
== GL_FLOAT
);
286 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
287 ASSERT(ac
->count
- ac
->start
< ctx
->Const
.MaxArrayLockSize
);
289 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
295 ac
->count
- ac
->start
);
297 to
->Size
= from
->Size
;
298 to
->StrideB
= 4 * sizeof(GLfloat
);
300 ac
->IsCached
.TexCoord
[unit
] = GL_TRUE
;
304 import_vertex( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
311 /* Limited choices at this stage:
313 ASSERT(type
== GL_FLOAT
);
314 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
316 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
322 ac
->count
- ac
->start
);
324 to
->Size
= from
->Size
;
325 to
->StrideB
= 4 * sizeof(GLfloat
);
327 ac
->IsCached
.Vertex
= GL_TRUE
;
331 import_normal( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
338 /* Limited choices at this stage:
340 ASSERT(type
== GL_FLOAT
);
341 ASSERT(stride
== 3*sizeof(GLfloat
) || stride
== 0);
343 _math_trans_3f( (GLfloat (*)[3]) to
->Ptr
,
348 ac
->count
- ac
->start
);
350 to
->StrideB
= 3 * sizeof(GLfloat
);
352 ac
->IsCached
.Normal
= GL_TRUE
;
356 import_color( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
363 import( ctx
, type
, to
, from
);
365 ac
->IsCached
.Color
= GL_TRUE
;
369 import_index( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
376 /* Limited choices at this stage:
378 ASSERT(type
== GL_UNSIGNED_INT
);
379 ASSERT(stride
== sizeof(GLuint
) || stride
== 0);
381 _math_trans_1ui( (GLuint
*) to
->Ptr
,
386 ac
->count
- ac
->start
);
388 to
->StrideB
= sizeof(GLuint
);
389 to
->Type
= GL_UNSIGNED_INT
;
390 ac
->IsCached
.Index
= GL_TRUE
;
394 import_secondarycolor( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
401 import( ctx
, type
, to
, from
);
403 ac
->IsCached
.SecondaryColor
= GL_TRUE
;
407 import_fogcoord( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
414 /* Limited choices at this stage:
416 ASSERT(type
== GL_FLOAT
);
417 ASSERT(stride
== sizeof(GLfloat
) || stride
== 0);
419 _math_trans_1f( (GLfloat
*) to
->Ptr
,
424 ac
->count
- ac
->start
);
426 to
->StrideB
= sizeof(GLfloat
);
428 ac
->IsCached
.FogCoord
= GL_TRUE
;
432 import_edgeflag( GLcontext
*ctx
, GLenum type
, GLuint stride
)
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
;
439 /* Limited choices at this stage:
441 ASSERT(type
== GL_UNSIGNED_BYTE
);
442 ASSERT(stride
== sizeof(GLubyte
) || stride
== 0);
444 _math_trans_1ub( (GLubyte
*) to
->Ptr
,
449 ac
->count
- ac
->start
);
451 to
->StrideB
= sizeof(GLubyte
);
452 to
->Type
= GL_UNSIGNED_BYTE
;
453 ac
->IsCached
.EdgeFlag
= GL_TRUE
;
457 import_attrib( GLcontext
*ctx
, GLuint index
, GLenum type
, GLuint stride
)
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
;
464 ASSERT(index
< VERT_ATTRIB_MAX
);
466 /* Limited choices at this stage:
468 ASSERT(type
== GL_FLOAT
);
469 ASSERT(stride
== 4*sizeof(GLfloat
) || stride
== 0);
470 ASSERT(ac
->count
- ac
->start
< ctx
->Const
.MaxArrayLockSize
);
472 _math_trans_4f( (GLfloat (*)[4]) to
->Ptr
,
478 ac
->count
- ac
->start
);
480 to
->Size
= from
->Size
;
481 to
->StrideB
= 4 * sizeof(GLfloat
);
483 ac
->IsCached
.Attrib
[index
] = GL_TRUE
;
489 * Externals to request arrays with specific properties:
493 struct gl_client_array
*
494 _ac_import_texcoord( GLcontext
*ctx
,
499 GLboolean reqwriteable
,
500 GLboolean
*writeable
)
502 ACcontext
*ac
= AC_CONTEXT(ctx
);
504 ASSERT(unit
< ctx
->Const
.MaxTextureCoordUnits
);
506 /* Can we keep the existing version?
508 if (ac
->NewArrayState
& _NEW_ARRAY_TEXCOORD(unit
))
509 reset_texcoord( ctx
, unit
);
511 /* Is the request impossible?
513 if (reqsize
!= 0 && ac
->Raw
.TexCoord
[unit
].Size
> (GLint
) reqsize
)
516 /* Do we need to pull in a copy of the client data:
518 if (ac
->Raw
.TexCoord
[unit
].Type
!= type
||
519 (reqstride
!= 0 && ac
->Raw
.TexCoord
[unit
].StrideB
!= (GLint
)reqstride
) ||
522 if (!ac
->IsCached
.TexCoord
[unit
])
523 import_texcoord(ctx
, unit
, type
, reqstride
);
524 *writeable
= GL_TRUE
;
525 return &ac
->Cache
.TexCoord
[unit
];
528 *writeable
= GL_FALSE
;
529 return &ac
->Raw
.TexCoord
[unit
];
533 struct gl_client_array
*
534 _ac_import_vertex( GLcontext
*ctx
,
538 GLboolean reqwriteable
,
539 GLboolean
*writeable
)
541 ACcontext
*ac
= AC_CONTEXT(ctx
);
543 /* Can we keep the existing version?
545 if (ac
->NewArrayState
& _NEW_ARRAY_VERTEX
)
548 /* Is the request impossible?
550 if (reqsize
!= 0 && ac
->Raw
.Vertex
.Size
> (GLint
) reqsize
)
553 /* Do we need to pull in a copy of the client data:
555 if (ac
->Raw
.Vertex
.Type
!= type
||
556 (reqstride
!= 0 && ac
->Raw
.Vertex
.StrideB
!= (GLint
) reqstride
) ||
559 if (!ac
->IsCached
.Vertex
)
560 import_vertex(ctx
, type
, reqstride
);
561 *writeable
= GL_TRUE
;
562 return &ac
->Cache
.Vertex
;
565 *writeable
= GL_FALSE
;
566 return &ac
->Raw
.Vertex
;
570 struct gl_client_array
*
571 _ac_import_normal( GLcontext
*ctx
,
574 GLboolean reqwriteable
,
575 GLboolean
*writeable
)
577 ACcontext
*ac
= AC_CONTEXT(ctx
);
579 /* Can we keep the existing version?
581 if (ac
->NewArrayState
& _NEW_ARRAY_NORMAL
)
584 /* Do we need to pull in a copy of the client data:
586 if (ac
->Raw
.Normal
.Type
!= type
||
587 (reqstride
!= 0 && ac
->Raw
.Normal
.StrideB
!= (GLint
) reqstride
) ||
590 if (!ac
->IsCached
.Normal
)
591 import_normal(ctx
, type
, reqstride
);
592 *writeable
= GL_TRUE
;
593 return &ac
->Cache
.Normal
;
596 *writeable
= GL_FALSE
;
597 return &ac
->Raw
.Normal
;
601 struct gl_client_array
*
602 _ac_import_color( GLcontext
*ctx
,
606 GLboolean reqwriteable
,
607 GLboolean
*writeable
)
609 ACcontext
*ac
= AC_CONTEXT(ctx
);
611 /* Can we keep the existing version?
613 if (ac
->NewArrayState
& _NEW_ARRAY_COLOR0
)
616 /* Is the request impossible?
618 if (reqsize
!= 0 && ac
->Raw
.Color
.Size
> (GLint
) reqsize
) {
622 /* Do we need to pull in a copy of the client data:
624 if ((type
!= 0 && ac
->Raw
.Color
.Type
!= type
) ||
625 (reqstride
!= 0 && ac
->Raw
.Color
.StrideB
!= (GLint
) reqstride
) ||
628 if (!ac
->IsCached
.Color
) {
629 import_color(ctx
, type
, reqstride
);
631 *writeable
= GL_TRUE
;
632 return &ac
->Cache
.Color
;
635 *writeable
= GL_FALSE
;
636 return &ac
->Raw
.Color
;
640 struct gl_client_array
*
641 _ac_import_index( GLcontext
*ctx
,
644 GLboolean reqwriteable
,
645 GLboolean
*writeable
)
647 ACcontext
*ac
= AC_CONTEXT(ctx
);
649 /* Can we keep the existing version?
651 if (ac
->NewArrayState
& _NEW_ARRAY_INDEX
)
655 /* Do we need to pull in a copy of the client data:
657 if (ac
->Raw
.Index
.Type
!= type
||
658 (reqstride
!= 0 && ac
->Raw
.Index
.StrideB
!= (GLint
) reqstride
) ||
661 if (!ac
->IsCached
.Index
)
662 import_index(ctx
, type
, reqstride
);
663 *writeable
= GL_TRUE
;
664 return &ac
->Cache
.Index
;
667 *writeable
= GL_FALSE
;
668 return &ac
->Raw
.Index
;
672 struct gl_client_array
*
673 _ac_import_secondarycolor( GLcontext
*ctx
,
677 GLboolean reqwriteable
,
678 GLboolean
*writeable
)
680 ACcontext
*ac
= AC_CONTEXT(ctx
);
682 /* Can we keep the existing version?
684 if (ac
->NewArrayState
& _NEW_ARRAY_COLOR1
)
685 reset_secondarycolor( ctx
);
687 /* Is the request impossible?
689 if (reqsize
!= 0 && ac
->Raw
.SecondaryColor
.Size
> (GLint
) reqsize
)
692 /* Do we need to pull in a copy of the client data:
694 if ((type
!= 0 && ac
->Raw
.SecondaryColor
.Type
!= type
) ||
695 (reqstride
!= 0 && ac
->Raw
.SecondaryColor
.StrideB
!= (GLint
)reqstride
) ||
698 if (!ac
->IsCached
.SecondaryColor
)
699 import_secondarycolor(ctx
, type
, reqstride
);
700 *writeable
= GL_TRUE
;
701 return &ac
->Cache
.SecondaryColor
;
704 *writeable
= GL_FALSE
;
705 return &ac
->Raw
.SecondaryColor
;
709 struct gl_client_array
*
710 _ac_import_fogcoord( GLcontext
*ctx
,
713 GLboolean reqwriteable
,
714 GLboolean
*writeable
)
716 ACcontext
*ac
= AC_CONTEXT(ctx
);
718 /* Can we keep the existing version?
720 if (ac
->NewArrayState
& _NEW_ARRAY_FOGCOORD
)
721 reset_fogcoord( ctx
);
723 /* Do we need to pull in a copy of the client data:
725 if (ac
->Raw
.FogCoord
.Type
!= type
||
726 (reqstride
!= 0 && ac
->Raw
.FogCoord
.StrideB
!= (GLint
) reqstride
) ||
729 if (!ac
->IsCached
.FogCoord
)
730 import_fogcoord(ctx
, type
, reqstride
);
731 *writeable
= GL_TRUE
;
732 return &ac
->Cache
.FogCoord
;
735 *writeable
= GL_FALSE
;
736 return &ac
->Raw
.FogCoord
;
740 struct gl_client_array
*
741 _ac_import_edgeflag( GLcontext
*ctx
,
744 GLboolean reqwriteable
,
745 GLboolean
*writeable
)
747 ACcontext
*ac
= AC_CONTEXT(ctx
);
749 /* Can we keep the existing version?
751 if (ac
->NewArrayState
& _NEW_ARRAY_EDGEFLAG
)
752 reset_edgeflag( ctx
);
754 /* Do we need to pull in a copy of the client data:
756 if (ac
->Raw
.EdgeFlag
.Type
!= type
||
757 (reqstride
!= 0 && ac
->Raw
.EdgeFlag
.StrideB
!= (GLint
) reqstride
) ||
760 if (!ac
->IsCached
.EdgeFlag
)
761 import_edgeflag(ctx
, type
, reqstride
);
762 *writeable
= GL_TRUE
;
763 return &ac
->Cache
.EdgeFlag
;
766 *writeable
= GL_FALSE
;
767 return &ac
->Raw
.EdgeFlag
;
771 /* GL_NV_vertex_program */
772 struct gl_client_array
*
773 _ac_import_attrib( GLcontext
*ctx
,
778 GLboolean reqwriteable
,
779 GLboolean
*writeable
)
781 ACcontext
*ac
= AC_CONTEXT(ctx
);
783 ASSERT(index
< VERT_ATTRIB_MAX
);
785 /* Can we keep the existing version?
787 if (ac
->NewArrayState
& _NEW_ARRAY_ATTRIB(index
))
788 reset_attrib( ctx
, index
);
790 /* Is the request impossible?
792 if (reqsize
!= 0 && ac
->Raw
.Attrib
[index
].Size
> (GLint
) reqsize
)
795 /* Do we need to pull in a copy of the client data:
797 if (ac
->Raw
.Attrib
[index
].Type
!= type
||
798 (reqstride
!= 0 && ac
->Raw
.Attrib
[index
].StrideB
!= (GLint
)reqstride
) ||
801 if (!ac
->IsCached
.Attrib
[index
])
802 import_attrib(ctx
, index
, type
, reqstride
);
803 *writeable
= GL_TRUE
;
804 return &ac
->Cache
.Attrib
[index
];
807 *writeable
= GL_FALSE
;
808 return &ac
->Raw
.Attrib
[index
];
813 /* Clients must call this function to validate state and set bounds
814 * before importing any data:
817 _ac_import_range( GLcontext
*ctx
, GLuint start
, GLuint count
)
819 ACcontext
*ac
= AC_CONTEXT(ctx
);
821 if (!ctx
->Array
.LockCount
) {
822 /* Not locked, discard cached data. Changes to lock
823 * status are caught via. _ac_invalidate_state().
825 ac
->NewArrayState
= _NEW_ARRAY_ALL
;
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.
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
);
844 /* Additional convienence function for importing the element list
845 * for glDrawElements() and glDrawRangeElements().
848 _ac_import_elements( GLcontext
*ctx
,
852 CONST
void *indices
)
854 ACcontext
*ac
= AC_CONTEXT(ctx
);
856 if (old_type
== new_type
)
859 if (ac
->elt_size
< count
* sizeof(GLuint
)) {
860 if (ac
->Elts
) FREE(ac
->Elts
);
861 while (ac
->elt_size
< count
* sizeof(GLuint
))
863 ac
->Elts
= (GLuint
*) MALLOC(ac
->elt_size
);
867 case GL_UNSIGNED_BYTE
:
870 case GL_UNSIGNED_SHORT
:
873 case GL_UNSIGNED_INT
: {
874 GLuint
*out
= (GLuint
*)ac
->Elts
;
878 case GL_UNSIGNED_BYTE
: {
879 CONST GLubyte
*in
= (CONST GLubyte
*)indices
;
880 for (i
= 0 ; i
< count
; i
++)
884 case GL_UNSIGNED_SHORT
: {
885 CONST GLushort
*in
= (CONST GLushort
*)indices
;
886 for (i
= 0 ; i
< count
; i
++)
894 return (CONST
void *)out
;