Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 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 "mtypes.h"
37
#include "varray.h"
38
#include "arrayobj.h"
39
#include "main/dispatch.h"
40
 
41
 
42
/** Used to do error checking for GL_EXT_vertex_array_bgra */
43
#define BGRA_OR_4  5
44
 
45
 
46
/** Used to indicate which GL datatypes are accepted by each of the
47
 * glVertex/Color/Attrib/EtcPointer() functions.
48
 */
49
#define BOOL_BIT             0x1
50
#define BYTE_BIT             0x2
51
#define UNSIGNED_BYTE_BIT    0x4
52
#define SHORT_BIT            0x8
53
#define UNSIGNED_SHORT_BIT   0x10
54
#define INT_BIT              0x20
55
#define UNSIGNED_INT_BIT     0x40
56
#define HALF_BIT             0x80
57
#define FLOAT_BIT            0x100
58
#define DOUBLE_BIT           0x200
59
#define FIXED_BIT            0x400
60
 
61
 
62
 
63
/** Convert GL datatype enum into a _BIT value seen above */
64
static GLbitfield
65
type_to_bit(const struct gl_context *ctx, GLenum type)
66
{
67
   switch (type) {
68
   case GL_BOOL:
69
      return BOOL_BIT;
70
   case GL_BYTE:
71
      return BYTE_BIT;
72
   case GL_UNSIGNED_BYTE:
73
      return UNSIGNED_BYTE_BIT;
74
   case GL_SHORT:
75
      return SHORT_BIT;
76
   case GL_UNSIGNED_SHORT:
77
      return UNSIGNED_SHORT_BIT;
78
   case GL_INT:
79
      return INT_BIT;
80
   case GL_UNSIGNED_INT:
81
      return UNSIGNED_INT_BIT;
82
   case GL_HALF_FLOAT:
83
      if (ctx->Extensions.ARB_half_float_vertex)
84
         return HALF_BIT;
85
      else
86
         return 0x0;
87
   case GL_FLOAT:
88
      return FLOAT_BIT;
89
   case GL_DOUBLE:
90
      return DOUBLE_BIT;
91
   case GL_FIXED:
92
      return FIXED_BIT;
93
   default:
94
      return 0;
95
   }
96
}
97
 
98
 
99
/**
100
 * Do error checking and update state for glVertex/Color/TexCoord/...Pointer
101
 * functions.
102
 *
103
 * \param func  name of calling function used for error reporting
104
 * \param array  the array to update
105
 * \param dirtyBit  which bit to set in ctx->Array.NewState for this array
106
 * \param legalTypes  bitmask of *_BIT above indicating legal datatypes
107
 * \param sizeMin  min allowable size value
108
 * \param sizeMax  max allowable size value (may also be BGRA_OR_4)
109
 * \param size  components per element (1, 2, 3 or 4)
110
 * \param type  datatype of each component (GL_FLOAT, GL_INT, etc)
111
 * \param stride  stride between elements, in elements
112
 * \param normalized  are integer types converted to floats in [-1, 1]?
113
 * \param integer  integer-valued values (will not be normalized to [-1,1])
114
 * \param ptr  the address (or offset inside VBO) of the array data
115
 */
116
static void
117
update_array(struct gl_context *ctx,
118
             const char *func,
119
             struct gl_client_array *array,
120
             GLbitfield dirtyBit, GLbitfield legalTypesMask,
121
             GLint sizeMin, GLint sizeMax,
122
             GLint size, GLenum type, GLsizei stride,
123
             GLboolean normalized, GLboolean integer,
124
             const GLvoid *ptr)
125
{
126
   GLbitfield typeBit;
127
   GLsizei elementSize;
128
   GLenum format = GL_RGBA;
129
 
130
   if (ctx->API != API_OPENGLES && ctx->API != API_OPENGLES2) {
131
      /* fixed point arrays / data is only allowed with OpenGL ES 1.x/2.0 */
132
      legalTypesMask &= ~FIXED_BIT;
133
   }
134
 
135
   typeBit = type_to_bit(ctx, type);
136
   if (typeBit == 0x0 || (typeBit & legalTypesMask) == 0x0) {
137
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(type = %s)",
138
                  func, _mesa_lookup_enum_by_nr(type));
139
      return;
140
   }
141
 
142
   /* Do size parameter checking.
143
    * If sizeMax = BGRA_OR_4 it means that size = GL_BGRA is legal and
144
    * must be handled specially.
145
    */
146
   if (ctx->Extensions.EXT_vertex_array_bgra &&
147
       sizeMax == BGRA_OR_4 &&
148
       size == GL_BGRA) {
149
      if (type != GL_UNSIGNED_BYTE) {
150
         _mesa_error(ctx, GL_INVALID_VALUE, "%s(GL_BGRA/GLubyte)", func);
151
         return;
152
      }
153
      format = GL_BGRA;
154
      size = 4;
155
   }
156
   else if (size < sizeMin || size > sizeMax || size > 4) {
157
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(size=%d)", func, size);
158
      return;
159
   }
160
 
161
   ASSERT(size <= 4);
162
 
163
   if (stride < 0) {
164
      _mesa_error( ctx, GL_INVALID_VALUE, "%s(stride=%d)", func, stride );
165
      return;
166
   }
