Home | History | Annotate | Download | only in vbo
      1 /**************************************************************************
      2 
      3 Copyright 2002 VMware, Inc.
      4 Copyright 2011 Dave Airlie (ARB_vertex_type_2_10_10_10_rev support)
      5 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 on the rights to use, copy, modify, merge, publish, distribute, sub
     11 license, and/or sell copies of the Software, and to permit persons to whom
     12 the Software is furnished to do so, subject to the following conditions:
     13 
     14 The above copyright notice and this permission notice (including the next
     15 paragraph) shall be included in all copies or substantial portions of the
     16 Software.
     17 
     18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
     21 VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
     22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
     23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
     24 USE OR OTHER DEALINGS IN THE SOFTWARE.
     25 
     26 **************************************************************************/
     27 
     28 #include "util/format_r11g11b10f.h"
     29 #include "main/varray.h"
     30 
     31 
     32 /* ATTR */
     33 #define ATTRI( A, N, V0, V1, V2, V3 ) \
     34     ATTR_UNION(A, N, GL_INT, fi_type, INT_AS_UNION(V0), INT_AS_UNION(V1), \
     35         INT_AS_UNION(V2), INT_AS_UNION(V3))
     36 #define ATTRUI( A, N, V0, V1, V2, V3 ) \
     37     ATTR_UNION(A, N, GL_UNSIGNED_INT, fi_type, UINT_AS_UNION(V0), UINT_AS_UNION(V1), \
     38         UINT_AS_UNION(V2), UINT_AS_UNION(V3))
     39 #define ATTRF( A, N, V0, V1, V2, V3 ) \
     40     ATTR_UNION(A, N, GL_FLOAT, fi_type, FLOAT_AS_UNION(V0), FLOAT_AS_UNION(V1),\
     41         FLOAT_AS_UNION(V2), FLOAT_AS_UNION(V3))
     42 #define ATTRD( A, N, V0, V1, V2, V3 ) \
     43     ATTR_UNION(A, N, GL_DOUBLE, double, V0, V1, V2, V3)
     44 #define ATTRUI64( A, N, V0, V1, V2, V3 ) \
     45     ATTR_UNION(A, N, GL_UNSIGNED_INT64_ARB, uint64_t, V0, V1, V2, V3)
     46 
     47 
     48 /* float */
     49 #define ATTR1FV( A, V ) ATTRF( A, 1, (V)[0], 0, 0, 1 )
     50 #define ATTR2FV( A, V ) ATTRF( A, 2, (V)[0], (V)[1], 0, 1 )
     51 #define ATTR3FV( A, V ) ATTRF( A, 3, (V)[0], (V)[1], (V)[2], 1 )
     52 #define ATTR4FV( A, V ) ATTRF( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
     53 
     54 #define ATTR1F( A, X )          ATTRF( A, 1, X, 0, 0, 1 )
     55 #define ATTR2F( A, X, Y )       ATTRF( A, 2, X, Y, 0, 1 )
     56 #define ATTR3F( A, X, Y, Z )    ATTRF( A, 3, X, Y, Z, 1 )
     57 #define ATTR4F( A, X, Y, Z, W ) ATTRF( A, 4, X, Y, Z, W )
     58 
     59 
     60 /* int */
     61 #define ATTR2IV( A, V ) ATTRI( A, 2, (V)[0], (V)[1], 0, 1 )
     62 #define ATTR3IV( A, V ) ATTRI( A, 3, (V)[0], (V)[1], (V)[2], 1 )
     63 #define ATTR4IV( A, V ) ATTRI( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
     64 
     65 #define ATTR1I( A, X )          ATTRI( A, 1, X, 0, 0, 1 )
     66 #define ATTR2I( A, X, Y )       ATTRI( A, 2, X, Y, 0, 1 )
     67 #define ATTR3I( A, X, Y, Z )    ATTRI( A, 3, X, Y, Z, 1 )
     68 #define ATTR4I( A, X, Y, Z, W ) ATTRI( A, 4, X, Y, Z, W )
     69 
     70 
     71 /* uint */
     72 #define ATTR2UIV( A, V ) ATTRUI( A, 2, (V)[0], (V)[1], 0, 1 )
     73 #define ATTR3UIV( A, V ) ATTRUI( A, 3, (V)[0], (V)[1], (V)[2], 1 )
     74 #define ATTR4UIV( A, V ) ATTRUI( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
     75 
     76 #define ATTR1UI( A, X )          ATTRUI( A, 1, X, 0, 0, 1 )
     77 #define ATTR2UI( A, X, Y )       ATTRUI( A, 2, X, Y, 0, 1 )
     78 #define ATTR3UI( A, X, Y, Z )    ATTRUI( A, 3, X, Y, Z, 1 )
     79 #define ATTR4UI( A, X, Y, Z, W ) ATTRUI( A, 4, X, Y, Z, W )
     80 
     81 #define MAT_ATTR( A, N, V ) ATTRF( A, N, (V)[0], (V)[1], (V)[2], (V)[3] )
     82 
     83 static inline float conv_ui10_to_norm_float(unsigned ui10)
     84 {
     85    return ui10 / 1023.0f;
     86 }
     87 
     88 static inline float conv_ui2_to_norm_float(unsigned ui2)
     89 {
     90    return ui2 / 3.0f;
     91 }
     92 
     93 #define ATTRUI10_1( A, UI ) ATTRF( A, 1, (UI) & 0x3ff, 0, 0, 1 )
     94 #define ATTRUI10_2( A, UI ) ATTRF( A, 2, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, 0, 1 )
     95 #define ATTRUI10_3( A, UI ) ATTRF( A, 3, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, 1 )
     96 #define ATTRUI10_4( A, UI ) ATTRF( A, 4, (UI) & 0x3ff, ((UI) >> 10) & 0x3ff, ((UI) >> 20) & 0x3ff, ((UI) >> 30) & 0x3 )
     97 
     98 #define ATTRUI10N_1( A, UI ) ATTRF( A, 1, conv_ui10_to_norm_float((UI) & 0x3ff), 0, 0, 1 )
     99 #define ATTRUI10N_2( A, UI ) ATTRF( A, 2, \
    100 				   conv_ui10_to_norm_float((UI) & 0x3ff), \
    101 				   conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), 0, 1 )
    102 #define ATTRUI10N_3( A, UI ) ATTRF( A, 3, \
    103 				   conv_ui10_to_norm_float((UI) & 0x3ff), \
    104 				   conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), \
    105 				   conv_ui10_to_norm_float(((UI) >> 20) & 0x3ff), 1 )
    106 #define ATTRUI10N_4( A, UI ) ATTRF( A, 4, \
    107 				   conv_ui10_to_norm_float((UI) & 0x3ff), \
    108 				   conv_ui10_to_norm_float(((UI) >> 10) & 0x3ff), \
    109 				   conv_ui10_to_norm_float(((UI) >> 20) & 0x3ff), \
    110 				   conv_ui2_to_norm_float(((UI) >> 30) & 0x3) )
    111 
    112 struct attr_bits_10 {signed int x:10;};
    113 struct attr_bits_2 {signed int x:2;};
    114 
    115 static inline float conv_i10_to_i(int i10)
    116 {
    117    struct attr_bits_10 val;
    118    val.x = i10;
    119    return (float)val.x;
    120 }
    121 
    122 static inline float conv_i2_to_i(int i2)
    123 {
    124    struct attr_bits_2 val;
    125    val.x = i2;
    126    return (float)val.x;
    127 }
    128 
    129 static inline float conv_i10_to_norm_float(const struct gl_context *ctx, int i10)
    130 {
    131    struct attr_bits_10 val;
    132    val.x = i10;
    133 
    134    /* Traditionally, OpenGL has had two equations for converting from
    135     * normalized fixed-point data to floating-point data.  In the OpenGL 3.2
    136     * specification, these are equations 2.2 and 2.3, respectively:
    137     *
    138     *    f = (2c + 1)/(2^b - 1).                                (2.2)
    139     *
    140     * Comments below this equation state: "In general, this representation is
    141     * used for signed normalized fixed-point parameters in GL commands, such
    142     * as vertex attribute values."  Which is what we're doing here.
    143     *
    144     *    f = max{c/(2^(b-1) - 1), -1.0}                         (2.3)
    145     *
    146     * Comments below this equation state: "In general, this representation is
    147     * used for signed normalized fixed-point texture or floating point values."
    148     *
    149     * OpenGL 4.2+ and ES 3.0 remedy this and state that equation 2.3 (above)
    150     * is used in every case.  They remove equation 2.2 completely.
    151     */
    152    if (_mesa_is_gles3(ctx) ||
    153        (ctx->API == API_OPENGL_CORE && ctx->Version >= 42)) {
    154       /* Equation 2.3 above. */
    155       float f = ((float) val.x) / 511.0F;
    156       return MAX2(f, -1.0f);
    157    } else {
    158       /* Equation 2.2 above. */
    159       return (2.0F * (float)val.x + 1.0F) * (1.0F  / 1023.0F);
    160    }
    161 }
    162 
    163 static inline float conv_i2_to_norm_float(const struct gl_context *ctx, int i2)
    164 {
    165    struct attr_bits_2 val;
    166    val.x = i2;
    167 
    168    if (_mesa_is_gles3(ctx) ||
    169        (ctx->API == API_OPENGL_CORE && ctx->Version >= 42)) {
    170       /* Equation 2.3 above. */
    171       float f = (float) val.x;
    172       return MAX2(f, -1.0f);
    173    } else {
    174       /* Equation 2.2 above. */
    175       return (2.0F * (float)val.x + 1.0F) * (1.0F / 3.0F);
    176    }
    177 }
    178 
    179 #define ATTRI10_1( A, I10 ) ATTRF( A, 1, conv_i10_to_i((I10) & 0x3ff), 0, 0, 1 )
    180 #define ATTRI10_2( A, I10 ) ATTRF( A, 2, \
    181 				conv_i10_to_i((I10) & 0x3ff),		\
    182 				conv_i10_to_i(((I10) >> 10) & 0x3ff), 0, 1 )
    183 #define ATTRI10_3( A, I10 ) ATTRF( A, 3, \
    184 				conv_i10_to_i((I10) & 0x3ff),	    \
    185 				conv_i10_to_i(((I10) >> 10) & 0x3ff), \
    186 				conv_i10_to_i(((I10) >> 20) & 0x3ff), 1 )
    187 #define ATTRI10_4( A, I10 ) ATTRF( A, 4, \
    188 				conv_i10_to_i((I10) & 0x3ff),		\
    189 				conv_i10_to_i(((I10) >> 10) & 0x3ff), \
    190 				conv_i10_to_i(((I10) >> 20) & 0x3ff), \
    191 				conv_i2_to_i(((I10) >> 30) & 0x3))
    192 
    193 
    194 #define ATTRI10N_1(ctx, A, I10) ATTRF(A, 1, conv_i10_to_norm_float(ctx, (I10) & 0x3ff), 0, 0, 1 )
    195 #define ATTRI10N_2(ctx, A, I10) ATTRF(A, 2, \
    196 				conv_i10_to_norm_float(ctx, (I10) & 0x3ff),		\
    197 				conv_i10_to_norm_float(ctx, ((I10) >> 10) & 0x3ff), 0, 1 )
    198 #define ATTRI10N_3(ctx, A, I10) ATTRF(A, 3, \
    199 				conv_i10_to_norm_float(ctx, (I10) & 0x3ff),	    \
    200 				conv_i10_to_norm_float(ctx, ((I10) >> 10) & 0x3ff), \
    201 				conv_i10_to_norm_float(ctx, ((I10) >> 20) & 0x3ff), 1 )
    202 #define ATTRI10N_4(ctx, A, I10) ATTRF(A, 4, \
    203 				conv_i10_to_norm_float(ctx, (I10) & 0x3ff),		\
    204 				conv_i10_to_norm_float(ctx, ((I10) >> 10) & 0x3ff), \
    205 				conv_i10_to_norm_float(ctx, ((I10) >> 20) & 0x3ff), \
    206 				conv_i2_to_norm_float(ctx, ((I10) >> 30) & 0x3))
    207 
    208 #define ATTR_UI(ctx, val, type, normalized, attr, arg) do {	\
    209    if ((type) == GL_UNSIGNED_INT_2_10_10_10_REV) {		\
    210       if (normalized) {						\
    211 	 ATTRUI10N_##val((attr), (arg));			\
    212       } else {							\
    213 	 ATTRUI10_##val((attr), (arg));				\
    214       }								\
    215    } else if ((type) == GL_INT_2_10_10_10_REV) {		\
    216       if (normalized) {						\
    217 	 ATTRI10N_##val(ctx, (attr), (arg));			\
    218       } else {							\
    219 	 ATTRI10_##val((attr), (arg));				\
    220       }								\
    221    } else if ((type) == GL_UNSIGNED_INT_10F_11F_11F_REV) {	\
    222       float res[4];						\
    223       res[3] = 1;                                               \
    224       r11g11b10f_to_float3((arg), res);				\
    225       ATTR##val##FV((attr), res);				\
    226    } else							\
    227       ERROR(GL_INVALID_VALUE);					\
    228    } while(0)
    229 
    230 #define ATTR_UI_INDEX(ctx, val, type, normalized, index, arg) do {	\
    231       if ((index) == 0 && _mesa_attr_zero_aliases_vertex(ctx)) {	\
    232 	 ATTR_UI(ctx, val, (type), normalized, 0, (arg));		\
    233       } else if ((index) < MAX_VERTEX_GENERIC_ATTRIBS) {		\
    234 	 ATTR_UI(ctx, val, (type), normalized, VBO_ATTRIB_GENERIC0 + (index), (arg)); \
    235       } else								\
    236 	 ERROR(GL_INVALID_VALUE);					\
    237    } while(0)
    238 
    239 
    240 /* Doubles */
    241 #define ATTR1DV( A, V ) ATTRD( A, 1, (V)[0], 0, 0, 1 )
    242 #define ATTR2DV( A, V ) ATTRD( A, 2, (V)[0], (V)[1], 0, 1 )
    243 #define ATTR3DV( A, V ) ATTRD( A, 3, (V)[0], (V)[1], (V)[2], 1 )
    244 #define ATTR4DV( A, V ) ATTRD( A, 4, (V)[0], (V)[1], (V)[2], (V)[3] )
    245 
    246 #define ATTR1D( A, X )          ATTRD( A, 1, X, 0, 0, 1 )
    247 #define ATTR2D( A, X, Y )       ATTRD( A, 2, X, Y, 0, 1 )
    248 #define ATTR3D( A, X, Y, Z )    ATTRD( A, 3, X, Y, Z, 1 )
    249 #define ATTR4D( A, X, Y, Z, W ) ATTRD( A, 4, X, Y, Z, W )
    250 
    251 #define ATTR1UIV64( A, V ) ATTRUI64( A, 1, (V)[0], 0, 0, 0 )
    252 #define ATTR1UI64( A, X )  ATTRUI64( A, 1, X, 0, 0, 0 )
    253 
    254 
    255 static void GLAPIENTRY
    256 TAG(Vertex2f)(GLfloat x, GLfloat y)
    257 {
    258    GET_CURRENT_CONTEXT(ctx);
    259    ATTR2F(VBO_ATTRIB_POS, x, y);
    260 }
    261 
    262 static void GLAPIENTRY
    263 TAG(Vertex2fv)(const GLfloat * v)
    264 {
    265    GET_CURRENT_CONTEXT(ctx);
    266    ATTR2FV(VBO_ATTRIB_POS, v);
    267 }
    268 
    269 static void GLAPIENTRY
    270 TAG(Vertex3f)(GLfloat x, GLfloat y, GLfloat z)
    271 {
    272    GET_CURRENT_CONTEXT(ctx);
    273    ATTR3F(VBO_ATTRIB_POS, x, y, z);
    274 }
    275 
    276 static void GLAPIENTRY
    277 TAG(Vertex3fv)(const GLfloat * v)
    278 {
    279    GET_CURRENT_CONTEXT(ctx);
    280    ATTR3FV(VBO_ATTRIB_POS, v);
    281 }
    282 
    283 static void GLAPIENTRY
    284 TAG(Vertex4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
    285 {
    286    GET_CURRENT_CONTEXT(ctx);
    287    ATTR4F(VBO_ATTRIB_POS, x, y, z, w);
    288 }
    289 
    290 static void GLAPIENTRY
    291 TAG(Vertex4fv)(const GLfloat * v)
    292 {
    293    GET_CURRENT_CONTEXT(ctx);
    294    ATTR4FV(VBO_ATTRIB_POS, v);
    295 }
    296 
    297 
    298 
    299 static void GLAPIENTRY
    300 TAG(TexCoord1f)(GLfloat x)
    301 {
    302    GET_CURRENT_CONTEXT(ctx);
    303    ATTR1F(VBO_ATTRIB_TEX0, x);
    304 }
    305 
    306 static void GLAPIENTRY
    307 TAG(TexCoord1fv)(const GLfloat * v)
    308 {
    309    GET_CURRENT_CONTEXT(ctx);
    310    ATTR1FV(VBO_ATTRIB_TEX0, v);
    311 }
    312 
    313 static void GLAPIENTRY
    314 TAG(TexCoord2f)(GLfloat x, GLfloat y)
    315 {
    316    GET_CURRENT_CONTEXT(ctx);
    317    ATTR2F(VBO_ATTRIB_TEX0, x, y);
    318 }
    319 
    320 static void GLAPIENTRY
    321 TAG(TexCoord2fv)(const GLfloat * v)
    322 {
    323    GET_CURRENT_CONTEXT(ctx);
    324    ATTR2FV(VBO_ATTRIB_TEX0, v);
    325 }
    326 
    327 static void GLAPIENTRY
    328 TAG(TexCoord3f)(GLfloat x, GLfloat y, GLfloat z)
    329 {
    330    GET_CURRENT_CONTEXT(ctx);
    331    ATTR3F(VBO_ATTRIB_TEX0, x, y, z);
    332 }
    333 
    334 static void GLAPIENTRY
    335 TAG(TexCoord3fv)(const GLfloat * v)
    336 {
    337    GET_CURRENT_CONTEXT(ctx);
    338    ATTR3FV(VBO_ATTRIB_TEX0, v);
    339 }
    340 
    341 static void GLAPIENTRY
    342 TAG(TexCoord4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
    343 {
    344    GET_CURRENT_CONTEXT(ctx);
    345    ATTR4F(VBO_ATTRIB_TEX0, x, y, z, w);
    346 }
    347 
    348 static void GLAPIENTRY
    349 TAG(TexCoord4fv)(const GLfloat * v)
    350 {
    351    GET_CURRENT_CONTEXT(ctx);
    352    ATTR4FV(VBO_ATTRIB_TEX0, v);
    353 }
    354 
    355 
    356 
    357 static void GLAPIENTRY
    358 TAG(Normal3f)(GLfloat x, GLfloat y, GLfloat z)
    359 {
    360    GET_CURRENT_CONTEXT(ctx);
    361    ATTR3F(VBO_ATTRIB_NORMAL, x, y, z);
    362 }
    363 
    364 static void GLAPIENTRY
    365 TAG(Normal3fv)(const GLfloat * v)
    366 {
    367    GET_CURRENT_CONTEXT(ctx);
    368    ATTR3FV(VBO_ATTRIB_NORMAL, v);
    369 }
    370 
    371 
    372 
    373 static void GLAPIENTRY
    374 TAG(FogCoordfEXT)(GLfloat x)
    375 {
    376    GET_CURRENT_CONTEXT(ctx);
    377    ATTR1F(VBO_ATTRIB_FOG, x);
    378 }
    379 
    380 
    381 
    382 static void GLAPIENTRY
    383 TAG(FogCoordfvEXT)(const GLfloat * v)
    384 {
    385    GET_CURRENT_CONTEXT(ctx);
    386    ATTR1FV(VBO_ATTRIB_FOG, v);
    387 }
    388 
    389 static void GLAPIENTRY
    390 TAG(Color3f)(GLfloat x, GLfloat y, GLfloat z)
    391 {
    392    GET_CURRENT_CONTEXT(ctx);
    393    ATTR3F(VBO_ATTRIB_COLOR0, x, y, z);
    394 }
    395 
    396 static void GLAPIENTRY
    397 TAG(Color3fv)(const GLfloat * v)
    398 {
    399    GET_CURRENT_CONTEXT(ctx);
    400    ATTR3FV(VBO_ATTRIB_COLOR0, v);
    401 }
    402 
    403 static void GLAPIENTRY
    404 TAG(Color4f)(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
    405 {
    406    GET_CURRENT_CONTEXT(ctx);
    407    ATTR4F(VBO_ATTRIB_COLOR0, x, y, z, w);
    408 }
    409 
    410 static void GLAPIENTRY
    411 TAG(Color4fv)(const GLfloat * v)
    412 {
    413    GET_CURRENT_CONTEXT(ctx);
    414    ATTR4FV(VBO_ATTRIB_COLOR0, v);
    415 }
    416 
    417 
    418 
    419 static void GLAPIENTRY
    420 TAG(SecondaryColor3fEXT)(GLfloat x, GLfloat y, GLfloat z)
    421 {
    422    GET_CURRENT_CONTEXT(ctx);
    423    ATTR3F(VBO_ATTRIB_COLOR1, x, y, z);
    424 }
    425 
    426 static void GLAPIENTRY
    427 TAG(SecondaryColor3fvEXT)(const GLfloat * v)
    428 {
    429    GET_CURRENT_CONTEXT(ctx);
    430    ATTR3FV(VBO_ATTRIB_COLOR1, v);
    431 }
    432 
    433 
    434 
    435 static void GLAPIENTRY
    436 TAG(EdgeFlag)(GLboolean b)
    437 {
    438    GET_CURRENT_CONTEXT(ctx);
    439    ATTR1F(VBO_ATTRIB_EDGEFLAG, (GLfloat) b);
    440 }
    441 
    442 
    443 
    444 static void GLAPIENTRY
    445 TAG(Indexf)(GLfloat f)
    446 {
    447    GET_CURRENT_CONTEXT(ctx);
    448    ATTR1F(VBO_ATTRIB_INDEX, f);
    449 }
    450 
    451 static void GLAPIENTRY
    452 TAG(Indexfv)(const GLfloat * f)
    453 {
    454    GET_CURRENT_CONTEXT(ctx);
    455    ATTR1FV(VBO_ATTRIB_INDEX, f);
    456 }
    457 
    458 
    459 
    460 static void GLAPIENTRY
    461 TAG(MultiTexCoord1f)(GLenum target, GLfloat x)
    462 {
    463    GET_CURRENT_CONTEXT(ctx);
    464    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    465    ATTR1F(attr, x);
    466 }
    467 
    468 static void GLAPIENTRY
    469 TAG(MultiTexCoord1fv)(GLenum target, const GLfloat * v)
    470 {
    471    GET_CURRENT_CONTEXT(ctx);
    472    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    473    ATTR1FV(attr, v);
    474 }
    475 
    476 static void GLAPIENTRY
    477 TAG(MultiTexCoord2f)(GLenum target, GLfloat x, GLfloat y)
    478 {
    479    GET_CURRENT_CONTEXT(ctx);
    480    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    481    ATTR2F(attr, x, y);
    482 }
    483 
    484 static void GLAPIENTRY
    485 TAG(MultiTexCoord2fv)(GLenum target, const GLfloat * v)
    486 {
    487    GET_CURRENT_CONTEXT(ctx);
    488    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    489    ATTR2FV(attr, v);
    490 }
    491 
    492 static void GLAPIENTRY
    493 TAG(MultiTexCoord3f)(GLenum target, GLfloat x, GLfloat y, GLfloat z)
    494 {
    495    GET_CURRENT_CONTEXT(ctx);
    496    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    497    ATTR3F(attr, x, y, z);
    498 }
    499 
    500 static void GLAPIENTRY
    501 TAG(MultiTexCoord3fv)(GLenum target, const GLfloat * v)
    502 {
    503    GET_CURRENT_CONTEXT(ctx);
    504    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    505    ATTR3FV(attr, v);
    506 }
    507 
    508 static void GLAPIENTRY
    509 TAG(MultiTexCoord4f)(GLenum target, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
    510 {
    511    GET_CURRENT_CONTEXT(ctx);
    512    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    513    ATTR4F(attr, x, y, z, w);
    514 }
    515 
    516 static void GLAPIENTRY
    517 TAG(MultiTexCoord4fv)(GLenum target, const GLfloat * v)
    518 {
    519    GET_CURRENT_CONTEXT(ctx);
    520    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
    521    ATTR4FV(attr, v);
    522 }
    523 
    524 
    525 /**
    526  * If index=0, does glVertexAttrib*() alias glVertex() to emit a vertex?
    527  * It depends on a few things, including whether we're inside or outside
    528  * of glBegin/glEnd.
    529  */
    530 static inline bool
    531 is_vertex_position(const struct gl_context *ctx, GLuint index)
    532 {
    533    return (index == 0 &&
    534            _mesa_attr_zero_aliases_vertex(ctx) &&
    535            _mesa_inside_begin_end(ctx));
    536 }
    537 
    538 
    539 static void GLAPIENTRY
    540 TAG(VertexAttrib1fARB)(GLuint index, GLfloat x)
    541 {
    542    GET_CURRENT_CONTEXT(ctx);
    543    if (is_vertex_position(ctx, index))
    544       ATTR1F(0, x);
    545    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    546       ATTR1F(VBO_ATTRIB_GENERIC0 + index, x);
    547    else
    548       ERROR(GL_INVALID_VALUE);
    549 }
    550 
    551 static void GLAPIENTRY
    552 TAG(VertexAttrib1fvARB)(GLuint index, const GLfloat * v)
    553 {
    554    GET_CURRENT_CONTEXT(ctx);
    555    if (is_vertex_position(ctx, index))
    556       ATTR1FV(0, v);
    557    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    558       ATTR1FV(VBO_ATTRIB_GENERIC0 + index, v);
    559    else
    560       ERROR(GL_INVALID_VALUE);
    561 }
    562 
    563 static void GLAPIENTRY
    564 TAG(VertexAttrib2fARB)(GLuint index, GLfloat x, GLfloat y)
    565 {
    566    GET_CURRENT_CONTEXT(ctx);
    567    if (is_vertex_position(ctx, index))
    568       ATTR2F(0, x, y);
    569    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    570       ATTR2F(VBO_ATTRIB_GENERIC0 + index, x, y);
    571    else
    572       ERROR(GL_INVALID_VALUE);
    573 }
    574 
    575 static void GLAPIENTRY
    576 TAG(VertexAttrib2fvARB)(GLuint index, const GLfloat * v)
    577 {
    578    GET_CURRENT_CONTEXT(ctx);
    579    if (is_vertex_position(ctx, index))
    580       ATTR2FV(0, v);
    581    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    582       ATTR2FV(VBO_ATTRIB_GENERIC0 + index, v);
    583    else
    584       ERROR(GL_INVALID_VALUE);
    585 }
    586 
    587 static void GLAPIENTRY
    588 TAG(VertexAttrib3fARB)(GLuint index, GLfloat x, GLfloat y, GLfloat z)
    589 {
    590    GET_CURRENT_CONTEXT(ctx);
    591    if (is_vertex_position(ctx, index))
    592       ATTR3F(0, x, y, z);
    593    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    594       ATTR3F(VBO_ATTRIB_GENERIC0 + index, x, y, z);
    595    else
    596       ERROR(GL_INVALID_VALUE);
    597 }
    598 
    599 static void GLAPIENTRY
    600 TAG(VertexAttrib3fvARB)(GLuint index, const GLfloat * v)
    601 {
    602    GET_CURRENT_CONTEXT(ctx);
    603    if (is_vertex_position(ctx, index))
    604       ATTR3FV(0, v);
    605    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    606       ATTR3FV(VBO_ATTRIB_GENERIC0 + index, v);
    607    else
    608       ERROR(GL_INVALID_VALUE);
    609 }
    610 
    611 static void GLAPIENTRY
    612 TAG(VertexAttrib4fARB)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
    613 {
    614    GET_CURRENT_CONTEXT(ctx);
    615    if (is_vertex_position(ctx, index))
    616       ATTR4F(0, x, y, z, w);
    617    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    618       ATTR4F(VBO_ATTRIB_GENERIC0 + index, x, y, z, w);
    619    else
    620       ERROR(GL_INVALID_VALUE);
    621 }
    622 
    623 static void GLAPIENTRY
    624 TAG(VertexAttrib4fvARB)(GLuint index, const GLfloat * v)
    625 {
    626    GET_CURRENT_CONTEXT(ctx);
    627    if (is_vertex_position(ctx, index))
    628       ATTR4FV(0, v);
    629    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    630       ATTR4FV(VBO_ATTRIB_GENERIC0 + index, v);
    631    else
    632       ERROR(GL_INVALID_VALUE);
    633 }
    634 
    635 
    636 
    637 /* Integer-valued generic attributes.
    638  * XXX: the integers just get converted to floats at this time
    639  */
    640 static void GLAPIENTRY
    641 TAG(VertexAttribI1i)(GLuint index, GLint x)
    642 {
    643    GET_CURRENT_CONTEXT(ctx);
    644    if (is_vertex_position(ctx, index))
    645       ATTR1I(0, x);
    646    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    647       ATTR1I(VBO_ATTRIB_GENERIC0 + index, x);
    648    else
    649       ERROR(GL_INVALID_VALUE);
    650 }
    651 
    652 static void GLAPIENTRY
    653 TAG(VertexAttribI2i)(GLuint index, GLint x, GLint y)
    654 {
    655    GET_CURRENT_CONTEXT(ctx);
    656    if (is_vertex_position(ctx, index))
    657       ATTR2I(0, x, y);
    658    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    659       ATTR2I(VBO_ATTRIB_GENERIC0 + index, x, y);
    660    else
    661       ERROR(GL_INVALID_VALUE);
    662 }
    663 
    664 static void GLAPIENTRY
    665 TAG(VertexAttribI3i)(GLuint index, GLint x, GLint y, GLint z)
    666 {
    667    GET_CURRENT_CONTEXT(ctx);
    668    if (is_vertex_position(ctx, index))
    669       ATTR3I(0, x, y, z);
    670    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    671       ATTR3I(VBO_ATTRIB_GENERIC0 + index, x, y, z);
    672    else
    673       ERROR(GL_INVALID_VALUE);
    674 }
    675 
    676 static void GLAPIENTRY
    677 TAG(VertexAttribI4i)(GLuint index, GLint x, GLint y, GLint z, GLint w)
    678 {
    679    GET_CURRENT_CONTEXT(ctx);
    680    if (is_vertex_position(ctx, index))
    681       ATTR4I(0, x, y, z, w);
    682    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    683       ATTR4I(VBO_ATTRIB_GENERIC0 + index, x, y, z, w);
    684    else
    685       ERROR(GL_INVALID_VALUE);
    686 }
    687 
    688 static void GLAPIENTRY
    689 TAG(VertexAttribI2iv)(GLuint index, const GLint *v)
    690 {
    691    GET_CURRENT_CONTEXT(ctx);
    692    if (is_vertex_position(ctx, index))
    693       ATTR2IV(0, v);
    694    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    695       ATTR2IV(VBO_ATTRIB_GENERIC0 + index, v);
    696    else
    697       ERROR(GL_INVALID_VALUE);
    698 }
    699 
    700 static void GLAPIENTRY
    701 TAG(VertexAttribI3iv)(GLuint index, const GLint *v)
    702 {
    703    GET_CURRENT_CONTEXT(ctx);
    704    if (is_vertex_position(ctx, index))
    705       ATTR3IV(0, v);
    706    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    707       ATTR3IV(VBO_ATTRIB_GENERIC0 + index, v);
    708    else
    709       ERROR(GL_INVALID_VALUE);
    710 }
    711 
    712 static void GLAPIENTRY
    713 TAG(VertexAttribI4iv)(GLuint index, const GLint *v)
    714 {
    715    GET_CURRENT_CONTEXT(ctx);
    716    if (is_vertex_position(ctx, index))
    717       ATTR4IV(0, v);
    718    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    719       ATTR4IV(VBO_ATTRIB_GENERIC0 + index, v);
    720    else
    721       ERROR(GL_INVALID_VALUE);
    722 }
    723 
    724 
    725 
    726 /* Unsigned integer-valued generic attributes.
    727  * XXX: the integers just get converted to floats at this time
    728  */
    729 static void GLAPIENTRY
    730 TAG(VertexAttribI1ui)(GLuint index, GLuint x)
    731 {
    732    GET_CURRENT_CONTEXT(ctx);
    733    if (is_vertex_position(ctx, index))
    734       ATTR1UI(0, x);
    735    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    736       ATTR1UI(VBO_ATTRIB_GENERIC0 + index, x);
    737    else
    738       ERROR(GL_INVALID_VALUE);
    739 }
    740 
    741 static void GLAPIENTRY
    742 TAG(VertexAttribI2ui)(GLuint index, GLuint x, GLuint y)
    743 {
    744    GET_CURRENT_CONTEXT(ctx);
    745    if (is_vertex_position(ctx, index))
    746       ATTR2UI(0, x, y);
    747    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    748       ATTR2UI(VBO_ATTRIB_GENERIC0 + index, x, y);
    749    else
    750       ERROR(GL_INVALID_VALUE);
    751 }
    752 
    753 static void GLAPIENTRY
    754 TAG(VertexAttribI3ui)(GLuint index, GLuint x, GLuint y, GLuint z)
    755 {
    756    GET_CURRENT_CONTEXT(ctx);
    757    if (is_vertex_position(ctx, index))
    758       ATTR3UI(0, x, y, z);
    759    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    760       ATTR3UI(VBO_ATTRIB_GENERIC0 + index, x, y, z);
    761    else
    762       ERROR(GL_INVALID_VALUE);
    763 }
    764 
    765 static void GLAPIENTRY
    766 TAG(VertexAttribI4ui)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w)
    767 {
    768    GET_CURRENT_CONTEXT(ctx);
    769    if (is_vertex_position(ctx, index))
    770       ATTR4UI(0, x, y, z, w);
    771    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    772       ATTR4UI(VBO_ATTRIB_GENERIC0 + index, x, y, z, w);
    773    else
    774       ERROR(GL_INVALID_VALUE);
    775 }
    776 
    777 static void GLAPIENTRY
    778 TAG(VertexAttribI2uiv)(GLuint index, const GLuint *v)
    779 {
    780    GET_CURRENT_CONTEXT(ctx);
    781    if (is_vertex_position(ctx, index))
    782       ATTR2UIV(0, v);
    783    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    784       ATTR2UIV(VBO_ATTRIB_GENERIC0 + index, v);
    785    else
    786       ERROR(GL_INVALID_VALUE);
    787 }
    788 
    789 static void GLAPIENTRY
    790 TAG(VertexAttribI3uiv)(GLuint index, const GLuint *v)
    791 {
    792    GET_CURRENT_CONTEXT(ctx);
    793    if (is_vertex_position(ctx, index))
    794       ATTR3UIV(0, v);
    795    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    796       ATTR3UIV(VBO_ATTRIB_GENERIC0 + index, v);
    797    else
    798       ERROR(GL_INVALID_VALUE);
    799 }
    800 
    801 static void GLAPIENTRY
    802 TAG(VertexAttribI4uiv)(GLuint index, const GLuint *v)
    803 {
    804    GET_CURRENT_CONTEXT(ctx);
    805    if (is_vertex_position(ctx, index))
    806       ATTR4UIV(0, v);
    807    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
    808       ATTR4UIV(VBO_ATTRIB_GENERIC0 + index, v);
    809    else
    810       ERROR(GL_INVALID_VALUE);
    811 }
    812 
    813 
    814 
    815 /* These entrypoints are no longer used for NV_vertex_program but they are
    816  * used by the display list and other code specifically because of their
    817  * property of aliasing with the legacy Vertex, TexCoord, Normal, etc
    818  * attributes.  (See vbo_save_loopback.c)
    819  */
    820 static void GLAPIENTRY
    821 TAG(VertexAttrib1fNV)(GLuint index, GLfloat x)
    822 {
    823    GET_CURRENT_CONTEXT(ctx);
    824    if (index < VBO_ATTRIB_MAX)
    825       ATTR1F(index, x);
    826 }
    827 
    828 static void GLAPIENTRY
    829 TAG(VertexAttrib1fvNV)(GLuint index, const GLfloat * v)
    830 {
    831    GET_CURRENT_CONTEXT(ctx);
    832    if (index < VBO_ATTRIB_MAX)
    833       ATTR1FV(index, v);
    834 }
    835 
    836 static void GLAPIENTRY
    837 TAG(VertexAttrib2fNV)(GLuint index, GLfloat x, GLfloat y)
    838 {
    839    GET_CURRENT_CONTEXT(ctx);
    840    if (index < VBO_ATTRIB_MAX)
    841       ATTR2F(index, x, y);
    842 }
    843 
    844 static void GLAPIENTRY
    845 TAG(VertexAttrib2fvNV)(GLuint index, const GLfloat * v)
    846 {
    847    GET_CURRENT_CONTEXT(ctx);
    848    if (index < VBO_ATTRIB_MAX)
    849       ATTR2FV(index, v);
    850 }
    851 
    852 static void GLAPIENTRY
    853 TAG(VertexAttrib3fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z)
    854 {
    855    GET_CURRENT_CONTEXT(ctx);
    856    if (index < VBO_ATTRIB_MAX)
    857       ATTR3F(index, x, y, z);
    858 }
    859 
    860 static void GLAPIENTRY
    861 TAG(VertexAttrib3fvNV)(GLuint index,
    862  const GLfloat * v)
    863 {
    864    GET_CURRENT_CONTEXT(ctx);
    865    if (index < VBO_ATTRIB_MAX)
    866       ATTR3FV(index, v);
    867 }
    868 
    869 static void GLAPIENTRY
    870 TAG(VertexAttrib4fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
    871 {
    872    GET_CURRENT_CONTEXT(ctx);
    873    if (index < VBO_ATTRIB_MAX)
    874       ATTR4F(index, x, y, z, w);
    875 }
    876 
    877 static void GLAPIENTRY
    878 TAG(VertexAttrib4fvNV)(GLuint index, const GLfloat * v)
    879 {
    880    GET_CURRENT_CONTEXT(ctx);
    881    if (index < VBO_ATTRIB_MAX)
    882       ATTR4FV(index, v);
    883 }
    884 
    885 
    886 #define ERROR_IF_NOT_PACKED_TYPE(ctx, type, func) \
    887    if (type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_INT_2_10_10_10_REV) { \
    888       _mesa_error(ctx, GL_INVALID_ENUM, "%s(type)", func); \
    889       return; \
    890    }
    891 
    892 /* Extended version of ERROR_IF_NOT_PACKED_TYPE which also
    893  * accepts GL_UNSIGNED_INT_10F_11F_11F_REV.
    894  *
    895  * Only used for VertexAttribP[123]ui[v]; VertexAttribP4* cannot use this type,
    896  * and neither can legacy vertex attribs.
    897  */
    898 #define ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, func) \
    899    if (type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_INT_2_10_10_10_REV && \
    900        type != GL_UNSIGNED_INT_10F_11F_11F_REV) { \
    901       _mesa_error(ctx, GL_INVALID_ENUM, "%s(type)", func); \
    902       return; \
    903    }
    904 
    905 static void GLAPIENTRY
    906 TAG(VertexP2ui)(GLenum type, GLuint value)
    907 {
    908    GET_CURRENT_CONTEXT(ctx);
    909    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP2ui");
    910    ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_POS, value);
    911 }
    912 
    913 static void GLAPIENTRY
    914 TAG(VertexP2uiv)(GLenum type, const GLuint *value)
    915 {
    916    GET_CURRENT_CONTEXT(ctx);
    917    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP2uiv");
    918    ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_POS, value[0]);
    919 }
    920 
    921 static void GLAPIENTRY
    922 TAG(VertexP3ui)(GLenum type, GLuint value)
    923 {
    924    GET_CURRENT_CONTEXT(ctx);
    925    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP3ui");
    926    ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_POS, value);
    927 }
    928 
    929 static void GLAPIENTRY
    930 TAG(VertexP3uiv)(GLenum type, const GLuint *value)
    931 {
    932    GET_CURRENT_CONTEXT(ctx);
    933    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP3uiv");
    934    ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_POS, value[0]);
    935 }
    936 
    937 static void GLAPIENTRY
    938 TAG(VertexP4ui)(GLenum type, GLuint value)
    939 {
    940    GET_CURRENT_CONTEXT(ctx);
    941    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP4ui");
    942    ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_POS, value);
    943 }
    944 
    945 static void GLAPIENTRY
    946 TAG(VertexP4uiv)(GLenum type, const GLuint *value)
    947 {
    948    GET_CURRENT_CONTEXT(ctx);
    949    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP4uiv");
    950    ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_POS, value[0]);
    951 }
    952 
    953 static void GLAPIENTRY
    954 TAG(TexCoordP1ui)(GLenum type, GLuint coords)
    955 {
    956    GET_CURRENT_CONTEXT(ctx);
    957    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP1ui");
    958    ATTR_UI(ctx, 1, type, 0, VBO_ATTRIB_TEX0, coords);
    959 }
    960 
    961 static void GLAPIENTRY
    962 TAG(TexCoordP1uiv)(GLenum type, const GLuint *coords)
    963 {
    964    GET_CURRENT_CONTEXT(ctx);
    965    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP1uiv");
    966    ATTR_UI(ctx, 1, type, 0, VBO_ATTRIB_TEX0, coords[0]);
    967 }
    968 
    969 static void GLAPIENTRY
    970 TAG(TexCoordP2ui)(GLenum type, GLuint coords)
    971 {
    972    GET_CURRENT_CONTEXT(ctx);
    973    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP2ui");
    974    ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_TEX0, coords);
    975 }
    976 
    977 static void GLAPIENTRY
    978 TAG(TexCoordP2uiv)(GLenum type, const GLuint *coords)
    979 {
    980    GET_CURRENT_CONTEXT(ctx);
    981    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP2uiv");
    982    ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_TEX0, coords[0]);
    983 }
    984 
    985 static void GLAPIENTRY
    986 TAG(TexCoordP3ui)(GLenum type, GLuint coords)
    987 {
    988    GET_CURRENT_CONTEXT(ctx);
    989    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP3ui");
    990    ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_TEX0, coords);
    991 }
    992 
    993 static void GLAPIENTRY
    994 TAG(TexCoordP3uiv)(GLenum type, const GLuint *coords)
    995 {
    996    GET_CURRENT_CONTEXT(ctx);
    997    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP3uiv");
    998    ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_TEX0, coords[0]);
    999 }
   1000 
   1001 static void GLAPIENTRY
   1002 TAG(TexCoordP4ui)(GLenum type, GLuint coords)
   1003 {
   1004    GET_CURRENT_CONTEXT(ctx);
   1005    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP4ui");
   1006    ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_TEX0, coords);
   1007 }
   1008 
   1009 static void GLAPIENTRY
   1010 TAG(TexCoordP4uiv)(GLenum type, const GLuint *coords)
   1011 {
   1012    GET_CURRENT_CONTEXT(ctx);
   1013    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP4uiv");
   1014    ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_TEX0, coords[0]);
   1015 }
   1016 
   1017 static void GLAPIENTRY
   1018 TAG(MultiTexCoordP1ui)(GLenum target, GLenum type, GLuint coords)
   1019 {
   1020    GET_CURRENT_CONTEXT(ctx);
   1021    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1022    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP1ui");
   1023    ATTR_UI(ctx, 1, type, 0, attr, coords);
   1024 }
   1025 
   1026 static void GLAPIENTRY
   1027 TAG(MultiTexCoordP1uiv)(GLenum target, GLenum type, const GLuint *coords)
   1028 {
   1029    GET_CURRENT_CONTEXT(ctx);
   1030    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1031    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP1uiv");
   1032    ATTR_UI(ctx, 1, type, 0, attr, coords[0]);
   1033 }
   1034 
   1035 static void GLAPIENTRY
   1036 TAG(MultiTexCoordP2ui)(GLenum target, GLenum type, GLuint coords)
   1037 {
   1038    GET_CURRENT_CONTEXT(ctx);
   1039    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1040    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP2ui");
   1041    ATTR_UI(ctx, 2, type, 0, attr, coords);
   1042 }
   1043 
   1044 static void GLAPIENTRY
   1045 TAG(MultiTexCoordP2uiv)(GLenum target, GLenum type, const GLuint *coords)
   1046 {
   1047    GET_CURRENT_CONTEXT(ctx);
   1048    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1049    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP2uiv");
   1050    ATTR_UI(ctx, 2, type, 0, attr, coords[0]);
   1051 }
   1052 
   1053 static void GLAPIENTRY
   1054 TAG(MultiTexCoordP3ui)(GLenum target, GLenum type, GLuint coords)
   1055 {
   1056    GET_CURRENT_CONTEXT(ctx);
   1057    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1058    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP3ui");
   1059    ATTR_UI(ctx, 3, type, 0, attr, coords);
   1060 }
   1061 
   1062 static void GLAPIENTRY
   1063 TAG(MultiTexCoordP3uiv)(GLenum target, GLenum type, const GLuint *coords)
   1064 {
   1065    GET_CURRENT_CONTEXT(ctx);
   1066    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1067    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP3uiv");
   1068    ATTR_UI(ctx, 3, type, 0, attr, coords[0]);
   1069 }
   1070 
   1071 static void GLAPIENTRY
   1072 TAG(MultiTexCoordP4ui)(GLenum target, GLenum type, GLuint coords)
   1073 {
   1074    GET_CURRENT_CONTEXT(ctx);
   1075    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1076    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP4ui");
   1077    ATTR_UI(ctx, 4, type, 0, attr, coords);
   1078 }
   1079 
   1080 static void GLAPIENTRY
   1081 TAG(MultiTexCoordP4uiv)(GLenum target, GLenum type, const GLuint *coords)
   1082 {
   1083    GET_CURRENT_CONTEXT(ctx);
   1084    GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0;
   1085    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP4uiv");
   1086    ATTR_UI(ctx, 4, type, 0, attr, coords[0]);
   1087 }
   1088 
   1089 static void GLAPIENTRY
   1090 TAG(NormalP3ui)(GLenum type, GLuint coords)
   1091 {
   1092    GET_CURRENT_CONTEXT(ctx);
   1093    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glNormalP3ui");
   1094    ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_NORMAL, coords);
   1095 }
   1096 
   1097 static void GLAPIENTRY
   1098 TAG(NormalP3uiv)(GLenum type, const GLuint *coords)
   1099 {
   1100    GET_CURRENT_CONTEXT(ctx);
   1101    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glNormalP3uiv");
   1102    ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_NORMAL, coords[0]);
   1103 }
   1104 
   1105 static void GLAPIENTRY
   1106 TAG(ColorP3ui)(GLenum type, GLuint color)
   1107 {
   1108    GET_CURRENT_CONTEXT(ctx);
   1109    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP3ui");
   1110    ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR0, color);
   1111 }
   1112 
   1113 static void GLAPIENTRY
   1114 TAG(ColorP3uiv)(GLenum type, const GLuint *color)
   1115 {
   1116    GET_CURRENT_CONTEXT(ctx);
   1117    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP3uiv");
   1118    ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR0, color[0]);
   1119 }
   1120 
   1121 static void GLAPIENTRY
   1122 TAG(ColorP4ui)(GLenum type, GLuint color)
   1123 {
   1124    GET_CURRENT_CONTEXT(ctx);
   1125    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP4ui");
   1126    ATTR_UI(ctx, 4, type, 1, VBO_ATTRIB_COLOR0, color);
   1127 }
   1128 
   1129 static void GLAPIENTRY
   1130 TAG(ColorP4uiv)(GLenum type, const GLuint *color)
   1131 {
   1132    GET_CURRENT_CONTEXT(ctx);
   1133    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP4uiv");
   1134    ATTR_UI(ctx, 4, type, 1, VBO_ATTRIB_COLOR0, color[0]);
   1135 }
   1136 
   1137 static void GLAPIENTRY
   1138 TAG(SecondaryColorP3ui)(GLenum type, GLuint color)
   1139 {
   1140    GET_CURRENT_CONTEXT(ctx);
   1141    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glSecondaryColorP3ui");
   1142    ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR1, color);
   1143 }
   1144 
   1145 static void GLAPIENTRY
   1146 TAG(SecondaryColorP3uiv)(GLenum type, const GLuint *color)
   1147 {
   1148    GET_CURRENT_CONTEXT(ctx);
   1149    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glSecondaryColorP3uiv");
   1150    ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR1, color[0]);
   1151 }
   1152 
   1153 static void GLAPIENTRY
   1154 TAG(VertexAttribP1ui)(GLuint index, GLenum type, GLboolean normalized,
   1155 		      GLuint value)
   1156 {
   1157    GET_CURRENT_CONTEXT(ctx);
   1158    ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP1ui");
   1159    ATTR_UI_INDEX(ctx, 1, type, normalized, index, value);
   1160 }
   1161 
   1162 static void GLAPIENTRY
   1163 TAG(VertexAttribP2ui)(GLuint index, GLenum type, GLboolean normalized,
   1164 		      GLuint value)
   1165 {
   1166    GET_CURRENT_CONTEXT(ctx);
   1167    ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP2ui");
   1168    ATTR_UI_INDEX(ctx, 2, type, normalized, index, value);
   1169 }
   1170 
   1171 static void GLAPIENTRY
   1172 TAG(VertexAttribP3ui)(GLuint index, GLenum type, GLboolean normalized,
   1173 		      GLuint value)
   1174 {
   1175    GET_CURRENT_CONTEXT(ctx);
   1176    ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP3ui");
   1177    ATTR_UI_INDEX(ctx, 3, type, normalized, index, value);
   1178 }
   1179 
   1180 static void GLAPIENTRY
   1181 TAG(VertexAttribP4ui)(GLuint index, GLenum type, GLboolean normalized,
   1182 		      GLuint value)
   1183 {
   1184    GET_CURRENT_CONTEXT(ctx);
   1185    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP4ui");
   1186    ATTR_UI_INDEX(ctx, 4, type, normalized, index, value);
   1187 }
   1188 
   1189 static void GLAPIENTRY
   1190 TAG(VertexAttribP1uiv)(GLuint index, GLenum type, GLboolean normalized,
   1191 		       const GLuint *value)
   1192 {
   1193    GET_CURRENT_CONTEXT(ctx);
   1194    ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP1uiv");
   1195    ATTR_UI_INDEX(ctx, 1, type, normalized, index, *value);
   1196 }
   1197 
   1198 static void GLAPIENTRY
   1199 TAG(VertexAttribP2uiv)(GLuint index, GLenum type, GLboolean normalized,
   1200 		       const GLuint *value)
   1201 {
   1202    GET_CURRENT_CONTEXT(ctx);
   1203    ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP2uiv");
   1204    ATTR_UI_INDEX(ctx, 2, type, normalized, index, *value);
   1205 }
   1206 
   1207 static void GLAPIENTRY
   1208 TAG(VertexAttribP3uiv)(GLuint index, GLenum type, GLboolean normalized,
   1209 		       const GLuint *value)
   1210 {
   1211    GET_CURRENT_CONTEXT(ctx);
   1212    ERROR_IF_NOT_PACKED_TYPE_EXT(ctx, type, "glVertexAttribP3uiv");
   1213    ATTR_UI_INDEX(ctx, 3, type, normalized, index, *value);
   1214 }
   1215 
   1216 static void GLAPIENTRY
   1217 TAG(VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized,
   1218 		      const GLuint *value)
   1219 {
   1220    GET_CURRENT_CONTEXT(ctx);
   1221    ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP4uiv");
   1222    ATTR_UI_INDEX(ctx, 4, type, normalized, index, *value);
   1223 }
   1224 
   1225 
   1226 
   1227 static void GLAPIENTRY
   1228 TAG(VertexAttribL1d)(GLuint index, GLdouble x)
   1229 {
   1230    GET_CURRENT_CONTEXT(ctx);
   1231    if (is_vertex_position(ctx, index))
   1232       ATTR1D(0, x);
   1233    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1234       ATTR1D(VBO_ATTRIB_GENERIC0 + index, x);
   1235    else
   1236       ERROR(GL_INVALID_VALUE);
   1237 }
   1238 
   1239 static void GLAPIENTRY
   1240 TAG(VertexAttribL1dv)(GLuint index, const GLdouble * v)
   1241 {
   1242    GET_CURRENT_CONTEXT(ctx);
   1243    if (is_vertex_position(ctx, index))
   1244       ATTR1DV(0, v);
   1245    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1246       ATTR1DV(VBO_ATTRIB_GENERIC0 + index, v);
   1247    else
   1248       ERROR(GL_INVALID_VALUE);
   1249 }
   1250 
   1251 static void GLAPIENTRY
   1252 TAG(VertexAttribL2d)(GLuint index, GLdouble x, GLdouble y)
   1253 {
   1254    GET_CURRENT_CONTEXT(ctx);
   1255    if (is_vertex_position(ctx, index))
   1256       ATTR2D(0, x, y);
   1257    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1258       ATTR2D(VBO_ATTRIB_GENERIC0 + index, x, y);
   1259    else
   1260       ERROR(GL_INVALID_VALUE);
   1261 }
   1262 
   1263 static void GLAPIENTRY
   1264 TAG(VertexAttribL2dv)(GLuint index, const GLdouble * v)
   1265 {
   1266    GET_CURRENT_CONTEXT(ctx);
   1267    if (is_vertex_position(ctx, index))
   1268       ATTR2DV(0, v);
   1269    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1270       ATTR2DV(VBO_ATTRIB_GENERIC0 + index, v);
   1271    else
   1272       ERROR(GL_INVALID_VALUE);
   1273 }
   1274 
   1275 static void GLAPIENTRY
   1276 TAG(VertexAttribL3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z)
   1277 {
   1278    GET_CURRENT_CONTEXT(ctx);
   1279    if (is_vertex_position(ctx, index))
   1280       ATTR3D(0, x, y, z);
   1281    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1282       ATTR3D(VBO_ATTRIB_GENERIC0 + index, x, y, z);
   1283    else
   1284       ERROR(GL_INVALID_VALUE);
   1285 }
   1286 
   1287 static void GLAPIENTRY
   1288 TAG(VertexAttribL3dv)(GLuint index, const GLdouble * v)
   1289 {
   1290    GET_CURRENT_CONTEXT(ctx);
   1291    if (is_vertex_position(ctx, index))
   1292       ATTR3DV(0, v);
   1293    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1294       ATTR3DV(VBO_ATTRIB_GENERIC0 + index, v);
   1295    else
   1296       ERROR(GL_INVALID_VALUE);
   1297 }
   1298 
   1299 static void GLAPIENTRY
   1300 TAG(VertexAttribL4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w)
   1301 {
   1302    GET_CURRENT_CONTEXT(ctx);
   1303    if (is_vertex_position(ctx, index))
   1304       ATTR4D(0, x, y, z, w);
   1305    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1306       ATTR4D(VBO_ATTRIB_GENERIC0 + index, x, y, z, w);
   1307    else
   1308       ERROR(GL_INVALID_VALUE);
   1309 }
   1310 
   1311 static void GLAPIENTRY
   1312 TAG(VertexAttribL4dv)(GLuint index, const GLdouble * v)
   1313 {
   1314    GET_CURRENT_CONTEXT(ctx);
   1315    if (is_vertex_position(ctx, index))
   1316       ATTR4DV(0, v);
   1317    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1318       ATTR4DV(VBO_ATTRIB_GENERIC0 + index, v);
   1319    else
   1320       ERROR(GL_INVALID_VALUE);
   1321 }
   1322 
   1323 static void GLAPIENTRY
   1324 TAG(VertexAttribL1ui64ARB)(GLuint index, GLuint64EXT x)
   1325 {
   1326    GET_CURRENT_CONTEXT(ctx);
   1327    if (is_vertex_position(ctx, index))
   1328       ATTR1UI64(0, x);
   1329    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1330       ATTR1UI64(VBO_ATTRIB_GENERIC0 + index, x);
   1331    else
   1332       ERROR(GL_INVALID_VALUE);
   1333 }
   1334 
   1335 static void GLAPIENTRY
   1336 TAG(VertexAttribL1ui64vARB)(GLuint index, const GLuint64EXT *v)
   1337 {
   1338    GET_CURRENT_CONTEXT(ctx);
   1339    if (is_vertex_position(ctx, index))
   1340       ATTR1UIV64(0, v);
   1341    else if (index < MAX_VERTEX_GENERIC_ATTRIBS)
   1342       ATTR1UIV64(VBO_ATTRIB_GENERIC0 + index, v);
   1343    else
   1344       ERROR(GL_INVALID_VALUE);
   1345 }
   1346 
   1347 #undef ATTR1FV
   1348 #undef ATTR2FV
   1349 #undef ATTR3FV
   1350 #undef ATTR4FV
   1351 
   1352 #undef ATTR1F
   1353 #undef ATTR2F
   1354 #undef ATTR3F
   1355 #undef ATTR4F
   1356 
   1357 #undef ATTR_UI
   1358 
   1359 #undef MAT
   1360