varray.c revision 422f3bb8ab95f00e17aa969f7a09c7ceee5f8bef
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.6
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27#include "glheader.h"
28#include "imports.h"
29#include "bufferobj.h"
30#include "context.h"
31#include "enable.h"
32#include "enums.h"
33#include "hash.h"
34#include "image.h"
35#include "macros.h"
36#include "mfeatures.h"
37#include "mtypes.h"
38#include "varray.h"
39#include "arrayobj.h"
40#include "main/dispatch.h"
41
42
43/** Used to do error checking for GL_EXT_vertex_array_bgra */
44#define BGRA_OR_4  5
45
46
47/** Used to indicate which GL datatypes are accepted by each of the
48 * glVertex/Color/Attrib/EtcPointer() functions.
49 */
50#define BOOL_BIT             0x1
51#define BYTE_BIT             0x2
52#define UNSIGNED_BYTE_BIT    0x4
53#define SHORT_BIT            0x8
54#define UNSIGNED_SHORT_BIT   0x10
55#define INT_BIT              0x20
56#define UNSIGNED_INT_BIT     0x40
57#define HALF_BIT             0x80
58#define FLOAT_BIT            0x100
59#define DOUBLE_BIT           0x200
60#define FIXED_ES_BIT         0x400
61#define FIXED_GL_BIT         0x800
62#define UNSIGNED_INT_2_10_10_10_REV_BIT 0x1000
63#define INT_2_10_10_10_REV_BIT 0x2000
64
65
66/** Convert GL datatype enum into a <type>_BIT value seen above */
67static GLbitfield
68type_to_bit(const struct gl_context *ctx, GLenum type)
69{
70   switch (type) {
71   case GL_BOOL:
72      return BOOL_BIT;
73   case GL_BYTE:
74      return BYTE_BIT;
75   case GL_UNSIGNED_BYTE:
76      return UNSIGNED_BYTE_BIT;
77   case GL_SHORT:
78      return SHORT_BIT;
79   case GL_UNSIGNED_SHORT:
80      return UNSIGNED_SHORT_BIT;
81   case GL_INT:
82      return INT_BIT;
83   case GL_UNSIGNED_INT:
84      return UNSIGNED_INT_BIT;
85   case GL_HALF_FLOAT:
86      if (ctx->Extensions.ARB_half_float_vertex)
87         return HALF_BIT;
88      else
89         return 0x0;
90   case GL_FLOAT:
91      return FLOAT_BIT;
92   case GL_DOUBLE:
93      return DOUBLE_BIT;
94   case GL_FIXED:
95      return _mesa_is_desktop_gl(ctx) ? FIXED_GL_BIT : FIXED_ES_BIT;
96   case GL_UNSIGNED_INT_2_10_10_10_REV:
97      return UNSIGNED_INT_2_10_10_10_REV_BIT;
98   case GL_INT_2_10_10_10_REV:
99      return INT_2_10_10_10_REV_BIT;
100   default:
101      return 0;
102   }
103}
104
105
106/**
107 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
108 * functions.
109 *
110 * \param func  name of calling function used for error reporting
111 * \param attrib  the attribute array index to update
112 * \param legalTypes  bitmask of *_BIT above indicating legal datatypes
113 * \param sizeMin  min allowable size value
114 * \param sizeMax  max allowable size value (may also be BGRA_OR_4)
115 * \param size  components per element (1, 2, 3 or 4)
116 * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
117 * \param stride  stride between elements, in elements
118 * \param normalized  are integer types converted to floats in [-1, 1]?
119 * \param integer  integer-valued values (will not be normalized to [-1,1])
120 * \param ptr  the address (or offset inside VBO) of the array data
121 */
122static void
123update_array(struct gl_context *ctx,
124             const char *func,
125             GLuint attrib, GLbitfield legalTypesMask,
126             GLint sizeMin, GLint sizeMax,
127             GLint size, GLenum type, GLsizei stride,
128             GLboolean normalized, GLboolean integer,
129             const GLvoid *ptr)
130{
131   struct gl_client_array *array;
132   GLbitfield typeBit;
133   GLsizei elementSize;
134   GLenum format = GL_RGBA;
135
136   /* Page 407 (page 423 of the PDF) of the OpenGL 3.0 spec says:
137    *
138    *     "Client vertex arrays - all vertex array attribute pointers must
139    *     refer to buffer objects (section 2.9.2). The default vertex array
140    *     object (the name zero) is also deprecated. Calling
141    *     VertexAttribPointer when no buffer object or no vertex array object
142    *     is bound will generate an INVALID_OPERATION error..."
143    *
144    * The check for VBOs is handled below.
145    */
146   if (ctx->API == API_OPENGL_CORE
147       && (ctx->Array.ArrayObj == ctx->Array.DefaultArrayObj)) {
148      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)",
149                  func);
150      return;
151   }
152
153   if (_mesa_is_gles(ctx)) {
154      /* Once Mesa gets support for GL_OES_vertex_half_float this mask will
155       * change.  Adding support for this extension isn't quite as trivial as
156       * we'd like because ES uses a different enum value for GL_HALF_FLOAT.
157       */
158      legalTypesMask &= ~(FIXED_GL_BIT | HALF_BIT | DOUBLE_BIT);
159
160      /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until
161       * 3.0.  The 2_10_10_10 types are added in OpenGL ES 3.0 or
162       * GL_OES_vertex_type_10_10_10_2.
163       */
164      if (ctx->Version < 30) {
165         legalTypesMask &= ~(UNSIGNED_INT_BIT
166                             | INT_BIT
167                             | UNSIGNED_INT_2_10_10_10_REV_BIT
168                             | INT_2_10_10_10_REV_BIT);
169      }
170
171      /* BGRA ordering is not supported in ES contexts.
172       */
173      if (sizeMax == BGRA_OR_4)
174         sizeMax = 4;
175   } else {
176      legalTypesMask &= ~FIXED_ES_BIT;
177
178      if (!ctx->Extensions.ARB_ES2_compatibility)
179         legalTypesMask &= ~FIXED_GL_BIT;
180
181      if (!ctx->Extensions.ARB_vertex_type_2_10_10_10_rev)
182         legalTypesMask &= ~(UNSIGNED_INT_2_10_10_10_REV_BIT |
183                             INT_2_10_10_10_REV_BIT);
184   }
185
186   typeBit = type_to_bit(ctx, type);
187   if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
188      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
189                  func, _mesa_lookup_enum_by_nr(type));
190      return;
191   }
192
193   /* Do size parameter checking.
194    * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
195    * must be handled specially.
196    */
197   if (ctx->Extensions.EXT_vertex_array_bgra &&
198       sizeMax == BGRA_OR_4 &&
199       size == GL_BGRA) {
200      GLboolean bgra_error = GL_FALSE;
201
202      if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev) {
203         if (type != GL_UNSIGNED_INT_2_10_10_10_REV &&
204             type != GL_INT_2_10_10_10_REV &&
205             type != GL_UNSIGNED_BYTE)
206            bgra_error = GL_TRUE;
207      } else if (type != GL_UNSIGNED_BYTE)
208         bgra_error = GL_TRUE;
209
210      if (bgra_error) {
211         _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func);
212         return;
213      }
214      format = GL_BGRA;
215      size = 4;
216   }
217   else if (size < sizeMin || size > sizeMax || size > 4) {
218      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
219      return;
220   }
221
222   if (ctx->Extensions.ARB_vertex_type_2_10_10_10_rev &&
223       (type == GL_UNSIGNED_INT_2_10_10_10_REV ||
224        type == GL_INT_2_10_10_10_REV) && size != 4) {
225      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(size=%d)", func, size);
226      return;
227   }
228
229   ASSERT(size <= 4);
230
231   if (stride < 0) {
232      _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
233      return;
234   }
235
236   /* Page 29 (page 44 of the PDF) of the OpenGL 3.3 spec says:
237    *
238    *     "An INVALID_OPERATION error is generated under any of the following
239    *     conditions:
240    *
241    *     ...
242    *
243    *     * any of the *Pointer commands specifying the location and
244    *       organization of vertex array data are called while zero is bound
245    *       to the ARRAY_BUFFER buffer object binding point (see section
246    *       2.9.6), and the pointer argument is not NULL."
247    */
248   if (ptr != NULL && ctx->Array.ArrayObj->ARBsemantics &&
249       !_mesa_is_bufferobj(ctx->Array.ArrayBufferObj)) {
250      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
251      return;
252   }
253
254   elementSize = _mesa_sizeof_type(type) * size;
255
256   array = &ctx->Array.ArrayObj->VertexAttrib[attrib];
257   array->Size = size;
258   array->Type = type;
259   array->Format = format;
260   array->Stride = stride;
261   array->StrideB = stride ? stride : elementSize;
262   array->Normalized = normalized;
263   array->Integer = integer;
264   array->Ptr = (const GLubyte *) ptr;
265   array->_ElementSize = elementSize;
266
267   _mesa_reference_buffer_object(ctx, &array->BufferObj,
268                                 ctx->Array.ArrayBufferObj);
269
270   ctx->NewState |= _NEW_ARRAY;
271   ctx->Array.ArrayObj->NewArrays |= VERT_BIT(attrib);
272}
273
274
275void GLAPIENTRY
276_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
277{
278   GET_CURRENT_CONTEXT(ctx);
279   GLbitfield legalTypes = (ctx->API == API_OPENGLES)
280      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
281      : (SHORT_BIT | INT_BIT | FLOAT_BIT |
282         DOUBLE_BIT | HALF_BIT |
283         UNSIGNED_INT_2_10_10_10_REV_BIT |
284         INT_2_10_10_10_REV_BIT);
285   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
286
287   update_array(ctx, "glVertexPointer", VERT_ATTRIB_POS,
288                legalTypes, 2, 4,
289                size, type, stride, GL_FALSE, GL_FALSE, ptr);
290}
291
292
293void GLAPIENTRY
294_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
295{
296   GET_CURRENT_CONTEXT(ctx);
297   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
298      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
299      : (BYTE_BIT | SHORT_BIT | INT_BIT |
300         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
301         UNSIGNED_INT_2_10_10_10_REV_BIT |
302         INT_2_10_10_10_REV_BIT);
303   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
304
305   update_array(ctx, "glNormalPointer", VERT_ATTRIB_NORMAL,
306                legalTypes, 3, 3,
307                3, type, stride, GL_TRUE, GL_FALSE, ptr);
308}
309
310
311void GLAPIENTRY
312_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
313{
314   GET_CURRENT_CONTEXT(ctx);
315   const GLbitfield legalTypes = (ctx->API == API_OPENGLES)
316      ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT)
317      : (BYTE_BIT | UNSIGNED_BYTE_BIT |
318         SHORT_BIT | UNSIGNED_SHORT_BIT |
319         INT_BIT | UNSIGNED_INT_BIT |
320         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
321         UNSIGNED_INT_2_10_10_10_REV_BIT |
322         INT_2_10_10_10_REV_BIT);
323   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3;
324   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
325
326   update_array(ctx, "glColorPointer", VERT_ATTRIB_COLOR0,
327                legalTypes, sizeMin, BGRA_OR_4,
328                size, type, stride, GL_TRUE, GL_FALSE, ptr);
329}
330
331
332void GLAPIENTRY
333_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
334{
335   const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
336   GET_CURRENT_CONTEXT(ctx);
337   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
338
339   update_array(ctx, "glFogCoordPointer", VERT_ATTRIB_FOG,
340                legalTypes, 1, 1,
341                1, type, stride, GL_FALSE, GL_FALSE, ptr);
342}
343
344
345void GLAPIENTRY
346_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
347{
348   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
349                                  FLOAT_BIT | DOUBLE_BIT);
350   GET_CURRENT_CONTEXT(ctx);
351   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
352
353   update_array(ctx, "glIndexPointer", VERT_ATTRIB_COLOR_INDEX,
354                legalTypes, 1, 1,
355                1, type, stride, GL_FALSE, GL_FALSE, ptr);
356}
357
358
359void GLAPIENTRY
360_mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
361			       GLsizei stride, const GLvoid *ptr)
362{
363   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
364                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
365                                  INT_BIT | UNSIGNED_INT_BIT |
366                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
367                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
368                                  INT_2_10_10_10_REV_BIT);
369   GET_CURRENT_CONTEXT(ctx);
370   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
371
372   update_array(ctx, "glSecondaryColorPointer", VERT_ATTRIB_COLOR1,
373                legalTypes, 3, BGRA_OR_4,
374                size, type, stride, GL_TRUE, GL_FALSE, ptr);
375}
376
377
378void GLAPIENTRY
379_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
380                      const GLvoid *ptr)
381{
382   GET_CURRENT_CONTEXT(ctx);
383   GLbitfield legalTypes = (ctx->API == API_OPENGLES)
384      ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT)
385      : (SHORT_BIT | INT_BIT |
386         HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
387         UNSIGNED_INT_2_10_10_10_REV_BIT |
388         INT_2_10_10_10_REV_BIT);
389   const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1;
390   const GLuint unit = ctx->Array.ActiveTexture;
391   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
392
393   update_array(ctx, "glTexCoordPointer", VERT_ATTRIB_TEX(unit),
394                legalTypes, sizeMin, 4,
395                size, type, stride, GL_FALSE, GL_FALSE,
396                ptr);
397}
398
399
400void GLAPIENTRY
401_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
402{
403   const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
404   /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */
405   const GLboolean integer = GL_TRUE;
406   GET_CURRENT_CONTEXT(ctx);
407   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
408
409   update_array(ctx, "glEdgeFlagPointer", VERT_ATTRIB_EDGEFLAG,
410                legalTypes, 1, 1,
411                1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr);
412}
413
414
415void GLAPIENTRY
416_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr)
417{
418   const GLbitfield legalTypes = (FLOAT_BIT | FIXED_ES_BIT);
419   GET_CURRENT_CONTEXT(ctx);
420   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
421
422   if (ctx->API != API_OPENGLES) {
423      _mesa_error(ctx, GL_INVALID_OPERATION,
424                  "glPointSizePointer(ES 1.x only)");
425      return;
426   }
427
428   update_array(ctx, "glPointSizePointer", VERT_ATTRIB_POINT_SIZE,
429                legalTypes, 1, 1,
430                1, type, stride, GL_FALSE, GL_FALSE, ptr);
431}
432
433
434#if FEATURE_NV_vertex_program
435/**
436 * Set a vertex attribute array.
437 * Note that these arrays DO alias the conventional GL vertex arrays
438 * (position, normal, color, fog, texcoord, etc).
439 * The generic attribute slots at #16 and above are not touched.
440 */
441void GLAPIENTRY
442_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
443                            GLsizei stride, const GLvoid *ptr)
444{
445   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT |
446                                  FLOAT_BIT | DOUBLE_BIT);
447   GLboolean normalized = GL_FALSE;
448   GET_CURRENT_CONTEXT(ctx);
449   ASSERT_OUTSIDE_BEGIN_END(ctx);
450
451   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
452      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
453      return;
454   }
455
456   if (type == GL_UNSIGNED_BYTE && size != 4) {
457      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
458      return;
459   }
460
461   update_array(ctx, "glVertexAttribPointerNV", VERT_ATTRIB_GENERIC(index),
462                legalTypes, 1, BGRA_OR_4,
463                size, type, stride, normalized, GL_FALSE, ptr);
464}
465#endif
466
467
468#if FEATURE_ARB_vertex_program
469/**
470 * Set a generic vertex attribute array.
471 * Note that these arrays DO NOT alias the conventional GL vertex arrays
472 * (position, normal, color, fog, texcoord, etc).
473 */
474void GLAPIENTRY
475_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
476                             GLboolean normalized,
477                             GLsizei stride, const GLvoid *ptr)
478{
479   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
480                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
481                                  INT_BIT | UNSIGNED_INT_BIT |
482                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
483                                  FIXED_ES_BIT | FIXED_GL_BIT |
484                                  UNSIGNED_INT_2_10_10_10_REV_BIT |
485                                  INT_2_10_10_10_REV_BIT);
486   GET_CURRENT_CONTEXT(ctx);
487   ASSERT_OUTSIDE_BEGIN_END(ctx);
488
489   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
490      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
491      return;
492   }
493
494   update_array(ctx, "glVertexAttribPointer", VERT_ATTRIB_GENERIC(index),
495                legalTypes, 1, BGRA_OR_4,
496                size, type, stride, normalized, GL_FALSE, ptr);
497}
498#endif
499
500
501/**
502 * GL_EXT_gpu_shader4 / GL 3.0.
503 * Set an integer-valued vertex attribute array.
504 * Note that these arrays DO NOT alias the conventional GL vertex arrays
505 * (position, normal, color, fog, texcoord, etc).
506 */
507void GLAPIENTRY
508_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
509                           GLsizei stride, const GLvoid *ptr)
510{
511   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
512                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
513                                  INT_BIT | UNSIGNED_INT_BIT);
514   const GLboolean normalized = GL_FALSE;
515   const GLboolean integer = GL_TRUE;
516   GET_CURRENT_CONTEXT(ctx);
517   ASSERT_OUTSIDE_BEGIN_END(ctx);
518
519   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
520      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
521      return;
522   }
523
524   update_array(ctx, "glVertexAttribIPointer", VERT_ATTRIB_GENERIC(index),
525                legalTypes, 1, 4,
526                size, type, stride, normalized, integer, ptr);
527}
528
529
530
531void GLAPIENTRY
532_mesa_EnableVertexAttribArrayARB(GLuint index)
533{
534   struct gl_array_object *arrayObj;
535   GET_CURRENT_CONTEXT(ctx);
536   ASSERT_OUTSIDE_BEGIN_END(ctx);
537
538   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
539      _mesa_error(ctx, GL_INVALID_VALUE,
540                  "glEnableVertexAttribArrayARB(index)");
541      return;
542   }
543
544   arrayObj = ctx->Array.ArrayObj;
545
546   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib));
547
548   if (!arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
549      /* was disabled, now being enabled */
550      FLUSH_VERTICES(ctx, _NEW_ARRAY);
551      arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_TRUE;
552      arrayObj->_Enabled |= VERT_BIT_GENERIC(index);
553      arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
554   }
555}
556
557
558void GLAPIENTRY
559_mesa_DisableVertexAttribArrayARB(GLuint index)
560{
561   struct gl_array_object *arrayObj;
562   GET_CURRENT_CONTEXT(ctx);
563   ASSERT_OUTSIDE_BEGIN_END(ctx);
564
565   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
566      _mesa_error(ctx, GL_INVALID_VALUE,
567                  "glDisableVertexAttribArrayARB(index)");
568      return;
569   }
570
571   arrayObj = ctx->Array.ArrayObj;
572
573   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(arrayObj->VertexAttrib));
574
575   if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled) {
576      /* was enabled, now being disabled */
577      FLUSH_VERTICES(ctx, _NEW_ARRAY);
578      arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Enabled = GL_FALSE;
579      arrayObj->_Enabled &= ~VERT_BIT_GENERIC(index);
580      arrayObj->NewArrays |= VERT_BIT_GENERIC(index);
581   }
582}
583
584
585/**
586 * Return info for a vertex attribute array (no alias with legacy
587 * vertex attributes (pos, normal, color, etc)).  This function does
588 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
589 */
590static GLuint
591get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
592                  const char *caller)
593{
594   const struct gl_client_array *array;
595
596   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
597      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
598      return 0;
599   }
600
601   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
602
603   array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
604
605   switch (pname) {
606   case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
607      return array->Enabled;
608   case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
609      return array->Size;
610   case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
611      return array->Stride;
612   case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
613      return array->Type;
614   case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
615      return array->Normalized;
616   case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
617      return array->BufferObj->Name;
618   case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
619      if ((_mesa_is_desktop_gl(ctx)
620           && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))
621          || _mesa_is_gles3(ctx)) {
622         return array->Integer;
623      }
624      goto error;
625   case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB:
626      if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays)
627          || _mesa_is_gles3(ctx)) {
628         return array->InstanceDivisor;
629      }
630      goto error;
631   default:
632      ; /* fall-through */
633   }
634
635error:
636   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
637   return 0;
638}
639
640
641static const GLfloat *
642get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
643{
644   if (index == 0) {
645      /* In OpenGL 3.1 attribute 0 becomes non-magic, just like in OpenGL ES
646       * 2.0.  Note that we cannot just check for API_OPENGL_CORE here because
647       * that will erroneously allow this usage in a 3.0 forward-compatible
648       * context too.
649       */
650      if ((ctx->API != API_OPENGL_CORE || ctx->Version < 31)
651          && ctx->API != API_OPENGLES2) {
652	 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
653	 return NULL;
654      }
655   }
656   else if (index >= ctx->Const.VertexProgram.MaxAttribs) {
657      _mesa_error(ctx, GL_INVALID_VALUE,
658		  "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
659      return NULL;
660   }
661
662   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
663
664   FLUSH_CURRENT(ctx, 0);
665   return ctx->Current.Attrib[VERT_ATTRIB_GENERIC(index)];
666}
667
668void GLAPIENTRY
669_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
670{
671   GET_CURRENT_CONTEXT(ctx);
672   ASSERT_OUTSIDE_BEGIN_END(ctx);
673
674   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
675      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
676      if (v != NULL) {
677         COPY_4V(params, v);
678      }
679   }
680   else {
681      params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname,
682                                                    "glGetVertexAttribfv");
683   }
684}
685
686
687void GLAPIENTRY
688_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
689{
690   GET_CURRENT_CONTEXT(ctx);
691   ASSERT_OUTSIDE_BEGIN_END(ctx);
692
693   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
694      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
695      if (v != NULL) {
696         params[0] = (GLdouble) v[0];
697         params[1] = (GLdouble) v[1];
698         params[2] = (GLdouble) v[2];
699         params[3] = (GLdouble) v[3];
700      }
701   }
702   else {
703      params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname,
704                                                     "glGetVertexAttribdv");
705   }
706}
707
708
709void GLAPIENTRY
710_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
711{
712   GET_CURRENT_CONTEXT(ctx);
713   ASSERT_OUTSIDE_BEGIN_END(ctx);
714
715   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
716      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
717      if (v != NULL) {
718         /* XXX should floats in[0,1] be scaled to full int range? */
719         params[0] = (GLint) v[0];
720         params[1] = (GLint) v[1];
721         params[2] = (GLint) v[2];
722         params[3] = (GLint) v[3];
723      }
724   }
725   else {
726      params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
727                                                  "glGetVertexAttribiv");
728   }
729}
730
731
732/** GL 3.0 */
733void GLAPIENTRY
734_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
735{
736   GET_CURRENT_CONTEXT(ctx);
737   ASSERT_OUTSIDE_BEGIN_END(ctx);
738
739   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
740      const GLint *v = (const GLint *)
741	 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
742      if (v != NULL) {
743         COPY_4V(params, v);
744      }
745   }
746   else {
747      params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
748                                                  "glGetVertexAttribIiv");
749   }
750}
751
752
753/** GL 3.0 */
754void GLAPIENTRY
755_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
756{
757   GET_CURRENT_CONTEXT(ctx);
758   ASSERT_OUTSIDE_BEGIN_END(ctx);
759
760   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
761      const GLuint *v = (const GLuint *)
762	 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
763      if (v != NULL) {
764         COPY_4V(params, v);
765      }
766   }
767   else {
768      params[0] = get_vertex_array_attrib(ctx, index, pname,
769                                          "glGetVertexAttribIuiv");
770   }
771}
772
773
774void GLAPIENTRY
775_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
776{
777   GET_CURRENT_CONTEXT(ctx);
778   ASSERT_OUTSIDE_BEGIN_END(ctx);
779
780   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
781      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
782      return;
783   }
784
785   if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
786      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
787      return;
788   }
789
790   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
791
792   *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)].Ptr;
793}
794
795
796void GLAPIENTRY
797_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
798                       GLsizei count, const GLvoid *ptr)
799{
800   (void) count;
801   _mesa_VertexPointer(size, type, stride, ptr);
802}
803
804
805void GLAPIENTRY
806_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
807                       const GLvoid *ptr)
808{
809   (void) count;
810   _mesa_NormalPointer(type, stride, ptr);
811}
812
813
814void GLAPIENTRY
815_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
816                      const GLvoid *ptr)
817{
818   (void) count;
819   _mesa_ColorPointer(size, type, stride, ptr);
820}
821
822
823void GLAPIENTRY
824_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
825                      const GLvoid *ptr)
826{
827   (void) count;
828   _mesa_IndexPointer(type, stride, ptr);
829}
830
831
832void GLAPIENTRY
833_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
834                         GLsizei count, const GLvoid *ptr)
835{
836   (void) count;
837   _mesa_TexCoordPointer(size, type, stride, ptr);
838}
839
840
841void GLAPIENTRY
842_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
843{
844   (void) count;
845   _mesa_EdgeFlagPointer(stride, ptr);
846}
847
848
849void GLAPIENTRY
850_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
851{
852   GET_CURRENT_CONTEXT(ctx);
853   GLboolean tflag, cflag, nflag;  /* enable/disable flags */
854   GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
855   GLenum ctype = 0;               /* color type */
856   GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
857   const GLint toffset = 0;        /* always zero */
858   GLint defstride;                /* default stride */
859   GLint c, f;
860
861   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
862
863   f = sizeof(GLfloat);
864   c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
865
866   if (stride < 0) {
867      _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
868      return;
869   }
870
871   switch (format) {
872      case GL_V2F:
873         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
874         tcomps = 0;  ccomps = 0;  vcomps = 2;
875         voffset = 0;
876         defstride = 2*f;
877         break;
878      case GL_V3F:
879         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
880         tcomps = 0;  ccomps = 0;  vcomps = 3;
881         voffset = 0;
882         defstride = 3*f;
883         break;
884      case GL_C4UB_V2F:
885         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
886         tcomps = 0;  ccomps = 4;  vcomps = 2;
887         ctype = GL_UNSIGNED_BYTE;
888         coffset = 0;
889         voffset = c;
890         defstride = c + 2*f;
891         break;
892      case GL_C4UB_V3F:
893         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
894         tcomps = 0;  ccomps = 4;  vcomps = 3;
895         ctype = GL_UNSIGNED_BYTE;
896         coffset = 0;
897         voffset = c;
898         defstride = c + 3*f;
899         break;
900      case GL_C3F_V3F:
901         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
902         tcomps = 0;  ccomps = 3;  vcomps = 3;
903         ctype = GL_FLOAT;
904         coffset = 0;
905         voffset = 3*f;
906         defstride = 6*f;
907         break;
908      case GL_N3F_V3F:
909         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
910         tcomps = 0;  ccomps = 0;  vcomps = 3;
911         noffset = 0;
912         voffset = 3*f;
913         defstride = 6*f;
914         break;
915      case GL_C4F_N3F_V3F:
916         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
917         tcomps = 0;  ccomps = 4;  vcomps = 3;
918         ctype = GL_FLOAT;
919         coffset = 0;
920         noffset = 4*f;
921         voffset = 7*f;
922         defstride = 10*f;
923         break;
924      case GL_T2F_V3F:
925         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
926         tcomps = 2;  ccomps = 0;  vcomps = 3;
927         voffset = 2*f;
928         defstride = 5*f;
929         break;
930      case GL_T4F_V4F:
931         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
932         tcomps = 4;  ccomps = 0;  vcomps = 4;
933         voffset = 4*f;
934         defstride = 8*f;
935         break;
936      case GL_T2F_C4UB_V3F:
937         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
938         tcomps = 2;  ccomps = 4;  vcomps = 3;
939         ctype = GL_UNSIGNED_BYTE;
940         coffset = 2*f;
941         voffset = c+2*f;
942         defstride = c+5*f;
943         break;
944      case GL_T2F_C3F_V3F:
945         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
946         tcomps = 2;  ccomps = 3;  vcomps = 3;
947         ctype = GL_FLOAT;
948         coffset = 2*f;
949         voffset = 5*f;
950         defstride = 8*f;
951         break;
952      case GL_T2F_N3F_V3F:
953         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
954         tcomps = 2;  ccomps = 0;  vcomps = 3;
955         noffset = 2*f;
956         voffset = 5*f;
957         defstride = 8*f;
958         break;
959      case GL_T2F_C4F_N3F_V3F:
960         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
961         tcomps = 2;  ccomps = 4;  vcomps = 3;
962         ctype = GL_FLOAT;
963         coffset = 2*f;
964         noffset = 6*f;
965         voffset = 9*f;
966         defstride = 12*f;
967         break;
968      case GL_T4F_C4F_N3F_V4F:
969         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
970         tcomps = 4;  ccomps = 4;  vcomps = 4;
971         ctype = GL_FLOAT;
972         coffset = 4*f;
973         noffset = 8*f;
974         voffset = 11*f;
975         defstride = 15*f;
976         break;
977      default:
978         _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
979         return;
980   }
981
982   if (stride==0) {
983      stride = defstride;
984   }
985
986   _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
987   _mesa_DisableClientState( GL_INDEX_ARRAY );
988   /* XXX also disable secondary color and generic arrays? */
989
990   /* Texcoords */
991   if (tflag) {
992      _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
993      _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
994                             (GLubyte *) pointer + toffset );
995   }
996   else {
997      _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
998   }
999
1000   /* Color */
1001   if (cflag) {
1002      _mesa_EnableClientState( GL_COLOR_ARRAY );
1003      _mesa_ColorPointer( ccomps, ctype, stride,
1004			  (GLubyte *) pointer + coffset );
1005   }
1006   else {
1007      _mesa_DisableClientState( GL_COLOR_ARRAY );
1008   }
1009
1010
1011   /* Normals */
1012   if (nflag) {
1013      _mesa_EnableClientState( GL_NORMAL_ARRAY );
1014      _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
1015   }
1016   else {
1017      _mesa_DisableClientState( GL_NORMAL_ARRAY );
1018   }
1019
1020   /* Vertices */
1021   _mesa_EnableClientState( GL_VERTEX_ARRAY );
1022   _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
1023			(GLubyte *) pointer + voffset );
1024}
1025
1026
1027void GLAPIENTRY
1028_mesa_LockArraysEXT(GLint first, GLsizei count)
1029{
1030   GET_CURRENT_CONTEXT(ctx);
1031   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1032
1033   if (MESA_VERBOSE & VERBOSE_API)
1034      _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
1035
1036   if (first < 0) {
1037      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
1038      return;
1039   }
1040   if (count <= 0) {
1041      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
1042      return;
1043   }
1044   if (ctx->Array.LockCount != 0) {
1045      _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
1046      return;
1047   }
1048
1049   ctx->Array.LockFirst = first;
1050   ctx->Array.LockCount = count;
1051
1052   ctx->NewState |= _NEW_ARRAY;
1053}
1054
1055
1056void GLAPIENTRY
1057_mesa_UnlockArraysEXT( void )
1058{
1059   GET_CURRENT_CONTEXT(ctx);
1060   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1061
1062   if (MESA_VERBOSE & VERBOSE_API)
1063      _mesa_debug(ctx, "glUnlockArrays\n");
1064
1065   if (ctx->Array.LockCount == 0) {
1066      _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
1067      return;
1068   }
1069
1070   ctx->Array.LockFirst = 0;
1071   ctx->Array.LockCount = 0;
1072   ctx->NewState |= _NEW_ARRAY;
1073}
1074
1075
1076/* GL_EXT_multi_draw_arrays */
1077void GLAPIENTRY
1078_mesa_MultiDrawArraysEXT( GLenum mode, const GLint *first,
1079                          const GLsizei *count, GLsizei primcount )
1080{
1081   GET_CURRENT_CONTEXT(ctx);
1082   GLint i;
1083
1084   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1085
1086   for (i = 0; i < primcount; i++) {
1087      if (count[i] > 0) {
1088         CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
1089      }
1090   }
1091}
1092
1093
1094/* GL_IBM_multimode_draw_arrays */
1095void GLAPIENTRY
1096_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1097			      const GLsizei * count,
1098			      GLsizei primcount, GLint modestride )
1099{
1100   GET_CURRENT_CONTEXT(ctx);
1101   GLint i;
1102
1103   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1104
1105   for ( i = 0 ; i < primcount ; i++ ) {
1106      if ( count[i] > 0 ) {
1107         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1108	 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] ));
1109      }
1110   }
1111}
1112
1113
1114/* GL_IBM_multimode_draw_arrays */
1115void GLAPIENTRY
1116_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1117				GLenum type, const GLvoid * const * indices,
1118				GLsizei primcount, GLint modestride )
1119{
1120   GET_CURRENT_CONTEXT(ctx);
1121   GLint i;
1122
1123   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1124
1125   /* XXX not sure about ARB_vertex_buffer_object handling here */
1126
1127   for ( i = 0 ; i < primcount ; i++ ) {
1128      if ( count[i] > 0 ) {
1129         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1130	 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] ));
1131      }
1132   }
1133}
1134
1135
1136/**
1137 * GL_NV_primitive_restart and GL 3.1
1138 */
1139void GLAPIENTRY
1140_mesa_PrimitiveRestartIndex(GLuint index)
1141{
1142   GET_CURRENT_CONTEXT(ctx);
1143
1144   if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) {
1145      _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1146      return;
1147   }
1148
1149   ASSERT_OUTSIDE_BEGIN_END(ctx);
1150
1151   if (ctx->Array.RestartIndex != index) {
1152      FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1153      ctx->Array.RestartIndex = index;
1154   }
1155}
1156
1157
1158/**
1159 * See GL_ARB_instanced_arrays.
1160 * Note that the instance divisor only applies to generic arrays, not
1161 * the legacy vertex arrays.
1162 */
1163void GLAPIENTRY
1164_mesa_VertexAttribDivisor(GLuint index, GLuint divisor)
1165{
1166   struct gl_client_array *array;
1167   GET_CURRENT_CONTEXT(ctx);
1168   ASSERT_OUTSIDE_BEGIN_END(ctx);
1169
1170   if (!ctx->Extensions.ARB_instanced_arrays) {
1171      _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribDivisor()");
1172      return;
1173   }
1174
1175   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
1176      _mesa_error(ctx, GL_INVALID_ENUM, "glVertexAttribDivisor(index = %u)",
1177                  index);
1178      return;
1179   }
1180
1181   ASSERT(VERT_ATTRIB_GENERIC(index) < Elements(ctx->Array.ArrayObj->VertexAttrib));
1182
1183   array = &ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(index)];
1184   if (array->InstanceDivisor != divisor) {
1185      FLUSH_VERTICES(ctx, _NEW_ARRAY);
1186      array->InstanceDivisor = divisor;
1187      ctx->Array.ArrayObj->NewArrays |= VERT_BIT(VERT_ATTRIB_GENERIC(index));
1188   }
1189}
1190
1191
1192
1193/**
1194 * Copy one client vertex array to another.
1195 */
1196void
1197_mesa_copy_client_array(struct gl_context *ctx,
1198                        struct gl_client_array *dst,
1199                        struct gl_client_array *src)
1200{
1201   dst->Size = src->Size;
1202   dst->Type = src->Type;
1203   dst->Format = src->Format;
1204   dst->Stride = src->Stride;
1205   dst->StrideB = src->StrideB;
1206   dst->Ptr = src->Ptr;
1207   dst->Enabled = src->Enabled;
1208   dst->Normalized = src->Normalized;
1209   dst->Integer = src->Integer;
1210   dst->InstanceDivisor = src->InstanceDivisor;
1211   dst->_ElementSize = src->_ElementSize;
1212   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1213   dst->_MaxElement = src->_MaxElement;
1214}
1215
1216
1217
1218/**
1219 * Print vertex array's fields.
1220 */
1221static void
1222print_array(const char *name, GLint index, const struct gl_client_array *array)
1223{
1224   if (index >= 0)
1225      printf("  %s[%d]: ", name, index);
1226   else
1227      printf("  %s: ", name);
1228   printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
1229	  array->Ptr, array->Type, array->Size,
1230	  array->_ElementSize, array->StrideB,
1231	  array->BufferObj->Name, (unsigned long) array->BufferObj->Size,
1232	  array->_MaxElement);
1233}
1234
1235
1236/**
1237 * Print current vertex object/array info.  For debug.
1238 */
1239void
1240_mesa_print_arrays(struct gl_context *ctx)
1241{
1242   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
1243   GLuint i;
1244
1245   _mesa_update_array_object_max_element(ctx, arrayObj);
1246
1247   printf("Array Object %u\n", arrayObj->Name);
1248   if (arrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled)
1249      print_array("Vertex", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_POS]);
1250   if (arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled)
1251      print_array("Normal", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_NORMAL]);
1252   if (arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled)
1253      print_array("Color", -1, &arrayObj->VertexAttrib[VERT_ATTRIB_COLOR0]);
1254   for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
1255      if (arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)].Enabled)
1256         print_array("TexCoord", i, &arrayObj->VertexAttrib[VERT_ATTRIB_TEX(i)]);
1257   for (i = 0; i < VERT_ATTRIB_GENERIC_MAX; i++)
1258      if (arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)].Enabled)
1259         print_array("Attrib", i, &arrayObj->VertexAttrib[VERT_ATTRIB_GENERIC(i)]);
1260   printf("  _MaxElement = %u\n", arrayObj->_MaxElement);
1261}
1262
1263
1264/**
1265 * Initialize vertex array state for given context.
1266 */
1267void
1268_mesa_init_varray(struct gl_context *ctx)
1269{
1270   ctx->Array.DefaultArrayObj = ctx->Driver.NewArrayObject(ctx, 0);
1271   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
1272                                ctx->Array.DefaultArrayObj);
1273   ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
1274
1275   ctx->Array.Objects = _mesa_NewHashTable();
1276}
1277
1278
1279/**
1280 * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
1281 */
1282static void
1283delete_arrayobj_cb(GLuint id, void *data, void *userData)
1284{
1285   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
1286   struct gl_context *ctx = (struct gl_context *) userData;
1287   _mesa_delete_array_object(ctx, arrayObj);
1288}
1289
1290
1291/**
1292 * Free vertex array state for given context.
1293 */
1294void
1295_mesa_free_varray_data(struct gl_context *ctx)
1296{
1297   _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
1298   _mesa_DeleteHashTable(ctx->Array.Objects);
1299}
1300