indirect_vertex_array.c revision f027f8d3a832f9820acba8892e2540094b01c9ae
1fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/*
2fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * (C) Copyright IBM Corporation 2004, 2005
3fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * All Rights Reserved.
4fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
5fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a
6fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * copy of this software and associated documentation files (the "Software"),
7fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * to deal in the Software without restriction, including without limitation
8fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sub license,
9fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * and/or sell copies of the Software, and to permit persons to whom the
10fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Software is furnished to do so, subject to the following conditions:
11fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
12fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The above copyright notice and this permission notice (including the next
13fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * paragraph) shall be included in all copies or substantial portions of the
14fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Software.
15fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
16fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * IBM,
20fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * SOFTWARE.
24fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
25fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
26fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#include <inttypes.h>
27fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#include <assert.h>
28fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#include <string.h>
29fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
3003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick#include "glxclient.h"
3103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick#include "indirect.h"
32fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#include <GL/glxproto.h>
33fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#include "glxextensions.h"
34fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#include "indirect_vertex_array.h"
35f027f8d3a832f9820acba8892e2540094b01c9aeGeorge Sapountzis#include "indirect_vertex_array_priv.h"
36fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
3703dc437363429d275b7f8cae74201a8e7993a52bIan Romanick#define __GLX_PAD(n) (((n)+3) & ~3)
3803dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
39fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
40fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \file indirect_vertex_array.c
41fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Implement GLX protocol for vertex arrays and vertex buffer objects.
42fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
43fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The most important function in this fill is \c fill_array_info_cache.
44fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
45fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * in the DrawArrays protocol.  Certain operations, such as enabling or
46fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * disabling an array, can invalidate this cache.  \c fill_array_info_cache
47fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * fills-in this data.  Additionally, it examines the enabled state and
48fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * other factors to determine what "version" of DrawArrays protocoal can be
49fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * used.
50fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
51fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Current, only two versions of DrawArrays protocol are implemented.  The
52fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * first version is the "none" protocol.  This is the fallback when the
53fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * server does not support GL 1.1 / EXT_vertex_arrays.  It is implemented
54fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * by sending batches of immediate mode commands that are equivalent to the
55fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * DrawArrays protocol.
56fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
57fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The other protocol that is currently implemented is the "old" protocol.
58fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * This is the GL 1.1 DrawArrays protocol.  The only difference between GL
59fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
60fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * This protocol is called "old" because the ARB is in the process of
61fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * defining a new protocol, which will probably be called wither "new" or
62fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * "vbo", to support multiple texture coordinate arrays, generic attributes,
63fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * and vertex buffer objects.
64fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
65fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \author Ian Romanick <idr@us.ibm.com>
66fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
67fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
68fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count );
69fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawArrays_old ( GLenum mode, GLint first, GLsizei count );
70fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
71fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
72fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLvoid *indices );
73fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawElements_old ( GLenum mode, GLsizei count, GLenum type,
74fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLvoid *indices );
75fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
76fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
77fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLubyte * emit_element_none( GLubyte * dst,
78fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays, unsigned index );
79fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLubyte * emit_element_old( GLubyte * dst,
80fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays, unsigned index );
81fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic struct array_state * get_array_entry(
82fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays, GLenum key, unsigned index );
83fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void fill_array_info_cache( struct array_state_vector * arrays );
8440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickstatic GLboolean validate_mode(__GLXcontext *gc, GLenum mode);
8540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickstatic GLboolean validate_count(__GLXcontext *gc, GLsizei count);
8603dc437363429d275b7f8cae74201a8e7993a52bIan Romanickstatic GLboolean validate_type(__GLXcontext *gc, GLenum type);
87fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
88fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
89fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
90fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Table of sizes, in bytes, of a GL types.  All of the type enums are be in
91fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * the range 0x1400 - 0x140F.  That includes types added by extensions (i.e.,
92fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_HALF_FLOAT_NV).  This elements of this table correspond to the
93fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * type enums masked with 0x0f.
94fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
95fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \notes
96fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_HALF_FLOAT_NV is not included.  Neither are \c GL_2_BYTES,
97fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_3_BYTES, or \c GL_4_BYTES.
98fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
99fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickconst GLuint __glXTypeSize_table[16] = {
100fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
101fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick};
102fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
103fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
104fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
105fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
106fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Initialize vertex array state of a GLX context.
107fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
108fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param gc  GLX context whose vertex array state is to be initialized.
109fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
110fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \warning
111fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * This function may only be called after __GLXcontext::gl_extension_bits,
112fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * __GLXcontext::server_minor, and __GLXcontext::server_major have been
113fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * initialized.  These values are used to determine what vertex arrays are
114fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * supported.
115fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
116fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \bug
117fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Return values from malloc are not properly tested.
118fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
119fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
120fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXInitVertexArrayState( __GLXcontext * gc )
121fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
122fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
123fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays;
124fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
125fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned array_count;
12683a5c2bf63ef285dea096612f4d84236e9c8d543Brian Paul    int texture_units = 1, vertex_program_attribs = 0;
12783a5c2bf63ef285dea096612f4d84236e9c8d543Brian Paul    unsigned i, j;
128fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
129fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean got_fog = GL_FALSE;
130fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean got_secondary_color = GL_FALSE;
131fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
132fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
133b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    arrays = calloc( 1, sizeof( struct array_state_vector ) );
134fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    state->array_state = arrays;
135fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
136fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
137fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->new_DrawArrays_possible = GL_FALSE;
138fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->DrawArrays = NULL;
139fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
140fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit = 0;
141fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
142fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
143fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Determine how many arrays are actually needed.  Only arrays that
144fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * are supported by the server are create.  For example, if the server
145fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * supports only 2 texture units, then only 2 texture coordinate arrays
146fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * are created.
147fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
148fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
149fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
150fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * GL_EDGE_FLAG_ARRAY are supported.
151fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
152979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick
153fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    array_count = 5;
154fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
155fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_EXT_fog_coord_bit )
156fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 || (gc->server_major > 1) || (gc->server_minor >= 4) ) {
157fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	got_fog = GL_TRUE;
158fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	array_count++;
159fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
160fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
161fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_EXT_secondary_color_bit )
162fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 || (gc->server_major > 1) || (gc->server_minor >= 4) ) {
163fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	got_secondary_color = GL_TRUE;
164fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	array_count++;
165fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
166fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
167fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_ARB_multitexture_bit )
168fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 || (gc->server_major > 1) || (gc->server_minor >= 3) ) {
16903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	__indirect_glGetIntegerv( GL_MAX_TEXTURE_UNITS, & texture_units );
170fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
171fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
17240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_ARB_vertex_program_bit ) ) {
17303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	__indirect_glGetProgramivARB( GL_VERTEX_PROGRAM_ARB,
17403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick				      GL_MAX_PROGRAM_ATTRIBS_ARB,
17503dc437363429d275b7f8cae74201a8e7993a52bIan Romanick				      & vertex_program_attribs );
17640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
17740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
178fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->num_texture_units = texture_units;
17940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    arrays->num_vertex_program_attribs = vertex_program_attribs;
18040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    array_count += texture_units + vertex_program_attribs;
181fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->num_arrays = array_count;
182b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    arrays->arrays = calloc( array_count, sizeof( struct array_state ) );
183fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
184fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].data_type = GL_FLOAT;
185fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].count = 3;
186fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].key = GL_NORMAL_ARRAY;
18740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    arrays->arrays[0].normalized = GL_TRUE;
188fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
189fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
190fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].data_type = GL_FLOAT;
191fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].count = 4;
192fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].key = GL_COLOR_ARRAY;
19340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    arrays->arrays[1].normalized = GL_TRUE;
194fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
195fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
196fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].data_type = GL_FLOAT;
197fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].count = 1;
198fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].key = GL_INDEX_ARRAY;
199fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
200fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
201fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
202fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].count = 1;
203fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
204fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
205fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
206fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < texture_units ; i++ ) {
207fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].data_type = GL_FLOAT;
208fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].count = 4;
209fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
21040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
211fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
212fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].index = i;
213fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
214fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0;
215fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
216fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
217fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    i = 4 + texture_units;
218fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
219fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( got_fog ) {
220fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].data_type = GL_FLOAT;
221fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].count = 1;
222fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
223fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
224fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	i++;
225fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
226fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
227fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( got_secondary_color ) {
228fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].data_type = GL_FLOAT;
229fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].count = 3;
230fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
231fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
23240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[i].normalized = GL_TRUE;
233fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	i++;
234fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
235fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
236fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
23740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    for ( j = 0 ; j < vertex_program_attribs ; j++ ) {
23840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	const unsigned idx = (vertex_program_attribs - (j + 1));
23940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
24040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
24140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].data_type = GL_FLOAT;
24240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].count = 4;
24340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
24440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
24540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].old_DrawArrays_possible = 0;
24640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].index = idx;
24740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
24840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].header[1] = idx;
24940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
25040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
25140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    i += vertex_program_attribs;
25240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
25340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
254fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Vertex array *must* be last becuase of the way that
255fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * emit_DrawArrays_none works.
256fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
257fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
258fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].data_type = GL_FLOAT;
259fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].count = 4;
260fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].key = GL_VERTEX_ARRAY;
261fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
262fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
263b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    assert( (i + 1) == arrays->num_arrays );
264fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
265fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack_index = 0;
266fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack = malloc( sizeof( struct array_stack_state )
267fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    * arrays->num_arrays );
268fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
269fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
270fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
271fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
272fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Calculate the size of a single vertex for the "none" protocol.  This is
273fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * essentially the size of all the immediate-mode commands required to
274fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * implement the enabled vertex arrays.
275fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
276fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic size_t
277fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickcalculate_single_vertex_size_none( const struct array_state_vector * arrays )
278fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
279fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size = 0;
280fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned   i;
281fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
282fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
283fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
284fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    	if ( arrays->arrays[i].enabled ) {
28540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    single_vertex_size += ((uint16_t *)arrays->arrays[i].header)[0];
286fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
287fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
288fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
289fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return single_vertex_size;
290fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
291fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
292fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
293fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
294fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit a single element using non-DrawArrays protocol.
295fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
296fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLubyte *
297fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_element_none( GLubyte * dst,
298fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		   const struct array_state_vector * arrays,
299fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		   unsigned index )
300fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
301fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
302fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
303fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
304fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
305fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
306fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    const size_t offset = index * arrays->arrays[i].true_stride;
307fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
30840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    /* The generic attributes can have more data than is in the
30940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * elements.  This is because a vertex array can be a 2 element,
31040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * normalized, unsigned short, but the "closest" immediate mode
31140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * protocol is for a 4Nus.  Since the sizes are small, the
31240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * performance impact on modern processors should be negligible.
31340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     */
31440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    (void) memset( dst, 0,
31540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick			   ((uint16_t *)arrays->arrays[i].header)[0] );
31640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
317fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) memcpy( dst, arrays->arrays[i].header,
318fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   arrays->arrays[i].header_size );
319fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
320fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    dst += arrays->arrays[i].header_size;
321fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
322fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) memcpy( dst, ((GLubyte *) arrays->arrays[i].data) + offset,
323fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   arrays->arrays[i].element_size );
324fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
325fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    dst += __GLX_PAD( arrays->arrays[i].element_size );
326fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
327fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
328fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
329fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return dst;
330fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
331fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
332fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
333fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
334fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit a single element using "old" DrawArrays protocol from
335fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * EXT_vertex_arrays / OpenGL 1.1.
336fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
337fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLubyte *
338fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_element_old( GLubyte * dst,
339fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		  const struct array_state_vector * arrays,
340fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		  unsigned index )
341fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
342fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
343fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
344fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
345fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
346fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
347fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    const size_t offset = index * arrays->arrays[i].true_stride;
348fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
349fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) memcpy( dst, ((GLubyte *) arrays->arrays[i].data) + offset,
350fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   arrays->arrays[i].element_size );
351fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
352fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    dst += __GLX_PAD( arrays->arrays[i].element_size );
353fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
354fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
355fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
356fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return dst;
357fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
358fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
359fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
360fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstruct array_state *
361fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickget_array_entry( const struct array_state_vector * arrays,
362fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		 GLenum key, unsigned index )
363fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
364fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
365fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
366fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
367fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (arrays->arrays[i].key == key)
368fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	     && (arrays->arrays[i].index == index) ) {
369fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return & arrays->arrays[i];
370fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
371fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
372fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
373fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return NULL;
374fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
375fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
376fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
377fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLboolean
378fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickallocate_array_info_cache( struct array_state_vector * arrays,
379fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   size_t required_size )
380fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
381979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick#define MAX_HEADER_SIZE 20
382fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( arrays->array_info_cache_buffer_size < required_size ) {
3832ae5645115124ecc97bf4a0ba9f5542cf2409845Ian Romanick	GLubyte * temp = realloc( arrays->array_info_cache_base,
3842ae5645115124ecc97bf4a0ba9f5542cf2409845Ian Romanick				  required_size + MAX_HEADER_SIZE );
385fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
386fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( temp == NULL ) {
387fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return GL_FALSE;
388fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
389fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
3902ae5645115124ecc97bf4a0ba9f5542cf2409845Ian Romanick	arrays->array_info_cache_base = temp;
391979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	arrays->array_info_cache = temp + MAX_HEADER_SIZE;
392fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_buffer_size = required_size;
393fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
394fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
395fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_size = required_size;
396fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return GL_TRUE;
397fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
398fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
399fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
400fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
401fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
402fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
403fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickfill_array_info_cache( struct array_state_vector * arrays )
404fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
405fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean old_DrawArrays_possible;
406fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
407fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
408fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
409fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Determine how many arrays are enabled.
410fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
411fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
412b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    arrays->enabled_client_array_count = 0;
413fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    old_DrawArrays_possible = arrays->old_DrawArrays_possible;
414fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
415fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
416b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick	    arrays->enabled_client_array_count++;
417fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
418fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
419fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
420fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
421fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( arrays->new_DrawArrays_possible ) {
422fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( ! arrays->new_DrawArrays_possible );
423fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
424fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else if ( old_DrawArrays_possible ) {
425b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick	const size_t required_size = arrays->enabled_client_array_count * 12;
426fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	uint32_t * info;
427fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
428fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
429fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! allocate_array_info_cache( arrays, required_size ) ) {
430fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
431fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
432fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
433fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
434fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	info = (uint32_t *) arrays->array_info_cache;
435fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
436fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( arrays->arrays[i].enabled ) {
437fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		*(info++) = arrays->arrays[i].data_type;
438fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		*(info++) = arrays->arrays[i].count;
439fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		*(info++) = arrays->arrays[i].key;
440fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
441fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
442fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
443fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawArrays = emit_DrawArrays_old;
444fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements = emit_DrawElements_old;
445fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
446fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
447fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawArrays = emit_DrawArrays_none;
448fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements = emit_DrawElements_none;
449fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
450b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick
451b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    arrays->array_info_cache_valid = GL_TRUE;
452fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
453fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
454fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
455fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
456fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit a \c glDrawArrays command using the "none" protocol.  That is,
457fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * emit immediate-mode commands that are equivalent to the requiested
458fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c glDrawArrays command.  This is used with servers that don't support
459fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
460fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * vertex state is enabled that is not compatible with that protocol.
461fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
462fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
463fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawArrays_none( GLenum mode, GLint first, GLsizei count )
464fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
465fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
466fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
467fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
468fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
469fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
470fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
471fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
472fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
473fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
474fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t end_cmd[2]   = { 4, X_GLrop_End };
475fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
476fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
477fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = calculate_single_vertex_size_none( arrays );
478fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
479fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = gc->pc;
480fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
481fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, begin_cmd, 4 );
482fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    *(int *)(pc +  4) = mode;
483fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
484fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 8;
485fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
486fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < count ; i++ ) {
487fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (pc + single_vertex_size) >= gc->bufEnd ) {
4885c82549d9e3151aae4f66f2a26b6055475f6f538Brian	    pc = __glXFlushRenderBuffer(gc, pc);
489fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
490fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
491fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = emit_element_none( pc, arrays, first + i );
492fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
493fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
494fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (pc + 4) >= gc->bufEnd ) {
4955c82549d9e3151aae4f66f2a26b6055475f6f538Brian	pc = __glXFlushRenderBuffer(gc, pc);
496fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
497fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
498fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, end_cmd, 4 );
499fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 4;
500fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
501fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    gc->pc = pc;
502fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( gc->pc > gc->limit ) {
503fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) __glXFlushRenderBuffer(gc, gc->pc);
504fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
505fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
506fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
507fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
508fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
509fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
510fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * protocol.
511fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
512fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param gc                    GLX context.
513fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param arrays                Array state.
514fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param elements_per_request  Location to store the number of elements that
515fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              can fit in a single Render / RenderLarge
516fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              command.
517fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param total_request         Total number of requests for a RenderLarge
518fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              command.  If a Render command is used, this
519fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              will be zero.
520fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param mode                  Drawing mode.
521fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param count                 Number of vertices.
522fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
523fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \returns
524fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * A pointer to the buffer for array data.
525fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
526fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLubyte *
527fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawArrays_header_old( __GLXcontext * gc,
528fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    struct array_state_vector * arrays,
529fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    size_t * elements_per_request,
530d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald			    unsigned int * total_requests,
531fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    GLenum mode, GLsizei count )
532fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
533fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t command_size;
534fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
535fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const unsigned header_size = 16;
536fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
537fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
538fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
539fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
540fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Determine the size of the whole command.  This includes the header,
541fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * the ARRAY_INFO data and the array data.  Once this size is calculated,
542fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * it will be known whether a Render or RenderLarge command is needed.
543fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
544fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
545fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = 0;
546fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
547fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
548fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    single_vertex_size += __GLX_PAD( arrays->arrays[i].element_size );
549fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
550fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
551fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
552fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    command_size = arrays->array_info_cache_size + header_size
553fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      + (single_vertex_size * count);
554fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
555fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
556fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Write the header for either a Render command or a RenderLarge
557fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * command.  After the header is written, write the ARRAY_INFO data.
558fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
559fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
560fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( command_size > gc->maxSmallRenderCommandSize ) {
561fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	/* maxSize is the maximum amount of data can be stuffed into a single
562fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * packet.  sz_xGLXRenderReq is added because bufSize is the maximum
563fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * packet size minus sz_xGLXRenderReq.
564fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 */
565fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
566fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	  - sz_xGLXRenderLargeReq;
567fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	unsigned vertex_requests;
568fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
569fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
570fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	/* Calculate the number of data packets that will be required to send
571fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * the whole command.  To do this, the number of verticies that
572fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * will fit in a single buffer must be calculated.
573fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 *
574fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * The important value here is elements_per_request.  This is the
575fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * number of complete array elements that will fit in a single
576fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * buffer.  There may be some wasted space at the end of the buffer,
577fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * but splitting elements across buffer boundries would be painful.
578fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 */
579fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
580fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	elements_per_request[0] = maxSize / single_vertex_size;
581fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
582fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	vertex_requests = (count + elements_per_request[0] - 1)
583fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	  / elements_per_request[0];
584fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
585fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*total_requests = vertex_requests + 1;
586fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
587fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
588fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXFlushRenderBuffer(gc, gc->pc);
589fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
590fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	command_size += 4;
591fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
592979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
593fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  0) = command_size;
594fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  4) = X_GLrop_DrawArrays;
595fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  8) = count;
596b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick	*(uint32_t *)(pc + 12) = arrays->enabled_client_array_count;
597fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc + 16) = mode;
598fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
599fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSendLargeChunk( gc, 1, *total_requests, pc,
600fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			     header_size + 4 + arrays->array_info_cache_size );
601fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
602fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = gc->pc;
603fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
604fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
605fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (gc->pc + command_size) >= gc->bufEnd ) {
606fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) __glXFlushRenderBuffer(gc, gc->pc);
607fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
608fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
609fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = gc->pc;
610fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint16_t *)(pc +  0) = command_size;
611fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint16_t *)(pc +  2) = X_GLrop_DrawArrays;
612fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  4) = count;
613b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick	*(uint32_t *)(pc +  8) = arrays->enabled_client_array_count;
614fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc + 12) = mode;
615fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
616fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc += header_size;
617fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
618fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) memcpy( pc, arrays->array_info_cache,
619fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		       arrays->array_info_cache_size );
620fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc += arrays->array_info_cache_size;
621b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick
622fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*elements_per_request = count;
623fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*total_requests = 0;
624fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
625fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
626fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
627fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return pc;
628fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
629fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
630fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
631fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
632fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
633fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
634fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawArrays_old( GLenum mode, GLint first, GLsizei count )
635fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
636fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
637fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
638fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
639fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
640fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
641fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
642fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t elements_per_request;
643d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald    unsigned total_requests = 0;
644fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
645fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t total_sent = 0;
646fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
647fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
648fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
649fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				     & total_requests, mode, count);
650fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
651fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
652fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Write the arrays.
653fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
654fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
655fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( total_requests == 0 ) {
656fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( elements_per_request >= count );
657fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
658fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < count ; i++ ) {
659fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = emit_element_old( pc, arrays, i + first );
660fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
661fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
662fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( pc <= gc->bufEnd );
663fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
664fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = pc;
665fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( gc->pc > gc->limit ) {
666fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) __glXFlushRenderBuffer(gc, gc->pc);
667fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
668fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
669fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
670fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	unsigned req;
671fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
672fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
673fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( req = 2 ; req <= total_requests ; req++ ) {
674fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( count < elements_per_request ) {
675fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		elements_per_request = count;
676fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
677fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
678fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = gc->pc;
679fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
680fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, i + first );
681fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
682fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
683fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    first += elements_per_request;
684fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
685fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    total_sent += (size_t) (pc - gc->pc);
686fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSendLargeChunk( gc, req, total_requests, gc->pc,
687fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 pc - gc->pc );
688fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
689fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    count -= elements_per_request;
690fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
691fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
692fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
693fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
694fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
695fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
696fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
697fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			const GLvoid *indices )
698fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
699fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
700fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
701fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
702fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
703fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
704fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t end_cmd[2]   = { 4, X_GLrop_End };
705fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
706fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
707fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
708fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
709fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
710fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
711fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = calculate_single_vertex_size_none( arrays );
712fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
713fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
714fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {
715fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
716fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
717fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
718fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = gc->pc;
719fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
720fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, begin_cmd, 4 );
721fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    *(int *)(pc +  4) = mode;
722fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
723fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 8;
724fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
725fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < count ; i++ ) {
72603dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	unsigned  index = 0;
727fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
728fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (pc + single_vertex_size) >= gc->bufEnd ) {
7295c82549d9e3151aae4f66f2a26b6055475f6f538Brian	    pc = __glXFlushRenderBuffer(gc, pc);
730fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
731fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
732fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch( type ) {
733fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_INT:
734fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    index = (unsigned) (((GLuint *) indices)[i]);
735fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
736fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_SHORT:
737fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    index = (unsigned) (((GLushort *) indices)[i]);
738fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
739fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_BYTE:
740fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    index = (unsigned) (((GLubyte *) indices)[i]);
741fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
742fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
743fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = emit_element_none( pc, arrays, index );
744fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
745fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
746fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (pc + 4) >= gc->bufEnd ) {
7475c82549d9e3151aae4f66f2a26b6055475f6f538Brian	pc = __glXFlushRenderBuffer(gc, pc);
748fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
749fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
750fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, end_cmd, 4 );
751fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 4;
752fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
753fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    gc->pc = pc;
754fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( gc->pc > gc->limit ) {
755fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) __glXFlushRenderBuffer(gc, gc->pc);
756fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
757fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
758fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
759fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
760fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
761fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
762fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
763fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
764fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		       const GLvoid *indices )
765fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
766fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
767fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
768fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
769fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
770fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
771fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
772fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t elements_per_request;
773d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald    unsigned total_requests = 0;
774fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
775fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned req;
776d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald    unsigned req_element=0;
777fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
778fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
779fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
780fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				     & total_requests, mode, count);
781fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
782fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
783fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Write the arrays.
784fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
785fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
786fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    req = 2;
787fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    while ( count > 0 ) {
788fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( count < elements_per_request ) {
789fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    elements_per_request = count;
790fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
791fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
792fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch( type ) {
793979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	case GL_UNSIGNED_INT: {
794d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald	    const GLuint   * ui_ptr = (const GLuint   *) indices + req_element;
795979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick
796fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
797fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		const GLint index = (GLint) *(ui_ptr++);
798fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, index );
799fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
800fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
801979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	}
802979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	case GL_UNSIGNED_SHORT: {
803d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald	    const GLushort * us_ptr = (const GLushort *) indices + req_element;
804979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick
805fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
806fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		const GLint index = (GLint) *(us_ptr++);
807fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, index );
808fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
809fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
810979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	}
811979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	case GL_UNSIGNED_BYTE: {
812d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald	    const GLubyte  * ub_ptr = (const GLubyte  *) indices + req_element;
813979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick
814fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
815fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		const GLint index = (GLint) *(ub_ptr++);
816fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, index );
817fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
818fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
819fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
820979f35fb78f39cec5de53795ce91f674bfb9df52Ian Romanick	}
821fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
822fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( total_requests != 0 ) {
823fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSendLargeChunk( gc, req, total_requests, gc->pc,
824fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 pc - gc->pc );
825fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = gc->pc;
826fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    req++;
827fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
828fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
829fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	count -= elements_per_request;
830d62be3d4cac4228a74fd93a5588717b8b8468cc6Colin McDonald	req_element += elements_per_request;
831fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
832fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
833fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
834fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( (total_requests == 0) || ((req - 1) == total_requests) );
835fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
836fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( total_requests == 0 ) {
837fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( pc <= gc->bufEnd );
838fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
839fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = pc;
840fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( gc->pc > gc->limit ) {
841fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) __glXFlushRenderBuffer(gc, gc->pc);
842fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
843fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
844fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
845fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
846fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
847fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
848fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
849fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * If it is not valid, then an error code is set in the GLX context.
850fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
851fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \returns
852fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
853fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
854fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLboolean
855fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvalidate_mode(__GLXcontext *gc, GLenum mode)
856fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
857fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch(mode) {
858fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_POINTS:
859fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_LINE_STRIP:
860fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_LINE_LOOP:
861fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_LINES:
862fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_TRIANGLE_STRIP:
863fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_TRIANGLE_FAN:
864fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_TRIANGLES:
865fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_QUAD_STRIP:
866fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_QUADS:
867fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_POLYGON:
868fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	break;
869fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      default:
870fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
871fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return GL_FALSE;
872fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
873fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
874fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return GL_TRUE;
875fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
876fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
877fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
878fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
879fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
880fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
881fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * being set.  A value of zero will not result in an error being set, but
882fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * will result in \c GL_FALSE being returned.
883fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
884fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \returns
885fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
886fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
887fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLboolean
888fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvalidate_count(__GLXcontext *gc, GLsizei count)
889fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
890fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (count < 0) {
891fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSetError(gc, GL_INVALID_VALUE);
892fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
893fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
894fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (count > 0);
895fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
896fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
897fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
89803dc437363429d275b7f8cae74201a8e7993a52bIan Romanick/**
89903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * Validate that the \c type parameter to \c glDrawElements, et. al. is
90003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * valid.  Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
90103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * \c GL_UNSIGNED_INT are valid.
90203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick *
90303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * \returns
90403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
90503dc437363429d275b7f8cae74201a8e7993a52bIan Romanick */
90603dc437363429d275b7f8cae74201a8e7993a52bIan Romanickstatic GLboolean validate_type(__GLXcontext *gc, GLenum type)
90703dc437363429d275b7f8cae74201a8e7993a52bIan Romanick{
90803dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    switch( type ) {
90903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    case GL_UNSIGNED_INT:
91003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    case GL_UNSIGNED_SHORT:
91103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    case GL_UNSIGNED_BYTE:
91203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	return GL_TRUE;
91303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick     default:
91403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	__glXSetError(gc, GL_INVALID_ENUM);
91503dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	return GL_FALSE;
91603dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    }
91703dc437363429d275b7f8cae74201a8e7993a52bIan Romanick}
91803dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
91903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
920fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
921fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
922fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
923fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
924fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
925fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
926fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
927fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
928fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( validate_mode(gc, mode) && validate_count(gc, count) ) {
929fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
930fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
931fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
932fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
933fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawArrays(mode, first, count);
934fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
935fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
936fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
937fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
938fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glArrayElement(GLint index)
939fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
940fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
941fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
942fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
943fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
944fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
945fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
946fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
947fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
948fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = calculate_single_vertex_size_none( arrays );
949fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
950fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {
951fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
952fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
953fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
954fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    gc->pc = emit_element_none( gc->pc, arrays, index );
955fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
956fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( gc->pc > gc->limit ) {
957fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) __glXFlushRenderBuffer(gc, gc->pc);
958fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
959fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
960fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
961fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
962fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
963fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		    const GLvoid *indices)
964fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
965fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
966fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
967fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
968fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
969fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
970fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
97103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    if ( validate_mode(gc, mode) && validate_count(gc, count)
97203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	 && validate_type(gc, type) ) {
973fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
974fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
975fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
976fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
977fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements(mode, count, type, indices);
978fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
979fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
980fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
981fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
982fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
983fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				    GLsizei count, GLenum type,
984fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				    const GLvoid *indices)
985fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
986fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
987fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
988fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
989fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
990fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
991fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
99203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    if ( validate_mode(gc, mode) && validate_count(gc, count)
99303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	 && validate_type(gc, type) ) {
994fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if (end < start) {
995fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSetError(gc, GL_INVALID_VALUE);
996fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
997fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
998fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
999fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1000fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1001fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1002fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1003fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements(mode, count, type, indices);
1004fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1005fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1006fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1007fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1008fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count,
1009fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		       GLsizei primcount)
1010fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1011fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1012fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1013fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1014fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1015fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei  i;
1016fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1017fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1018fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( validate_mode(gc, mode) ) {
1019fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1020fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1021fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1022fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1023fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < primcount ; i++ ) {
1024fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( validate_count( gc, count[i] ) ) {
1025fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		arrays->DrawArrays(mode, first[i], count[i]);
1026fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1027fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1028fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1029fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1030fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1031fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1032fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count,
1033fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			 GLenum type, const GLvoid ** indices,
1034fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			 GLsizei primcount)
1035fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1036fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1037fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1038fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1039fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1040fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei  i;
1041fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1042fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
104303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    if ( validate_mode(gc, mode) && validate_type(gc, type) ) {
1044fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1045fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1046fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1047fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1048fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < primcount ; i++ ) {
1049fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( validate_count( gc, count[i] ) ) {
1050fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		arrays->DrawElements(mode, count[i], type, indices[i]);
1051fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1052fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1053fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1054fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1055fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1056fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1057b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1058fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    do { \
1059fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->data = PTR; \
1060fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->data_type = TYPE; \
1061fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->user_stride = STRIDE; \
1062fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->count = COUNT; \
1063b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick	(a)->normalized = NORMALIZED; \
1064fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	\
1065fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1066fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->true_stride = (STRIDE == 0) \
1067fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	  ? (a)->element_size : STRIDE; \
1068fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	\
1069fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->header_size = HDR_SIZE; \
1070fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1071fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	((uint16_t *) (a)->header)[1] = OPCODE; \
1072fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    } while(0)
1073fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1074fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1075fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glVertexPointer( GLint size, GLenum type, GLsizei stride,
1076fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 const GLvoid * pointer )
1077fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1078fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t short_ops[5] = {
1079fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1080fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1081fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t int_ops[5] = {
1082fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1083fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1084fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t float_ops[5] = {
1085fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1086fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1087fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t double_ops[5] = {
1088fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1089fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1090fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1091fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1092fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1093fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1094fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1095fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1096fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1097fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size < 2 || size > 4 || stride < 0) {
1098fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1099fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1100fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1101fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1102fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1103fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:	opcode = short_ops[size]; break;
1104fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:	opcode = int_ops[size]; break;
1105fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:	opcode = float_ops[size]; break;
1106fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:	opcode = double_ops[size]; break;
1107fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1108fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1109fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1110fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1111fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1112fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_VERTEX_ARRAY, 0 );
1113fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1114b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, GL_FALSE, 4,
1115b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
1116fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1117fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1118fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1119fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1120fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1121fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1122fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1123fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glNormalPointer( GLenum type, GLsizei stride,
1124fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 const GLvoid * pointer )
1125fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1126fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1127fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1128fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1129fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1130fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1131fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1132fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1133fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1134fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1135fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1136fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1137b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick
1138fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1139fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_BYTE:	opcode = X_GLrop_Normal3bv; break;
1140fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:	opcode = X_GLrop_Normal3sv; break;
1141fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:	opcode = X_GLrop_Normal3iv; break;
1142fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:	opcode = X_GLrop_Normal3fv; break;
1143fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:	opcode = X_GLrop_Normal3dv; break;
1144fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1145fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1146fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1147fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1148fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1149fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_NORMAL_ARRAY, 0 );
1150fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1151b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 3, GL_TRUE, 4,
1152b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
1153fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1154fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1155fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1156fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1157fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1158fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1159fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1160fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glColorPointer( GLint size, GLenum type, GLsizei stride,
1161fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1162fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1163fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t byte_ops[5] = {
1164fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1165fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1166fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t ubyte_ops[5] = {
1167fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1168fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1169fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t short_ops[5] = {
1170fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1171fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1172fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t ushort_ops[5] = {
1173fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1174fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1175fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t int_ops[5] = {
1176fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1177fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1178fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t uint_ops[5] = {
1179fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1180fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1181fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t float_ops[5] = {
1182fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1183fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1184fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t double_ops[5] = {
1185fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1186fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1187fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1188fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1189fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1190fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1191fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1192fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1193fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1194fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size < 3 || size > 4 || stride < 0) {
1195fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1196fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1197fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1198fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1199fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1200fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_BYTE:		opcode = byte_ops[size]; break;
1201fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_BYTE:	opcode = ubyte_ops[size]; break;
1202fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:		opcode = short_ops[size]; break;
1203fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_SHORT:	opcode = ushort_ops[size]; break;
1204fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:		opcode = int_ops[size]; break;
1205fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_INT:	opcode = uint_ops[size]; break;
1206fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = float_ops[size]; break;
1207fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = double_ops[size]; break;
1208fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1209fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1210fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1211fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1212fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1213fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_COLOR_ARRAY, 0 );
1214fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1215b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, GL_TRUE, 4,
1216b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
1217fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1218fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1219fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1220fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1221fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1222fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1223fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1224fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glIndexPointer( GLenum type, GLsizei stride,
1225fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1226fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1227fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1228fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1229fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1230fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1231fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1232fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1233fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1234fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1235fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1236fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1237fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1238fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1239fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1240fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_BYTE:	opcode = X_GLrop_Indexubv; break;
1241fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:		opcode = X_GLrop_Indexsv; break;
1242fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:		opcode = X_GLrop_Indexiv; break;
1243fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = X_GLrop_Indexfv; break;
1244fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = X_GLrop_Indexdv; break;
1245fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1246fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1247fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1248fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1249fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1250fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_INDEX_ARRAY, 0 );
1251fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1252b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 1, GL_FALSE, 4,
1253b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
1254fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1255fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1256fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1257fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1258fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1259fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1260fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1261fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glEdgeFlagPointer( GLsizei stride, const GLvoid * pointer )
1262fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1263fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1264fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1265fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1266fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1267fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1268fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1269fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1270fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1271fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1272fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1273fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1274fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1275fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_EDGE_FLAG_ARRAY, 0 );
1276fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1277b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1278b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    4, X_GLrop_EdgeFlagv );
1279fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1280fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1281fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1282fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1283fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1284fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1285fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1286fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glTexCoordPointer( GLint size, GLenum type, GLsizei stride,
1287fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				   const GLvoid * pointer )
1288fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1289fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t short_ops[5] = {
1290fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv, X_GLrop_TexCoord4sv
1291fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1292fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t int_ops[5] = {
1293fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv, X_GLrop_TexCoord4iv
1294fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1295fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t float_ops[5] = {
1296fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, X_GLrop_TexCoord4fv
1297fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1298fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t double_ops[5] = {
1299fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv, X_GLrop_TexCoord4dv
1300fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1301fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1302fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mshort_ops[5] = {
1303fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB, X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
1304fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1305fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mint_ops[5] = {
1306fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB, X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
1307fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1308fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mfloat_ops[5] = {
1309fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB, X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
1310fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1311fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mdouble_ops[5] = {
1312fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB, X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
1313fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1314fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1315fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1316fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1317fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1318fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1319fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1320fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned header_size;
1321fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned index;
1322fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1323fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1324fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size < 1 || size > 4 || stride < 0) {
1325fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1326fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1327fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1328fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1329fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    index = arrays->active_texture_unit;
1330fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( index == 0 ) {
1331fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch ( type ) {
1332fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_SHORT:		opcode = short_ops[size]; break;
1333fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_INT:		opcode = int_ops[size]; break;
1334fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_FLOAT:		opcode = float_ops[size]; break;
1335fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_DOUBLE:		opcode = double_ops[size]; break;
1336fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	default:
1337fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
1338fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
1339fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1340fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1341fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	header_size = 4;
1342fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1343fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
1344fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch ( type ) {
1345fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_SHORT:		opcode = mshort_ops[size]; break;
1346fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_INT:		opcode = mint_ops[size]; break;
1347fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_FLOAT:		opcode = mfloat_ops[size]; break;
1348fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_DOUBLE:		opcode = mdouble_ops[size]; break;
1349fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	default:
1350fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
1351fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
1352fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1353fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1354fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	header_size = 8;
1355fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1356fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1357fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_TEXTURE_COORD_ARRAY, index );
1358fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1359b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, GL_FALSE,
1360b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    header_size, opcode );
1361fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1362fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1363fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1364fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1365fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1366fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1367fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1368fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glSecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride,
1369fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1370fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1371fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1372fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1373fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1374fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1375fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1376fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1377fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1378fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size != 3 || stride < 0) {
1379fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1380fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1381fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1382fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1383fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1384fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_BYTE:		opcode = 4126; break;
1385fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_BYTE:	opcode = 4131; break;
1386fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:		opcode = 4127; break;
1387fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_SHORT:	opcode = 4132; break;
1388fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:		opcode = 4128; break;
1389fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_INT:	opcode = 4133; break;
1390fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = 4129; break;
1391fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = 4130; break;
1392fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1393fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1394fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1395fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1396fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1397fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_SECONDARY_COLOR_ARRAY, 0 );
1398fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a == NULL ) {
1399fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_OPERATION);
1400fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1401fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1402fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1403b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, GL_TRUE, 4,
1404b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
1405fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1406fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1407fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1408fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1409fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1410fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1411fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1412fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glFogCoordPointerEXT( GLenum type, GLsizei stride,
1413fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1414fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1415fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1416fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1417fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1418fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1419fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1420fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1421fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1422fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1423fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1424fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1425fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1426b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick
1427fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1428fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = 4124; break;
1429fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = 4125; break;
1430fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1431fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1432fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1433fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1434fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1435fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_FOG_COORD_ARRAY, 0 );
1436fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a == NULL ) {
1437fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_OPERATION);
1438fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1439fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1440fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1441b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 1, GL_FALSE, 4,
1442b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
1443fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1444fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1445fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1446fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1447fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1448fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1449fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
145040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickvoid __indirect_glVertexAttribPointerARB(GLuint index, GLint size,
145140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 GLenum type, GLboolean normalized,
145240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 GLsizei stride,
145340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 const GLvoid * pointer)
145440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick{
145540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    static const uint16_t short_ops[5]  = { 0, 4189, 4190, 4191, 4192 };
145640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    static const uint16_t float_ops[5]  = { 0, 4193, 4194, 4195, 4196 };
145740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    static const uint16_t double_ops[5] = { 0, 4197, 4198, 4199, 4200 };
145840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
145940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    uint16_t opcode;
146040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
146140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
146240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    struct array_state_vector * arrays = state->array_state;
146340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    struct array_state * a;
146440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    unsigned true_immediate_count;
146540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    unsigned true_immediate_size;
146640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
146740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
146840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( (size < 1) || (size > 4) || (stride < 0)
146940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	 || (index > arrays->num_vertex_program_attribs) ){
147040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
147140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        return;
147240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
147340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
147440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
147540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	switch( type ) {
147640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_BYTE:           opcode = X_GLrop_VertexAttrib4NbvARB;  break;
147740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_BYTE:  opcode = X_GLrop_VertexAttrib4NubvARB; break;
147840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_SHORT:          opcode = X_GLrop_VertexAttrib4NsvARB;  break;
147940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_SHORT: opcode = X_GLrop_VertexAttrib4NusvARB; break;
148040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_INT:            opcode = X_GLrop_VertexAttrib4NivARB;  break;
148140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_INT:   opcode = X_GLrop_VertexAttrib4NuivARB; break;
148240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	default:
148340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
148440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    return;
148540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	}
148640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
148740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	true_immediate_count = 4;
148840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
148940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    else {
149003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	true_immediate_count = size;
149103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
149240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	switch( type ) {
149340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_BYTE:
149440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4bvARB;
149540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
149640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
149740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_BYTE:
149840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4ubvARB;
149940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
150040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
150140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_SHORT:
150240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = short_ops[size];
150340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
150440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_SHORT:
150540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4usvARB;
150640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
150740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
150840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_INT:
150940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick            opcode = X_GLrop_VertexAttrib4ivARB;
151040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
151140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
151240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_INT:
151340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4uivARB;
151440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
151540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
151640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_FLOAT:
151740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = float_ops[size];
151840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
151940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_DOUBLE:
152040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = double_ops[size];
152140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
152240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	default:
152340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
152440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    return;
152540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	}
152640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
152740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
152840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    a = get_array_entry( arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index );
152940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( a == NULL ) {
153040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        __glXSetError(gc, GL_INVALID_OPERATION);
153140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        return;
153240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
153340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
1534b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, normalized, 8,
1535b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick			    opcode );
153640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
153740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    true_immediate_size = __glXTypeSize(type) * true_immediate_count;
153840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size
153940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					      + true_immediate_size);
154040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
154140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( a->enabled ) {
154240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
154340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
154440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick}
154540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
154640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
154740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick/**
154840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * I don't have 100% confidence that this is correct.  The different rules
154940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * about whether or not generic vertex attributes alias "classic" vertex
155040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
155140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * ARB_vertex_shader, and NV_vertex_program are a bit confusing.  My
155240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * feeling is that the client-side doesn't have to worry about it.  The
155340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * client just sends all the data to the server and lets the server deal
155440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * with it.
155540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick */
155640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickvoid __indirect_glVertexAttribPointerNV( GLuint index, GLint size,
155740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 GLenum type, GLsizei stride,
155840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 const GLvoid * pointer)
155940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick{
156040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
156140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    GLboolean normalized = GL_FALSE;
156240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
156340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
156440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    switch( type ) {
156540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_UNSIGNED_BYTE:
156640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	if ( size != 4 ) {
156740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    __glXSetError(gc, GL_INVALID_VALUE);
156840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    return;
156940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	}
157040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	normalized = GL_TRUE;
157140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
157240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_SHORT:
157340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_FLOAT:
157440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_DOUBLE:
157540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	__indirect_glVertexAttribPointerARB(index, size, type,
157640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					    normalized,
157740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					    stride, pointer);
157840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	return;
157940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    default:
158040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	__glXSetError(gc, GL_INVALID_ENUM);
158140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	return;
158240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
158340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick}
158440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
158540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
1586fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glClientActiveTextureARB(GLenum texture)
1587fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1588fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext * const gc = __glXGetCurrentContext();
1589fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * const state = (__GLXattribute *)(gc->client_state_private);
1590fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * const arrays = state->array_state;
1591fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLint unit = (GLint) texture - GL_TEXTURE0;
1592fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1593fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1594791e7b385adbe865d0fa7b0aff3672095fdc0c7bBrian Paul    if ( (unit < 0) || (unit >= arrays->num_texture_units) ) {
1595fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSetError(gc, GL_INVALID_ENUM);
1596fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	return;
1597fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1598fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1599fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit = unit;
1600fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1601fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1602fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1603fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1604fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1605fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1606fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXSetArrayEnable( __GLXattribute * state,
1607fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLboolean enable )
1608fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1609fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1610fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1611fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1612fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1613fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( key == GL_TEXTURE_COORD_ARRAY ) {
1614fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	index = arrays->active_texture_unit;
1615fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1616fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1617fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, key, index );
1618fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1619fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (a != NULL) && (a->enabled != enable) ) {
1620fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	a->enabled = enable;
1621fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1622fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1623fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1624fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1625fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1626fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1627fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1628fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
1629fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXArrayDisableAll( __GLXattribute * state )
1630fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1631fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1632fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
1633fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1634fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1635fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1636fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].enabled = GL_FALSE;
1637fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1638fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1639fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_valid = GL_FALSE;
1640fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1641fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1642fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1643fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1644fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1645fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1646fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayEnable( const __GLXattribute * const state,
1647fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1648fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1649fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1650fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1651fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1652fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1653fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1654fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->enabled;
1655fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1656fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1657fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1658fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1659fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1660fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1661fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1662fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1663fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1664fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayType( const __GLXattribute * const state,
1665fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1666fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1667fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1668fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1669fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1670fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1671fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
16726efdf648f51fd1ae27043b2c59e9965467fb1ddbBruce Merry	*dest = (GLintptr) a->data_type;
1673fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1674fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1675fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1676fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1677fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1678fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1679fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1680fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1681fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1682fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArraySize( const __GLXattribute * const state,
1683fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1684fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1685fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1686fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1687fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1688fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1689fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1690fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->count;
1691fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1692fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1693fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1694fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1695fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1696fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1697fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1698fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1699fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1700fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayStride( const __GLXattribute * const state,
1701fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1702fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1703fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1704fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1705fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1706fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1707fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1708fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->user_stride;
1709fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1710fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1711fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1712fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1713fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1714fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1715fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1716fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1717fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1718fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayPointer( const __GLXattribute * const state,
1719fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		      GLenum key, unsigned index, void ** dest )
1720fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1721fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1722fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1723fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1724fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1725fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1726fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
172740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	*dest = (void *) (a->data);
172840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
172940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
173040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    return (a != NULL);
173140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick}
173240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
173340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
173440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick/**
173540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick */
173640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan RomanickGLboolean
173740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick__glXGetArrayNormalized( const __GLXattribute * const state,
173840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick			 GLenum key, unsigned index, GLintptr * dest )
173940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick{
174040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    const struct array_state_vector * arrays = state->array_state;
174140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
174240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick						    key, index );
174340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
174440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
174540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( a != NULL ) {
174640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	*dest = (GLintptr) a->normalized;
1747fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1748fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1749fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1750fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1751fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1752fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1753fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1754fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1755fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLuint
1756fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetActiveTextureUnit( const __GLXattribute * const state )
1757fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1758fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return state->array_state->active_texture_unit;
1759fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1760fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1761fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1762fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
1763fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXPushArrayState( __GLXattribute * state )
1764fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1765fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1766fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_stack_state * stack = & arrays->stack[ (arrays->stack_index * arrays->num_arrays)];
1767fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
1768fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
176988cf5aa783fc16043b31bc4cc0744412712dc22fBrian Paul    /* XXX are we pushing _all_ the necessary fields? */
1770fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1771fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].data = arrays->arrays[i].data;
1772fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].data_type = arrays->arrays[i].data_type;
1773fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].user_stride = arrays->arrays[i].user_stride;
1774fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].count = arrays->arrays[i].count;
1775fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].key = arrays->arrays[i].key;
177688cf5aa783fc16043b31bc4cc0744412712dc22fBrian Paul        stack[i].index = arrays->arrays[i].index;
1777fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].enabled = arrays->arrays[i].enabled;
1778fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1779fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1780fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit_stack[ arrays->stack_index ] =
1781fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      arrays->active_texture_unit;
1782fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1783fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack_index++;
1784fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1785fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1786fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1787fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
1788fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXPopArrayState( __GLXattribute * state )
1789fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1790fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1791fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_stack_state * stack;
1792fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
1793fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1794fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1795fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack_index--;
1796fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    stack = & arrays->stack[ (arrays->stack_index * arrays->num_arrays) ];
1797fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1798fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1799fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch ( stack[i].key ) {
1800fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_NORMAL_ARRAY:
1801fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glNormalPointer( stack[i].data_type,
1802fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					stack[i].user_stride,
1803fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					stack[i].data );
1804fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1805fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_COLOR_ARRAY:
1806fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glColorPointer( stack[i].count,
1807fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].data_type,
1808fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].user_stride,
1809fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].data );
1810fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1811fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_INDEX_ARRAY:
1812fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glIndexPointer( stack[i].data_type,
1813fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].user_stride,
1814fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].data );
1815fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1816fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_EDGE_FLAG_ARRAY:
1817fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glEdgeFlagPointer( stack[i].user_stride,
1818fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].data );
1819fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1820fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_TEXTURE_COORD_ARRAY:
1821fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    arrays->active_texture_unit = stack[i].index;
1822fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glTexCoordPointer( stack[i].count,
1823fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].data_type,
1824fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].user_stride,
1825fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].data );
1826fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1827fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_SECONDARY_COLOR_ARRAY:
1828fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glSecondaryColorPointerEXT( stack[i].count,
1829fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						   stack[i].data_type,
1830fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						   stack[i].user_stride,
1831fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						   stack[i].data );
1832fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1833fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_FOG_COORDINATE_ARRAY:
1834fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glFogCoordPointerEXT( stack[i].data_type,
1835fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					     stack[i].user_stride,
1836fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					     stack[i].data );
1837fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1838fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1839fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1840fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1841fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSetArrayEnable( state, stack[i].key, stack[i].index,
1842fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			     stack[i].enabled );
1843fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1844fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1845b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick    arrays->active_texture_unit =
1846b81efaaa1ac8676a1092e4354079ffcbe7960af2Ian Romanick      arrays->active_texture_unit_stack[ arrays->stack_index ];
1847fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1848