gallium: fix refcount bug introduced in eb20e2984
[mesa.git] / src / mesa / main / varray.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.2
4 *
5 * Copyright (C) 1999-2008 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
25
26 #include "glheader.h"
27 #include "imports.h"
28 #include "bufferobj.h"
29 #include "context.h"
30 #include "enable.h"
31 #include "enums.h"
32 #include "mtypes.h"
33 #include "varray.h"
34 #include "arrayobj.h"
35 #include "glapi/dispatch.h"
36
37
38 /**
39 * Update the fields of a vertex array object.
40 * We need to do a few special things for arrays that live in
41 * vertex buffer objects.
42 *
43 * \param array the array to update
44 * \param dirtyBit which bit to set in ctx->Array.NewState for this array
45 * \param elementSize size of each array element, in bytes
46 * \param size components per element (1, 2, 3 or 4)
47 * \param type datatype of each component (GL_FLOAT, GL_INT, etc)
48 * \param stride stride between elements, in elements
49 * \param normalized are integer types converted to floats in [-1, 1]?
50 * \param ptr the address (or offset inside VBO) of the array data
51 */
52 static void
53 update_array(GLcontext *ctx, struct gl_client_array *array,
54 GLbitfield dirtyBit, GLsizei elementSize,
55 GLint size, GLenum type,
56 GLsizei stride, GLboolean normalized, const GLvoid *ptr)
57 {
58 array->Size = size;
59 array->Type = type;
60 array->Stride = stride;
61 array->StrideB = stride ? stride : elementSize;
62 array->Normalized = normalized;
63 array->Ptr = (const GLubyte *) ptr;
64 #if FEATURE_ARB_vertex_buffer_object
65 _mesa_reference_buffer_object(ctx, &array->BufferObj,
66 ctx->Array.ArrayBufferObj);
67
68 /* Compute the index of the last array element that's inside the buffer.
69 * Later in glDrawArrays we'll check if start + count > _MaxElement to
70 * be sure we won't go out of bounds.
71 */
72 if (ctx->Array.ArrayBufferObj->Name)
73 array->_MaxElement = ((GLsizeiptrARB) ctx->Array.ArrayBufferObj->Size
74 - (GLsizeiptrARB) array->Ptr + array->StrideB
75 - elementSize) / array->StrideB;
76 else
77 #endif
78 array->_MaxElement = 2 * 1000 * 1000 * 1000; /* just a big number */
79
80 ctx->NewState |= _NEW_ARRAY;
81 ctx->Array.NewState |= dirtyBit;
82 }
83
84
85 void GLAPIENTRY
86 _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
87 {
88 GLsizei elementSize;
89 GET_CURRENT_CONTEXT(ctx);
90 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
91
92 if (size < 2 || size > 4) {
93 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
94 return;
95 }
96 if (stride < 0) {
97 _mesa_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
98 return;
99 }
100
101 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
102 _mesa_debug(ctx, "glVertexPointer( sz %d type %s stride %d )\n", size,
103 _mesa_lookup_enum_by_nr( type ), stride);
104
105 /* always need to check that <type> is legal */
106 switch (type) {
107 case GL_SHORT:
108 elementSize = size * sizeof(GLshort);
109 break;
110 case GL_INT:
111 elementSize = size * sizeof(GLint);
112 break;
113 case GL_FLOAT:
114 elementSize = size * sizeof(GLfloat);
115 break;
116 case GL_DOUBLE:
117 elementSize = size * sizeof(GLdouble);
118 break;
119 #if FEATURE_fixedpt
120 case GL_FIXED:
121 elementSize = size * sizeof(GLfixed);
122 break;
123 #endif
124 #if FEATURE_vertex_array_byte
125 case GL_BYTE:
126 elementSize = size * sizeof(GLbyte);
127 break;
128 #endif
129 default:
130 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
131 return;
132 }
133
134 update_array(ctx, &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
135 elementSize, size, type, stride, GL_FALSE, ptr);
136
137 if (ctx->Driver.VertexPointer)
138 ctx->Driver.VertexPointer( ctx, size, type, stride, ptr );
139 }
140
141
142 void GLAPIENTRY
143 _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
144 {
145 GLsizei elementSize;
146 GET_CURRENT_CONTEXT(ctx);
147 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
148
149 if (stride < 0) {
150 _mesa_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
151 return;
152 }
153
154 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
155 _mesa_debug(ctx, "glNormalPointer( type %s stride %d )\n",
156 _mesa_lookup_enum_by_nr( type ), stride);
157
158 switch (type) {
159 case GL_BYTE:
160 elementSize = 3 * sizeof(GLbyte);
161 break;
162 case GL_SHORT:
163 elementSize = 3 * sizeof(GLshort);
164 break;
165 case GL_INT:
166 elementSize = 3 * sizeof(GLint);
167 break;
168 case GL_FLOAT:
169 elementSize = 3 * sizeof(GLfloat);
170 break;
171 case GL_DOUBLE:
172 elementSize = 3 * sizeof(GLdouble);
173 break;
174 #if FEATURE_fixedpt
175 case GL_FIXED:
176 elementSize = 3 * sizeof(GLfixed);
177 break;
178 #endif
179 default:
180 _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
181 return;
182 }
183
184 update_array(ctx, &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
185 elementSize, 3, type, stride, GL_TRUE, ptr);
186
187 if (ctx->Driver.NormalPointer)
188 ctx->Driver.NormalPointer( ctx, type, stride, ptr );
189 }
190
191
192 void GLAPIENTRY
193 _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
194 {
195 GLsizei elementSize;
196 GET_CURRENT_CONTEXT(ctx);
197 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
198
199 if (size < 3 || size > 4) {
200 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
201 return;
202 }
203 if (stride < 0) {
204 _mesa_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
205 return;
206 }
207
208 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
209 _mesa_debug(ctx, "glColorPointer( sz %d type %s stride %d )\n", size,
210 _mesa_lookup_enum_by_nr( type ), stride);
211
212 switch (type) {
213 case GL_BYTE:
214 elementSize = size * sizeof(GLbyte);
215 break;
216 case GL_UNSIGNED_BYTE:
217 elementSize = size * sizeof(GLubyte);
218 break;
219 case GL_SHORT:
220 elementSize = size * sizeof(GLshort);
221 break;
222 case GL_UNSIGNED_SHORT:
223 elementSize = size * sizeof(GLushort);
224 break;
225 case GL_INT:
226 elementSize = size * sizeof(GLint);
227 break;
228 case GL_UNSIGNED_INT:
229 elementSize = size * sizeof(GLuint);
230 break;
231 case GL_FLOAT:
232 elementSize = size * sizeof(GLfloat);
233 break;
234 case GL_DOUBLE:
235 elementSize = size * sizeof(GLdouble);
236 break;
237 #if FEATURE_fixedpt
238 case GL_FIXED:
239 elementSize = size * sizeof(GLfixed);
240 break;
241 #endif
242 default:
243 _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
244 return;
245 }
246
247 update_array(ctx, &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
248 elementSize, size, type, stride, GL_TRUE, ptr);
249
250 if (ctx->Driver.ColorPointer)
251 ctx->Driver.ColorPointer( ctx, size, type, stride, ptr );
252 }
253
254
255 void GLAPIENTRY
256 _mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
257 {
258 GLint elementSize;
259 GET_CURRENT_CONTEXT(ctx);
260 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
261
262 if (stride < 0) {
263 _mesa_error( ctx, GL_INVALID_VALUE, "glFogCoordPointer(stride)" );
264 return;
265 }
266
267 switch (type) {
268 case GL_FLOAT:
269 elementSize = sizeof(GLfloat);
270 break;
271 case GL_DOUBLE:
272 elementSize = sizeof(GLdouble);
273 break;
274 default:
275 _mesa_error( ctx, GL_INVALID_ENUM, "glFogCoordPointer(type)" );
276 return;
277 }
278
279 update_array(ctx, &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
280 elementSize, 1, type, stride, GL_FALSE, ptr);
281
282 if (ctx->Driver.FogCoordPointer)
283 ctx->Driver.FogCoordPointer( ctx, type, stride, ptr );
284 }
285
286
287 void GLAPIENTRY
288 _mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
289 {
290 GLsizei elementSize;
291 GET_CURRENT_CONTEXT(ctx);
292 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
293
294 if (stride < 0) {
295 _mesa_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
296 return;
297 }
298
299 switch (type) {
300 case GL_UNSIGNED_BYTE:
301 elementSize = sizeof(GLubyte);
302 break;
303 case GL_SHORT:
304 elementSize = sizeof(GLshort);
305 break;
306 case GL_INT:
307 elementSize = sizeof(GLint);
308 break;
309 case GL_FLOAT:
310 elementSize = sizeof(GLfloat);
311 break;
312 case GL_DOUBLE:
313 elementSize = sizeof(GLdouble);
314 break;
315 default:
316 _mesa_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
317 return;
318 }
319
320 update_array(ctx, &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
321 elementSize, 1, type, stride, GL_FALSE, ptr);
322
323 if (ctx->Driver.IndexPointer)
324 ctx->Driver.IndexPointer( ctx, type, stride, ptr );
325 }
326
327
328 void GLAPIENTRY
329 _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
330 GLsizei stride, const GLvoid *ptr)
331 {
332 GLsizei elementSize;
333 GET_CURRENT_CONTEXT(ctx);
334 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
335
336 if (size != 3 && size != 4) {
337 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(size)" );
338 return;
339 }
340 if (stride < 0) {
341 _mesa_error( ctx, GL_INVALID_VALUE, "glSecondaryColorPointer(stride)" );
342 return;
343 }
344
345 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
346 _mesa_debug(ctx, "glSecondaryColorPointer( sz %d type %s stride %d )\n",
347 size, _mesa_lookup_enum_by_nr( type ), stride);
348
349 switch (type) {
350 case GL_BYTE:
351 elementSize = size * sizeof(GLbyte);
352 break;
353 case GL_UNSIGNED_BYTE:
354 elementSize = size * sizeof(GLubyte);
355 break;
356 case GL_SHORT:
357 elementSize = size * sizeof(GLshort);
358 break;
359 case GL_UNSIGNED_SHORT:
360 elementSize = size * sizeof(GLushort);
361 break;
362 case GL_INT:
363 elementSize = size * sizeof(GLint);
364 break;
365 case GL_UNSIGNED_INT:
366 elementSize = size * sizeof(GLuint);
367 break;
368 case GL_FLOAT:
369 elementSize = size * sizeof(GLfloat);
370 break;
371 case GL_DOUBLE:
372 elementSize = size * sizeof(GLdouble);
373 break;
374 default:
375 _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
376 return;
377 }
378
379 update_array(ctx, &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1,
380 elementSize, size, type, stride, GL_TRUE, ptr);
381
382 if (ctx->Driver.SecondaryColorPointer)
383 ctx->Driver.SecondaryColorPointer( ctx, size, type, stride, ptr );
384 }
385
386
387 void GLAPIENTRY
388 _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
389 const GLvoid *ptr)
390 {
391 GLint elementSize;
392 GET_CURRENT_CONTEXT(ctx);
393 const GLuint unit = ctx->Array.ActiveTexture;
394 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
395
396 if (size < 1 || size > 4) {
397 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
398 return;
399 }
400 if (stride < 0) {
401 _mesa_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
402 return;
403 }
404
405 if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
406 _mesa_debug(ctx, "glTexCoordPointer(unit %u sz %d type %s stride %d)\n",
407 unit, size, _mesa_lookup_enum_by_nr( type ), stride);
408
409 /* always need to check that <type> is legal */
410 switch (type) {
411 case GL_SHORT:
412 elementSize = size * sizeof(GLshort);
413 break;
414 case GL_INT:
415 elementSize = size * sizeof(GLint);
416 break;
417 case GL_FLOAT:
418 elementSize = size * sizeof(GLfloat);
419 break;
420 case GL_DOUBLE:
421 elementSize = size * sizeof(GLdouble);
422 break;
423 #if FEATURE_fixedpt
424 case GL_FIXED:
425 elementSize = size * sizeof(GLfixed);
426 break;
427 #endif
428 #if FEATURE_vertex_array_byte
429 case GL_BYTE:
430 elementSize = size * sizeof(GLbyte);
431 break;
432 #endif
433 default:
434 _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
435 return;
436 }
437
438 update_array(ctx, &ctx->Array.ArrayObj->TexCoord[unit],
439 _NEW_ARRAY_TEXCOORD(unit),
440 elementSize, size, type, stride, GL_FALSE, ptr);
441
442 if (ctx->Driver.TexCoordPointer)
443 ctx->Driver.TexCoordPointer( ctx, size, type, stride, ptr );
444 }
445
446
447 void GLAPIENTRY
448 _mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
449 {
450 GET_CURRENT_CONTEXT(ctx);
451 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
452
453 if (stride < 0) {
454 _mesa_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
455 return;
456 }
457
458 update_array(ctx, &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
459 sizeof(GLboolean), 1, GL_UNSIGNED_BYTE, stride, GL_FALSE, ptr);
460
461 if (ctx->Driver.EdgeFlagPointer)
462 ctx->Driver.EdgeFlagPointer( ctx, stride, ptr );
463 }
464
465
466 void GLAPIENTRY
467 _mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr)
468 {
469 GLsizei elementSize;
470 GET_CURRENT_CONTEXT(ctx);
471 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
472
473 if (stride < 0) {
474 _mesa_error( ctx, GL_INVALID_VALUE, "glPointSizePointer(stride)" );
475 return;
476 }
477
478 switch (type) {
479 case GL_FLOAT:
480 elementSize = sizeof(GLfloat);
481 break;
482 #if FEATURE_fixedpt
483 case GL_FIXED:
484 elementSize = sizeof(GLfixed);
485 break;
486 #endif
487 default:
488 _mesa_error( ctx, GL_INVALID_ENUM, "glPointSizePointer(type)" );
489 return;
490 }
491
492 update_array(ctx, &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE,
493 elementSize, 1, type, stride, GL_FALSE, ptr);
494 }
495
496
497 #if FEATURE_NV_vertex_program
498 void GLAPIENTRY
499 _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
500 GLsizei stride, const GLvoid *ptr)
501 {
502 const GLboolean normalized = GL_FALSE;
503 GLsizei elementSize;
504 GET_CURRENT_CONTEXT(ctx);
505 ASSERT_OUTSIDE_BEGIN_END(ctx);
506
507 if (index >= MAX_VERTEX_PROGRAM_ATTRIBS) {
508 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
509 return;
510 }
511
512 if (size < 1 || size > 4) {
513 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size)");
514 return;
515 }
516
517 if (stride < 0) {
518 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(stride)");
519 return;
520 }
521
522 if (type == GL_UNSIGNED_BYTE && size != 4) {
523 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
524 return;
525 }
526
527 /* check for valid 'type' and compute StrideB right away */
528 switch (type) {
529 case GL_UNSIGNED_BYTE:
530 elementSize = size * sizeof(GLubyte);
531 break;
532 case GL_SHORT:
533 elementSize = size * sizeof(GLshort);
534 break;
535 case GL_FLOAT:
536 elementSize = size * sizeof(GLfloat);
537 break;
538 case GL_DOUBLE:
539 elementSize = size * sizeof(GLdouble);
540 break;
541 default:
542 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
543 return;
544 }
545
546 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
547 _NEW_ARRAY_ATTRIB(index),
548 elementSize, size, type, stride, normalized, ptr);
549
550 if (ctx->Driver.VertexAttribPointer)
551 ctx->Driver.VertexAttribPointer( ctx, index, size, type, stride, ptr );
552 }
553 #endif
554
555
556 #if FEATURE_ARB_vertex_program
557 void GLAPIENTRY
558 _mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
559 GLboolean normalized,
560 GLsizei stride, const GLvoid *ptr)
561 {
562 GLsizei elementSize;
563 GET_CURRENT_CONTEXT(ctx);
564 ASSERT_OUTSIDE_BEGIN_END(ctx);
565
566 if (index >= ctx->Const.VertexProgram.MaxAttribs) {
567 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
568 return;
569 }
570
571 if (size < 1 || size > 4) {
572 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(size)");
573 return;
574 }
575
576 if (stride < 0) {
577 _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(stride)");
578 return;
579 }
580
581 /* check for valid 'type' and compute StrideB right away */
582 /* NOTE: more types are supported here than in the NV extension */
583 switch (type) {
584 case GL_BYTE:
585 elementSize = size * sizeof(GLbyte);
586 break;
587 case GL_UNSIGNED_BYTE:
588 elementSize = size * sizeof(GLubyte);
589 break;
590 case GL_SHORT:
591 elementSize = size * sizeof(GLshort);
592 break;
593 case GL_UNSIGNED_SHORT:
594 elementSize = size * sizeof(GLushort);
595 break;
596 case GL_INT:
597 elementSize = size * sizeof(GLint);
598 break;
599 case GL_UNSIGNED_INT:
600 elementSize = size * sizeof(GLuint);
601 break;
602 case GL_FLOAT:
603 elementSize = size * sizeof(GLfloat);
604 break;
605 case GL_DOUBLE:
606 elementSize = size * sizeof(GLdouble);
607 break;
608 #if FEATURE_fixedpt
609 case GL_FIXED:
610 elementSize = size * sizeof(GLfixed);
611 break;
612 #endif
613 default:
614 _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerARB(type)" );
615 return;
616 }
617
618 update_array(ctx, &ctx->Array.ArrayObj->VertexAttrib[index],
619 _NEW_ARRAY_ATTRIB(index),
620 elementSize, size, type, stride, normalized, ptr);
621
622 if (ctx->Driver.VertexAttribPointer)
623 ctx->Driver.VertexAttribPointer(ctx, index, size, type, stride, ptr);
624 }
625 #endif
626
627
628 void GLAPIENTRY
629 _mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
630 GLsizei count, const GLvoid *ptr)
631 {
632 (void) count;
633 _mesa_VertexPointer(size, type, stride, ptr);
634 }
635
636
637 void GLAPIENTRY
638 _mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
639 const GLvoid *ptr)
640 {
641 (void) count;
642 _mesa_NormalPointer(type, stride, ptr);
643 }
644
645
646 void GLAPIENTRY
647 _mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
648 const GLvoid *ptr)
649 {
650 (void) count;
651 _mesa_ColorPointer(size, type, stride, ptr);
652 }
653
654
655 void GLAPIENTRY
656 _mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
657 const GLvoid *ptr)
658 {
659 (void) count;
660 _mesa_IndexPointer(type, stride, ptr);
661 }
662
663
664 void GLAPIENTRY
665 _mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
666 GLsizei count, const GLvoid *ptr)
667 {
668 (void) count;
669 _mesa_TexCoordPointer(size, type, stride, ptr);
670 }
671
672
673 void GLAPIENTRY
674 _mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
675 {
676 (void) count;
677 _mesa_EdgeFlagPointer(stride, ptr);
678 }
679
680
681 void GLAPIENTRY
682 _mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
683 {
684 GET_CURRENT_CONTEXT(ctx);
685 GLboolean tflag, cflag, nflag; /* enable/disable flags */
686 GLint tcomps, ccomps, vcomps; /* components per texcoord, color, vertex */
687 GLenum ctype = 0; /* color type */
688 GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
689 const GLint toffset = 0; /* always zero */
690 GLint defstride; /* default stride */
691 GLint c, f;
692
693 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
694
695 f = sizeof(GLfloat);
696 c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
697
698 if (stride < 0) {
699 _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
700 return;
701 }
702
703 switch (format) {
704 case GL_V2F:
705 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
706 tcomps = 0; ccomps = 0; vcomps = 2;
707 voffset = 0;
708 defstride = 2*f;
709 break;
710 case GL_V3F:
711 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_FALSE;
712 tcomps = 0; ccomps = 0; vcomps = 3;
713 voffset = 0;
714 defstride = 3*f;
715 break;
716 case GL_C4UB_V2F:
717 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
718 tcomps = 0; ccomps = 4; vcomps = 2;
719 ctype = GL_UNSIGNED_BYTE;
720 coffset = 0;
721 voffset = c;
722 defstride = c + 2*f;
723 break;
724 case GL_C4UB_V3F:
725 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
726 tcomps = 0; ccomps = 4; vcomps = 3;
727 ctype = GL_UNSIGNED_BYTE;
728 coffset = 0;
729 voffset = c;
730 defstride = c + 3*f;
731 break;
732 case GL_C3F_V3F:
733 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_FALSE;
734 tcomps = 0; ccomps = 3; vcomps = 3;
735 ctype = GL_FLOAT;
736 coffset = 0;
737 voffset = 3*f;
738 defstride = 6*f;
739 break;
740 case GL_N3F_V3F:
741 tflag = GL_FALSE; cflag = GL_FALSE; nflag = GL_TRUE;
742 tcomps = 0; ccomps = 0; vcomps = 3;
743 noffset = 0;
744 voffset = 3*f;
745 defstride = 6*f;
746 break;
747 case GL_C4F_N3F_V3F:
748 tflag = GL_FALSE; cflag = GL_TRUE; nflag = GL_TRUE;
749 tcomps = 0; ccomps = 4; vcomps = 3;
750 ctype = GL_FLOAT;
751 coffset = 0;
752 noffset = 4*f;
753 voffset = 7*f;
754 defstride = 10*f;
755 break;
756 case GL_T2F_V3F:
757 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
758 tcomps = 2; ccomps = 0; vcomps = 3;
759 voffset = 2*f;
760 defstride = 5*f;
761 break;
762 case GL_T4F_V4F:
763 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_FALSE;
764 tcomps = 4; ccomps = 0; vcomps = 4;
765 voffset = 4*f;
766 defstride = 8*f;
767 break;
768 case GL_T2F_C4UB_V3F:
769 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
770 tcomps = 2; ccomps = 4; vcomps = 3;
771 ctype = GL_UNSIGNED_BYTE;
772 coffset = 2*f;
773 voffset = c+2*f;
774 defstride = c+5*f;
775 break;
776 case GL_T2F_C3F_V3F:
777 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_FALSE;
778 tcomps = 2; ccomps = 3; vcomps = 3;
779 ctype = GL_FLOAT;
780 coffset = 2*f;
781 voffset = 5*f;
782 defstride = 8*f;
783 break;
784 case GL_T2F_N3F_V3F:
785 tflag = GL_TRUE; cflag = GL_FALSE; nflag = GL_TRUE;
786 tcomps = 2; ccomps = 0; vcomps = 3;
787 noffset = 2*f;
788 voffset = 5*f;
789 defstride = 8*f;
790 break;
791 case GL_T2F_C4F_N3F_V3F:
792 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
793 tcomps = 2; ccomps = 4; vcomps = 3;
794 ctype = GL_FLOAT;
795 coffset = 2*f;
796 noffset = 6*f;
797 voffset = 9*f;
798 defstride = 12*f;
799 break;
800 case GL_T4F_C4F_N3F_V4F:
801 tflag = GL_TRUE; cflag = GL_TRUE; nflag = GL_TRUE;
802 tcomps = 4; ccomps = 4; vcomps = 4;
803 ctype = GL_FLOAT;
804 coffset = 4*f;
805 noffset = 8*f;
806 voffset = 11*f;
807 defstride = 15*f;
808 break;
809 default:
810 _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
811 return;
812 }
813
814 if (stride==0) {
815 stride = defstride;
816 }
817
818 _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
819 _mesa_DisableClientState( GL_INDEX_ARRAY );
820 /* XXX also disable secondary color and generic arrays? */
821
822 /* Texcoords */
823 if (tflag) {
824 _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
825 _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
826 (GLubyte *) pointer + toffset );
827 }
828 else {
829 _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
830 }
831
832 /* Color */
833 if (cflag) {
834 _mesa_EnableClientState( GL_COLOR_ARRAY );
835 _mesa_ColorPointer( ccomps, ctype, stride,
836 (GLubyte *) pointer + coffset );
837 }
838 else {
839 _mesa_DisableClientState( GL_COLOR_ARRAY );
840 }
841
842
843 /* Normals */
844 if (nflag) {
845 _mesa_EnableClientState( GL_NORMAL_ARRAY );
846 _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
847 }
848 else {
849 _mesa_DisableClientState( GL_NORMAL_ARRAY );
850 }
851
852 /* Vertices */
853 _mesa_EnableClientState( GL_VERTEX_ARRAY );
854 _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
855 (GLubyte *) pointer + voffset );
856 }
857
858
859 void GLAPIENTRY
860 _mesa_LockArraysEXT(GLint first, GLsizei count)
861 {
862 GET_CURRENT_CONTEXT(ctx);
863 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
864
865 if (MESA_VERBOSE & VERBOSE_API)
866 _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
867
868 if (first == 0 && count > 0 &&
869 count <= (GLint) ctx->Const.MaxArrayLockSize) {
870 ctx->Array.LockFirst = first;
871 ctx->Array.LockCount = count;
872 }
873 else {
874 ctx->Array.LockFirst = 0;
875 ctx->Array.LockCount = 0;
876 }
877
878 ctx->NewState |= _NEW_ARRAY;
879 ctx->Array.NewState |= _NEW_ARRAY_ALL;
880
881 if (ctx->Driver.LockArraysEXT)
882 ctx->Driver.LockArraysEXT( ctx, first, count );
883 }
884
885
886 void GLAPIENTRY
887 _mesa_UnlockArraysEXT( void )
888 {
889 GET_CURRENT_CONTEXT(ctx);
890 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
891
892 if (MESA_VERBOSE & VERBOSE_API)
893 _mesa_debug(ctx, "glUnlockArrays\n");
894
895 ctx->Array.LockFirst = 0;
896 ctx->Array.LockCount = 0;
897 ctx->NewState |= _NEW_ARRAY;
898 ctx->Array.NewState |= _NEW_ARRAY_ALL;
899
900 if (ctx->Driver.UnlockArraysEXT)
901 ctx->Driver.UnlockArraysEXT( ctx );
902 }
903
904
905 /* GL_EXT_multi_draw_arrays */
906 /* Somebody forgot to spec the first and count parameters as const! <sigh> */
907 void GLAPIENTRY
908 _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
909 GLsizei *count, GLsizei primcount )
910 {
911 GET_CURRENT_CONTEXT(ctx);
912 GLint i;
913
914 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
915
916 for (i = 0; i < primcount; i++) {
917 if (count[i] > 0) {
918 CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
919 }
920 }
921 }
922
923
924 /* GL_EXT_multi_draw_arrays */
925 void GLAPIENTRY
926 _mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
927 const GLvoid **indices, GLsizei primcount )
928 {
929 GET_CURRENT_CONTEXT(ctx);
930 GLint i;
931
932 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
933
934 for (i = 0; i < primcount; i++) {
935 if (count[i] > 0) {
936 CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i]));
937 }
938 }
939 }
940
941
942 /* GL_IBM_multimode_draw_arrays */
943 void GLAPIENTRY
944 _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
945 const GLsizei * count,
946 GLsizei primcount, GLint modestride )
947 {
948 GET_CURRENT_CONTEXT(ctx);
949 GLint i;
950
951 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
952
953 for ( i = 0 ; i < primcount ; i++ ) {
954 if ( count[i] > 0 ) {
955 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
956 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] ));
957 }
958 }
959 }
960
961
962 /* GL_IBM_multimode_draw_arrays */
963 void GLAPIENTRY
964 _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
965 GLenum type, const GLvoid * const * indices,
966 GLsizei primcount, GLint modestride )
967 {
968 GET_CURRENT_CONTEXT(ctx);
969 GLint i;
970
971 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
972
973 /* XXX not sure about ARB_vertex_buffer_object handling here */
974
975 for ( i = 0 ; i < primcount ; i++ ) {
976 if ( count[i] > 0 ) {
977 GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
978 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] ));
979 }
980 }
981 }
982
983
984 /**
985 * Initialize vertex array state for given context.
986 */
987 void
988 _mesa_init_varray(GLcontext *ctx)
989 {
990 ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0);
991 ctx->Array.ArrayObj = ctx->Array.DefaultArrayObj;
992
993 ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */
994 }