Subversion Repositories Kolibri OS

Rev

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

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