167
 
168
   if (ctx->Array.ArrayObj->VBOonly &&
169
       ctx->Array.ArrayBufferObj->Name == 0) {
170
      /* GL_ARB_vertex_array_object requires that all arrays reside in VBOs.
171
       * Generate GL_INVALID_OPERATION if that's not true.
172
       */
173
      _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-VBO array)", func);
174
      return;
175
   }
176
 
177
   elementSize = _mesa_sizeof_type(type) * size;
178
 
179
   array->Size = size;
180
   array->Type = type;
181
   array->Format = format;
182
   array->Stride = stride;
183
   array->StrideB = stride ? stride : elementSize;
184
   array->Normalized = normalized;
185
   array->Ptr = (const GLubyte *) ptr;
186
   array->_ElementSize = elementSize;
187
 
188
   _mesa_reference_buffer_object(ctx, &array->BufferObj,
189
                                 ctx->Array.ArrayBufferObj);
190
 
191
   ctx->NewState |= _NEW_ARRAY;
192
   ctx->Array.NewState |= dirtyBit;
193
}
194
 
195
 
196
void GLAPIENTRY
197
_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
198
{
199
   GLbitfield legalTypes = (SHORT_BIT | INT_BIT | FLOAT_BIT |
200
                            DOUBLE_BIT | HALF_BIT | FIXED_BIT);
201
   GET_CURRENT_CONTEXT(ctx);
202
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
203
 
204
   if (ctx->API == API_OPENGLES)
205
      legalTypes |= BYTE_BIT;
206
 
207
   update_array(ctx, "glVertexPointer",
208
                &ctx->Array.ArrayObj->Vertex, _NEW_ARRAY_VERTEX,
209
                legalTypes, 2, 4,
210
                size, type, stride, GL_FALSE, GL_FALSE, ptr);
211
}
212
 
213
 
214
void GLAPIENTRY
215
_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
216
{
217
   const GLbitfield legalTypes = (BYTE_BIT | SHORT_BIT | INT_BIT |
218
                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
219
                                  FIXED_BIT);
220
   GET_CURRENT_CONTEXT(ctx);
221
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
222
 
223
   update_array(ctx, "glNormalPointer",
224
                &ctx->Array.ArrayObj->Normal, _NEW_ARRAY_NORMAL,
225
                legalTypes, 3, 3,
226
                3, type, stride, GL_TRUE, GL_FALSE, ptr);
227
}
228
 
229
 
230
void GLAPIENTRY
231
_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
232
{
233
   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
234
                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
235
                                  INT_BIT | UNSIGNED_INT_BIT |
236
                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
237
                                  FIXED_BIT);
238
   GET_CURRENT_CONTEXT(ctx);
239
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
240
 
241
   update_array(ctx, "glColorPointer",
242
                &ctx->Array.ArrayObj->Color, _NEW_ARRAY_COLOR0,
243
                legalTypes, 3, BGRA_OR_4,
244
                size, type, stride, GL_TRUE, GL_FALSE, ptr);
245
}
246
 
247
 
248
void GLAPIENTRY
249
_mesa_FogCoordPointerEXT(GLenum type, GLsizei stride, const GLvoid *ptr)
250
{
251
   const GLbitfield legalTypes = (HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
252
   GET_CURRENT_CONTEXT(ctx);
253
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
254
 
255
   update_array(ctx, "glFogCoordPointer",
256
                &ctx->Array.ArrayObj->FogCoord, _NEW_ARRAY_FOGCOORD,
257
                legalTypes, 1, 1,
258
                1, type, stride, GL_FALSE, GL_FALSE, ptr);
259
}
260
 
261
 
262
void GLAPIENTRY
263
_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr)
264
{
265
   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT | INT_BIT |
266
                                  FLOAT_BIT | DOUBLE_BIT);
267
   GET_CURRENT_CONTEXT(ctx);
268
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
269
 
270
   update_array(ctx, "glIndexPointer",
271
                &ctx->Array.ArrayObj->Index, _NEW_ARRAY_INDEX,
272
                legalTypes, 1, 1,
273
                1, type, stride, GL_FALSE, GL_FALSE, ptr);
274
}
275
 
276
 
277
void GLAPIENTRY
278
_mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
279
			       GLsizei stride, const GLvoid *ptr)
280
{
281
   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
282
                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
283
                                  INT_BIT | UNSIGNED_INT_BIT |
284
                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT);
285
   GET_CURRENT_CONTEXT(ctx);
286
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
287
 
288
   update_array(ctx, "glSecondaryColorPointer",
289
                &ctx->Array.ArrayObj->SecondaryColor, _NEW_ARRAY_COLOR1,
290
                legalTypes, 3, BGRA_OR_4,
291
                size, type, stride, GL_TRUE, GL_FALSE, ptr);
292
}
293
 
294
 
295
void GLAPIENTRY
296
_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
297
                      const GLvoid *ptr)
