Subversion Repositories Kolibri OS

Rev

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

  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 <type>_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. }
  1169.