298
{
299
   GLbitfield legalTypes = (SHORT_BIT | INT_BIT |
300
                            HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
301
                            FIXED_BIT);
302
   GET_CURRENT_CONTEXT(ctx);
303
   const GLuint unit = ctx->Array.ActiveTexture;
304
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
305
 
306
   if (ctx->API == API_OPENGLES)
307
      legalTypes |= BYTE_BIT;
308
 
309
   ASSERT(unit < Elements(ctx->Array.ArrayObj->TexCoord));
310
 
311
   update_array(ctx, "glTexCoordPointer",
312
                &ctx->Array.ArrayObj->TexCoord[unit],
313
                _NEW_ARRAY_TEXCOORD(unit),
314
                legalTypes, 1, 4,
315
                size, type, stride, GL_FALSE, GL_FALSE,
316
                ptr);
317
}
318
 
319
 
320
void GLAPIENTRY
321
_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr)
322
{
323
   const GLbitfield legalTypes = UNSIGNED_BYTE_BIT;
324
   /* see table 2.4 edits in GL_EXT_gpu_shader4 spec: */
325
   const GLboolean integer = GL_TRUE;
326
   GET_CURRENT_CONTEXT(ctx);
327
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
328
 
329
   update_array(ctx, "glEdgeFlagPointer",
330
                &ctx->Array.ArrayObj->EdgeFlag, _NEW_ARRAY_EDGEFLAG,
331
                legalTypes, 1, 1,
332
                1, GL_UNSIGNED_BYTE, stride, GL_FALSE, integer, ptr);
333
}
334
 
335
 
336
void GLAPIENTRY
337
_mesa_PointSizePointer(GLenum type, GLsizei stride, const GLvoid *ptr)
338
{
339
   const GLbitfield legalTypes = (FLOAT_BIT | FIXED_BIT);
340
   GET_CURRENT_CONTEXT(ctx);
341
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
342
 
343
   if (ctx->API != API_OPENGLES) {
344
      _mesa_error(ctx, GL_INVALID_OPERATION,
345
                  "glPointSizePointer(ES 1.x only)");
346
      return;
347
   }
348
 
349
   update_array(ctx, "glPointSizePointer",
350
                &ctx->Array.ArrayObj->PointSize, _NEW_ARRAY_POINT_SIZE,
351
                legalTypes, 1, 1,
352
                1, type, stride, GL_FALSE, GL_FALSE, ptr);
353
}
354
 
355
 
356
#if FEATURE_NV_vertex_program
357
/**
358
 * Set a vertex attribute array.
359
 * Note that these arrays DO alias the conventional GL vertex arrays
360
 * (position, normal, color, fog, texcoord, etc).
361
 * The generic attribute slots at #16 and above are not touched.
362
 */
363
void GLAPIENTRY
364
_mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
365
                            GLsizei stride, const GLvoid *ptr)
366
{
367
   const GLbitfield legalTypes = (UNSIGNED_BYTE_BIT | SHORT_BIT |
368
                                  FLOAT_BIT | DOUBLE_BIT);
369
   GLboolean normalized = GL_FALSE;
370
   GET_CURRENT_CONTEXT(ctx);
371
   ASSERT_OUTSIDE_BEGIN_END(ctx);
372
 
373
   if (index >= MAX_NV_VERTEX_PROGRAM_INPUTS) {
374
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(index)");
375
      return;
376
   }
377
 
378
   if (type == GL_UNSIGNED_BYTE && size != 4) {
379
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerNV(size!=4)");
380
      return;
381
   }
382
 
383
   update_array(ctx, "glVertexAttribPointerNV",
384
                &ctx->Array.ArrayObj->VertexAttrib[index],
385
                _NEW_ARRAY_ATTRIB(index),
386
                legalTypes, 1, BGRA_OR_4,
387
                size, type, stride, normalized, GL_FALSE, ptr);
388
}
389
#endif
390
 
391
 
392
#if FEATURE_ARB_vertex_program
393
/**
394
 * Set a generic vertex attribute array.
395
 * Note that these arrays DO NOT alias the conventional GL vertex arrays
396
 * (position, normal, color, fog, texcoord, etc).
397
 */
398
void GLAPIENTRY
399
_mesa_VertexAttribPointerARB(GLuint index, GLint size, GLenum type,
400
                             GLboolean normalized,
401
                             GLsizei stride, const GLvoid *ptr)
402
{
403
   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
404
                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
405
                                  INT_BIT | UNSIGNED_INT_BIT |
406
                                  HALF_BIT | FLOAT_BIT | DOUBLE_BIT |
407
                                  FIXED_BIT);
408
   GET_CURRENT_CONTEXT(ctx);
409
   ASSERT_OUTSIDE_BEGIN_END(ctx);
410
 
411
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
412
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribPointerARB(index)");
413
      return;
414
   }
415
 
416
   update_array(ctx, "glVertexAttribPointer",
417
                &ctx->Array.ArrayObj->VertexAttrib[index],
418
                _NEW_ARRAY_ATTRIB(index),
419
                legalTypes, 1, BGRA_OR_4,
420
                size, type, stride, normalized, GL_FALSE, ptr);
421
}
422
#endif
423
 
424
 
425
/**
426
 * GL_EXT_gpu_shader4 / GL 3.0.
427
 * Set an integer-valued vertex attribute array.
428
 * Note that these arrays DO NOT alias the conventional GL vertex arrays
429
 * (position, normal, color, fog, texcoord, etc).
430
 */
431
void GLAPIENTRY
432
_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type,
433
                           GLsizei stride, const GLvoid *ptr)
434
{
435
   const GLbitfield legalTypes = (BYTE_BIT | UNSIGNED_BYTE_BIT |
436
                                  SHORT_BIT | UNSIGNED_SHORT_BIT |
437
                                  INT_BIT | UNSIGNED_INT_BIT);
438
   const GLboolean normalized = GL_FALSE;
439
   const GLboolean integer = GL_TRUE;
440
   GET_CURRENT_CONTEXT(ctx);
441
   ASSERT_OUTSIDE_BEGIN_END(ctx);
442
 
443
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
444
      _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribIPointer(index)");
445
      return;
446
   }
447
 
448
   update_array(ctx, "glVertexAttribIPointer",
449
                &ctx->Array.ArrayObj->VertexAttrib[index],
450
                _NEW_ARRAY_ATTRIB(index),
451
                legalTypes, 1, 4,
452
                size, type, stride, normalized, integer, ptr);
453
}
454
 
455
 
456
 
457
void GLAPIENTRY
458
_mesa_EnableVertexAttribArrayARB(GLuint index)
459
{
460
   GET_CURRENT_CONTEXT(ctx);
461
   ASSERT_OUTSIDE_BEGIN_END(ctx);
462
 
463
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
464
      _mesa_error(ctx, GL_INVALID_VALUE,
465
                  "glEnableVertexAttribArrayARB(index)");
466
      return;
467
   }
468
 
469
   ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
470
 
471
   FLUSH_VERTICES(ctx, _NEW_ARRAY);
472
   ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_TRUE;
473
   ctx->Array.ArrayObj->_Enabled |= _NEW_ARRAY_ATTRIB(index);
474
   ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
475
}
476
 
477
 
478
void GLAPIENTRY
479
_mesa_DisableVertexAttribArrayARB(GLuint index)
480
{
481
   GET_CURRENT_CONTEXT(ctx);
482
   ASSERT_OUTSIDE_BEGIN_END(ctx);
483
 
484
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
485
      _mesa_error(ctx, GL_INVALID_VALUE,
486
                  "glEnableVertexAttribArrayARB(index)");
487
      return;
488
   }
489
 
490
   ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
491
 
492
   FLUSH_VERTICES(ctx, _NEW_ARRAY);
493
   ctx->Array.ArrayObj->VertexAttrib[index].Enabled = GL_FALSE;
494
   ctx->Array.ArrayObj->_Enabled &= ~_NEW_ARRAY_ATTRIB(index);
495
   ctx->Array.NewState |= _NEW_ARRAY_ATTRIB(index);
496
}
497
 
498
 
499
/**
500
 * Return info for a vertex attribute array (no alias with legacy
501
 * vertex attributes (pos, normal, color, etc)).  This function does
502
 * not handle the 4-element GL_CURRENT_VERTEX_ATTRIB_ARB query.
503
 */
504
static GLuint
505
get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname,
506
                  const char *caller)
507
{
508
   const struct gl_client_array *array;
509
 
510
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
511
      _mesa_error(ctx, GL_INVALID_VALUE, "%s(index=%u)", caller, index);
512
      return 0;
513
   }
514
 
515
   ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
516
 
517
   array = &ctx->Array.ArrayObj->VertexAttrib[index];
518
 
519
   switch (pname) {
520
   case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB:
521
      return array->Enabled;
522
   case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB:
523
      return array->Size;
524
   case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB:
525
      return array->Stride;
526
   case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB:
527
      return array->Type;
528
   case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB:
529
      return array->Normalized;
530
   case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB:
531
      return array->BufferObj->Name;
532
   case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
533
      if (ctx->Extensions.EXT_gpu_shader4) {
534
         return array->Integer;
535
      }
536
      /* fall-through */
537
   default:
538
      _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", caller, pname);
539
      return 0;
540
   }
541
}
542
 
543
 
544
static const GLfloat *
545
get_current_attrib(struct gl_context *ctx, GLuint index, const char *function)
546
{
547
   if (index == 0) {
548
      if (ctx->API != API_OPENGLES2) {
549
	 _mesa_error(ctx, GL_INVALID_OPERATION, "%s(index==0)", function);
550
	 return NULL;
551
      }
552
   }
553
   else if (index >= ctx->Const.VertexProgram.MaxAttribs) {
554
      _mesa_error(ctx, GL_INVALID_VALUE,
555
		  "%s(index>=GL_MAX_VERTEX_ATTRIBS)", function);
556
      return NULL;
557
   }
558
 
559
   FLUSH_CURRENT(ctx, 0);
560
   return ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + index];
561
}
562
 
563
void GLAPIENTRY
564
_mesa_GetVertexAttribfvARB(GLuint index, GLenum pname, GLfloat *params)
565
{
566
   GET_CURRENT_CONTEXT(ctx);
567
   ASSERT_OUTSIDE_BEGIN_END(ctx);
568
 
569
   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
570
      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribfv");
571
      if (v != NULL) {
572
         COPY_4V(params, v);
573
      }
574
   }
575
   else {
576
      params[0] = (GLfloat) get_vertex_array_attrib(ctx, index, pname,
577
                                                    "glGetVertexAttribfv");
578
   }
579
}
580
 
581
 
582
void GLAPIENTRY
583
_mesa_GetVertexAttribdvARB(GLuint index, GLenum pname, GLdouble *params)
584
{
585
   GET_CURRENT_CONTEXT(ctx);
586
   ASSERT_OUTSIDE_BEGIN_END(ctx);
587
 
588
   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
589
      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribdv");
590
      if (v != NULL) {
591
         params[0] = (GLdouble) v[0];
592
         params[1] = (GLdouble) v[1];
593
         params[2] = (GLdouble) v[2];
594
         params[3] = (GLdouble) v[3];
595
      }
596
   }
597
   else {
598
      params[0] = (GLdouble) get_vertex_array_attrib(ctx, index, pname,
599
                                                     "glGetVertexAttribdv");
600
   }
601
}
602
 
603
 
604
void GLAPIENTRY
605
_mesa_GetVertexAttribivARB(GLuint index, GLenum pname, GLint *params)
606
{
607
   GET_CURRENT_CONTEXT(ctx);
608
   ASSERT_OUTSIDE_BEGIN_END(ctx);
609
 
610
   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
611
      const GLfloat *v = get_current_attrib(ctx, index, "glGetVertexAttribiv");
612
      if (v != NULL) {
613
         /* XXX should floats in[0,1] be scaled to full int range? */
614
         params[0] = (GLint) v[0];
615
         params[1] = (GLint) v[1];
616
         params[2] = (GLint) v[2];
617
         params[3] = (GLint) v[3];
618
      }
619
   }
620
   else {
621
      params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
622
                                                  "glGetVertexAttribiv");
623
   }
624
}
625
 
626
 
627
/** GL 3.0 */
628
void GLAPIENTRY
629
_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params)
630
{
631
   GET_CURRENT_CONTEXT(ctx);
632
   ASSERT_OUTSIDE_BEGIN_END(ctx);
633
 
634
   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
635
      const GLfloat *v =
636
	 get_current_attrib(ctx, index, "glGetVertexAttribIiv");
637
      if (v != NULL) {
638
         /* XXX we don't have true integer-valued vertex attribs yet */
639
         params[0] = (GLint) v[0];
640
         params[1] = (GLint) v[1];
641
         params[2] = (GLint) v[2];
642
         params[3] = (GLint) v[3];
643
      }
644
   }
645
   else {
646
      params[0] = (GLint) get_vertex_array_attrib(ctx, index, pname,
647
                                                  "glGetVertexAttribIiv");
648
   }
649
}
650
 
651
 
652
/** GL 3.0 */
653
void GLAPIENTRY
654
_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params)
655
{
656
   GET_CURRENT_CONTEXT(ctx);
657
   ASSERT_OUTSIDE_BEGIN_END(ctx);
658
 
659
   if (pname == GL_CURRENT_VERTEX_ATTRIB_ARB) {
660
      const GLfloat *v =
661
	 get_current_attrib(ctx, index, "glGetVertexAttribIuiv");
662
      if (v != NULL) {
663
         /* XXX we don't have true integer-valued vertex attribs yet */
664
         params[0] = (GLuint) v[0];
665
         params[1] = (GLuint) v[1];
666
         params[2] = (GLuint) v[2];
667
         params[3] = (GLuint) v[3];
668
      }
669
   }
670
   else {
671
      params[0] = get_vertex_array_attrib(ctx, index, pname,
672
                                          "glGetVertexAttribIuiv");
673
   }
674
}
675
 
676
 
677
void GLAPIENTRY
678
_mesa_GetVertexAttribPointervARB(GLuint index, GLenum pname, GLvoid **pointer)
679
{
680
   GET_CURRENT_CONTEXT(ctx);
681
   ASSERT_OUTSIDE_BEGIN_END(ctx);
682
 
683
   if (index >= ctx->Const.VertexProgram.MaxAttribs) {
684
      _mesa_error(ctx, GL_INVALID_VALUE, "glGetVertexAttribPointerARB(index)");
685
      return;
686
   }
687
 
688
   if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB) {
689
      _mesa_error(ctx, GL_INVALID_ENUM, "glGetVertexAttribPointerARB(pname)");
690
      return;
691
   }
692
 
693
   ASSERT(index < Elements(ctx->Array.ArrayObj->VertexAttrib));
694
 
695
   *pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
696
}
697
 
698
 
699
void GLAPIENTRY
700
_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride,
701
                       GLsizei count, const GLvoid *ptr)
702
{
703
   (void) count;
704
   _mesa_VertexPointer(size, type, stride, ptr);
705
}
706
 
707
 
708
void GLAPIENTRY
709
_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count,
710
                       const GLvoid *ptr)
711
{
712
   (void) count;
713
   _mesa_NormalPointer(type, stride, ptr);
714
}
715
 
716
 
717
void GLAPIENTRY
718
_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count,
719
                      const GLvoid *ptr)
720
{
721
   (void) count;
722
   _mesa_ColorPointer(size, type, stride, ptr);
723
}
724
 
725
 
726
void GLAPIENTRY
727
_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count,
728
                      const GLvoid *ptr)
729
{
730
   (void) count;
731
   _mesa_IndexPointer(type, stride, ptr);
732
}
733
 
734
 
735
void GLAPIENTRY
736
_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride,
737
                         GLsizei count, const GLvoid *ptr)
738
{
739
   (void) count;
740
   _mesa_TexCoordPointer(size, type, stride, ptr);
741
}
742
 
743
 
744
void GLAPIENTRY
745
_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr)
746
{
747
   (void) count;
748
   _mesa_EdgeFlagPointer(stride, ptr);
749
}
750
 
751
 
752
void GLAPIENTRY
753
_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
754
{
755
   GET_CURRENT_CONTEXT(ctx);
756
   GLboolean tflag, cflag, nflag;  /* enable/disable flags */
757
   GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
758
   GLenum ctype = 0;               /* color type */
759
   GLint coffset = 0, noffset = 0, voffset;/* color, normal, vertex offsets */
760
   const GLint toffset = 0;        /* always zero */
761
   GLint defstride;                /* default stride */
762
   GLint c, f;
763
 
764
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
765
 
766
   f = sizeof(GLfloat);
767
   c = f * ((4 * sizeof(GLubyte) + (f - 1)) / f);
768
 
769
   if (stride < 0) {
770
      _mesa_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
771
      return;
772
   }
773
 
774
   switch (format) {
775
      case GL_V2F:
776
         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
777
         tcomps = 0;  ccomps = 0;  vcomps = 2;
778
         voffset = 0;
779
         defstride = 2*f;
780
         break;
781
      case GL_V3F:
782
         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
783
         tcomps = 0;  ccomps = 0;  vcomps = 3;
784
         voffset = 0;
785
         defstride = 3*f;
786
         break;
787
      case GL_C4UB_V2F:
788
         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
789
         tcomps = 0;  ccomps = 4;  vcomps = 2;
790
         ctype = GL_UNSIGNED_BYTE;
791
         coffset = 0;
792
         voffset = c;
793
         defstride = c + 2*f;
794
         break;
795
      case GL_C4UB_V3F:
796
         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
797
         tcomps = 0;  ccomps = 4;  vcomps = 3;
798
         ctype = GL_UNSIGNED_BYTE;
799
         coffset = 0;
800
         voffset = c;
801
         defstride = c + 3*f;
802
         break;
803
      case GL_C3F_V3F:
804
         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
805
         tcomps = 0;  ccomps = 3;  vcomps = 3;
806
         ctype = GL_FLOAT;
807
         coffset = 0;
808
         voffset = 3*f;
809
         defstride = 6*f;
810
         break;
811
      case GL_N3F_V3F:
812
         tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
813
         tcomps = 0;  ccomps = 0;  vcomps = 3;
814
         noffset = 0;
815
         voffset = 3*f;
816
         defstride = 6*f;
817
         break;
818
      case GL_C4F_N3F_V3F:
819
         tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
820
         tcomps = 0;  ccomps = 4;  vcomps = 3;
821
         ctype = GL_FLOAT;
822
         coffset = 0;
823
         noffset = 4*f;
824
         voffset = 7*f;
825
         defstride = 10*f;
826
         break;
827
      case GL_T2F_V3F:
828
         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
829
         tcomps = 2;  ccomps = 0;  vcomps = 3;
830
         voffset = 2*f;
831
         defstride = 5*f;
832
         break;
833
      case GL_T4F_V4F:
834
         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
835
         tcomps = 4;  ccomps = 0;  vcomps = 4;
836
         voffset = 4*f;
837
         defstride = 8*f;
838
         break;
839
      case GL_T2F_C4UB_V3F:
840
         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
841
         tcomps = 2;  ccomps = 4;  vcomps = 3;
842
         ctype = GL_UNSIGNED_BYTE;
843
         coffset = 2*f;
844
         voffset = c+2*f;
845
         defstride = c+5*f;
846
         break;
847
      case GL_T2F_C3F_V3F:
848
         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
849
         tcomps = 2;  ccomps = 3;  vcomps = 3;
850
         ctype = GL_FLOAT;
851
         coffset = 2*f;
852
         voffset = 5*f;
853
         defstride = 8*f;
854
         break;
855
      case GL_T2F_N3F_V3F:
856
         tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
857
         tcomps = 2;  ccomps = 0;  vcomps = 3;
858
         noffset = 2*f;
859
         voffset = 5*f;
860
         defstride = 8*f;
861
         break;
862
      case GL_T2F_C4F_N3F_V3F:
863
         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
864
         tcomps = 2;  ccomps = 4;  vcomps = 3;
865
         ctype = GL_FLOAT;
866
         coffset = 2*f;
867
         noffset = 6*f;
868
         voffset = 9*f;
869
         defstride = 12*f;
870
         break;
871
      case GL_T4F_C4F_N3F_V4F:
872
         tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
873
         tcomps = 4;  ccomps = 4;  vcomps = 4;
874
         ctype = GL_FLOAT;
875
         coffset = 4*f;
876
         noffset = 8*f;
877
         voffset = 11*f;
878
         defstride = 15*f;
879
         break;
880
      default:
881
         _mesa_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
882
         return;
883
   }
884
 
885
   if (stride==0) {
886
      stride = defstride;
887
   }
888
 
889
   _mesa_DisableClientState( GL_EDGE_FLAG_ARRAY );
890
   _mesa_DisableClientState( GL_INDEX_ARRAY );
891
   /* XXX also disable secondary color and generic arrays? */
892
 
893
   /* Texcoords */
894
   if (tflag) {
895
      _mesa_EnableClientState( GL_TEXTURE_COORD_ARRAY );
896
      _mesa_TexCoordPointer( tcomps, GL_FLOAT, stride,
897
                             (GLubyte *) pointer + toffset );
898
   }
899
   else {
900
      _mesa_DisableClientState( GL_TEXTURE_COORD_ARRAY );
901
   }
902
 
903
   /* Color */
904
   if (cflag) {
905
      _mesa_EnableClientState( GL_COLOR_ARRAY );
906
      _mesa_ColorPointer( ccomps, ctype, stride,
907
			  (GLubyte *) pointer + coffset );
908
   }
909
   else {
910
      _mesa_DisableClientState( GL_COLOR_ARRAY );
911
   }
912
 
913
 
914
   /* Normals */
915
   if (nflag) {
916
      _mesa_EnableClientState( GL_NORMAL_ARRAY );
917
      _mesa_NormalPointer( GL_FLOAT, stride, (GLubyte *) pointer + noffset );
918
   }
919
   else {
920
      _mesa_DisableClientState( GL_NORMAL_ARRAY );
921
   }
922
 
923
   /* Vertices */
924
   _mesa_EnableClientState( GL_VERTEX_ARRAY );
925
   _mesa_VertexPointer( vcomps, GL_FLOAT, stride,
926
			(GLubyte *) pointer + voffset );
927
}
928
 
929
 
930
void GLAPIENTRY
931
_mesa_LockArraysEXT(GLint first, GLsizei count)
932
{
933
   GET_CURRENT_CONTEXT(ctx);
934
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
935
 
936
   if (MESA_VERBOSE & VERBOSE_API)
937
      _mesa_debug(ctx, "glLockArrays %d %d\n", first, count);
938
 
939
   if (first < 0) {
940
      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(first)" );
941
      return;
942
   }
943
   if (count <= 0) {
944
      _mesa_error( ctx, GL_INVALID_VALUE, "glLockArraysEXT(count)" );
945
      return;
946
   }
947
   if (ctx->Array.LockCount != 0) {
948
      _mesa_error( ctx, GL_INVALID_OPERATION, "glLockArraysEXT(reentry)" );
949
      return;
950
   }
951
 
952
   ctx->Array.LockFirst = first;
953
   ctx->Array.LockCount = count;
954
 
955
   ctx->NewState |= _NEW_ARRAY;
956
   ctx->Array.NewState |= _NEW_ARRAY_ALL;
957
}
958
 
959
 
960
void GLAPIENTRY
961
_mesa_UnlockArraysEXT( void )
962
{
963
   GET_CURRENT_CONTEXT(ctx);
964
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
965
 
966
   if (MESA_VERBOSE & VERBOSE_API)
967
      _mesa_debug(ctx, "glUnlockArrays\n");
968
 
969
   if (ctx->Array.LockCount == 0) {
970
      _mesa_error( ctx, GL_INVALID_OPERATION, "glUnlockArraysEXT(reexit)" );
971
      return;
972
   }
973
 
974
   ctx->Array.LockFirst = 0;
975
   ctx->Array.LockCount = 0;
976
   ctx->NewState |= _NEW_ARRAY;
977
   ctx->Array.NewState |= _NEW_ARRAY_ALL;
978
}
979
 
980
 
981
/* GL_EXT_multi_draw_arrays */
982
void GLAPIENTRY
983
_mesa_MultiDrawArraysEXT( GLenum mode, const GLint *first,
984
                          const GLsizei *count, GLsizei primcount )
985
{
986
   GET_CURRENT_CONTEXT(ctx);
987
   GLint i;
988
 
989
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
990
 
991
   for (i = 0; i < primcount; i++) {
992
      if (count[i] > 0) {
993
         CALL_DrawArrays(ctx->Exec, (mode, first[i], count[i]));
994
      }
995
   }
996
}
997
 
998
 
999
/* GL_IBM_multimode_draw_arrays */
1000
void GLAPIENTRY
1001
_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
1002
			      const GLsizei * count,
1003
			      GLsizei primcount, GLint modestride )
1004
{
1005
   GET_CURRENT_CONTEXT(ctx);
1006
   GLint i;
1007
 
1008
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1009
 
1010
   for ( i = 0 ; i < primcount ; i++ ) {
1011
      if ( count[i] > 0 ) {
1012
         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1013
	 CALL_DrawArrays(ctx->Exec, ( m, first[i], count[i] ));
1014
      }
1015
   }
1016
}
1017
 
1018
 
1019
/* GL_IBM_multimode_draw_arrays */
1020
void GLAPIENTRY
1021
_mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
1022
				GLenum type, const GLvoid * const * indices,
1023
				GLsizei primcount, GLint modestride )
1024
{
1025
   GET_CURRENT_CONTEXT(ctx);
1026
   GLint i;
1027
 
1028
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1029
 
1030
   /* XXX not sure about ARB_vertex_buffer_object handling here */
1031
 
1032
   for ( i = 0 ; i < primcount ; i++ ) {
1033
      if ( count[i] > 0 ) {
1034
         GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride));
1035
	 CALL_DrawElements(ctx->Exec, ( m, count[i], type, indices[i] ));
1036
      }
1037
   }
1038
}
1039
 
1040
 
1041
/**
1042
 * GL_NV_primitive_restart and GL 3.1
1043
 */
1044
void GLAPIENTRY
1045
_mesa_PrimitiveRestartIndex(GLuint index)
1046
{
1047
   GET_CURRENT_CONTEXT(ctx);
1048
 
1049
   if (!ctx->Extensions.NV_primitive_restart &&
1050
       ctx->VersionMajor * 10 + ctx->VersionMinor < 31) {
1051
      _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()");
1052
      return;
1053
   }
1054
 
1055
   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
1056
 
1057
   FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
1058
 
1059
   ctx->Array.RestartIndex = index;
1060
}
1061
 
1062
 
1063
/**
1064
 * Copy one client vertex array to another.
1065
 */
1066
void
1067
_mesa_copy_client_array(struct gl_context *ctx,
1068
                        struct gl_client_array *dst,
1069
                        struct gl_client_array *src)
1070
{
1071
   dst->Size = src->Size;
1072
   dst->Type = src->Type;
1073
   dst->Format = src->Format;
1074
   dst->Stride = src->Stride;
1075
   dst->StrideB = src->StrideB;
1076
   dst->Ptr = src->Ptr;
1077
   dst->Enabled = src->Enabled;
1078
   dst->Normalized = src->Normalized;
1079
   dst->Integer = src->Integer;
1080
   dst->_ElementSize = src->_ElementSize;
1081
   _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
1082
   dst->_MaxElement = src->_MaxElement;
1083
}
1084
 
1085
 
1086
 
1087
/**
1088
 * Print vertex array's fields.
1089
 */
1090
static void
1091
print_array(const char *name, GLint index, const struct gl_client_array *array)
1092
{
1093
   if (index >= 0)
1094
      printf("  %s[%d]: ", name, index);
1095
   else
1096
      printf("  %s: ", name);
1097
   printf("Ptr=%p, Type=0x%x, Size=%d, ElemSize=%u, Stride=%d, Buffer=%u(Size %lu), MaxElem=%u\n",
1098
	  array->Ptr, array->Type, array->Size,
1099
	  array->_ElementSize, array->StrideB,
1100
	  array->BufferObj->Name, (unsigned long) array->BufferObj->Size,
1101
	  array->_MaxElement);
1102
}
1103
 
1104
 
1105
/**
1106
 * Print current vertex object/array info.  For debug.
1107
 */
1108
void
1109
_mesa_print_arrays(struct gl_context *ctx)
1110
{
1111
   struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
1112
   GLuint i;
1113
 
1114
   _mesa_update_array_object_max_element(ctx, arrayObj);
1115
 
1116
   printf("Array Object %u\n", arrayObj->Name);
1117
   if (arrayObj->Vertex.Enabled)
1118
      print_array("Vertex", -1, &arrayObj->Vertex);
1119
   if (arrayObj->Normal.Enabled)
1120
      print_array("Normal", -1, &arrayObj->Normal);
1121
   if (arrayObj->Color.Enabled)
1122
      print_array("Color", -1, &arrayObj->Color);
1123
   for (i = 0; i < Elements(arrayObj->TexCoord); i++)
1124
      if (arrayObj->TexCoord[i].Enabled)
1125
         print_array("TexCoord", i, &arrayObj->TexCoord[i]);
1126
   for (i = 0; i < Elements(arrayObj->VertexAttrib); i++)
1127
      if (arrayObj->VertexAttrib[i].Enabled)
1128
         print_array("Attrib", i, &arrayObj->VertexAttrib[i]);
1129
   printf("  _MaxElement = %u\n", arrayObj->_MaxElement);
1130
}
1131
 
1132
 
1133
/**
1134
 * Initialize vertex array state for given context.
1135
 */
1136
void
1137
_mesa_init_varray(struct gl_context *ctx)
1138
{
1139
   ctx->Array.DefaultArrayObj = _mesa_new_array_object(ctx, 0);
1140
   _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj,
1141
                                ctx->Array.DefaultArrayObj);
1142
   ctx->Array.ActiveTexture = 0;   /* GL_ARB_multitexture */
1143
 
1144
   ctx->Array.Objects = _mesa_NewHashTable();
1145
}
1146
 
1147
 
1148
/**
1149
 * Callback for deleting an array object.  Called by _mesa_HashDeleteAll().
1150
 */
1151
static void
1152
delete_arrayobj_cb(GLuint id, void *data, void *userData)
1153
{
1154
   struct gl_array_object *arrayObj = (struct gl_array_object *) data;
1155
   struct gl_context *ctx = (struct gl_context *) userData;
1156
   _mesa_delete_array_object(ctx, arrayObj);
1157
}
1158
 
1159
 
1160
/**
1161
 * Free vertex array state for given context.
1162
 */
1163
void
1164
_mesa_free_varray_data(struct gl_context *ctx)
1165
{
1166
   _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx);
1167
   _mesa_DeleteHashTable(ctx->Array.Objects);
1168
}