indirect_vertex_array.c revision 03dc437363429d275b7f8cae74201a8e7993a52b
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"
35fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
3603dc437363429d275b7f8cae74201a8e7993a52bIan Romanick#define __GLX_PAD(n) (((n)+3) & ~3)
3703dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
38fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
39fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \file indirect_vertex_array.c
40fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Implement GLX protocol for vertex arrays and vertex buffer objects.
41fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
42fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The most important function in this fill is \c fill_array_info_cache.
43fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
44fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * in the DrawArrays protocol.  Certain operations, such as enabling or
45fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * disabling an array, can invalidate this cache.  \c fill_array_info_cache
46fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * fills-in this data.  Additionally, it examines the enabled state and
47fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * other factors to determine what "version" of DrawArrays protocoal can be
48fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * used.
49fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
50fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Current, only two versions of DrawArrays protocol are implemented.  The
51fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * first version is the "none" protocol.  This is the fallback when the
52fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * server does not support GL 1.1 / EXT_vertex_arrays.  It is implemented
53fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * by sending batches of immediate mode commands that are equivalent to the
54fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * DrawArrays protocol.
55fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
56fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * The other protocol that is currently implemented is the "old" protocol.
57fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * This is the GL 1.1 DrawArrays protocol.  The only difference between GL
58fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
59fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * This protocol is called "old" because the ARB is in the process of
60fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * defining a new protocol, which will probably be called wither "new" or
61fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * "vbo", to support multiple texture coordinate arrays, generic attributes,
62fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * and vertex buffer objects.
63fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
64fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \author Ian Romanick <idr@us.ibm.com>
65fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
66fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
67fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
68fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
69fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * State descriptor for a single array of vertex data.
70fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
71fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstruct array_state {
72fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
73fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Pointer to the application supplied data.
74fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
75fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const void * data;
76fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
77fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
78fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Enum representing the type of the application supplied data.
79fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
80fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLenum data_type;
81fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
82fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
83fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Stride value supplied by the application.  This value is not used
84fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * internally.  It is only kept so that it can be queried by the
85fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * application using glGet*v.
86fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
87fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei user_stride;
88fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
89fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
90fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Calculated size, in bytes, of a single element in the array.  This
91fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * is calculated based on \c count and the size of the data type
92fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * represented by \c data_type.
93fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
94fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei element_size;
95fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
96fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
97fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Actual byte-stride from one element to the next.  This value will
98fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * be equal to either \c user_stride or \c element_stride.
99fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
100fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei true_stride;
101fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
102fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
103fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Number of data values in each element.
104fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
105fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLint count;
106fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
107fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
10840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     * "Normalized" data is on the range [0,1] (unsigned) or [-1,1] (signed).
10940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     * This is used for mapping integral types to floating point types.
11040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     */
11140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    GLboolean normalized;
11240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
11340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    /**
114fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Pre-calculated GLX protocol command header.
115fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
116fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint32_t header[2];
117fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
118fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
119fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Size of the header data.  For simple data, like glColorPointerfv,
120fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * this is 4.  For complex data that requires either a count (e.g.,
121fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * glWeightfvARB), an index (e.g., glVertexAttrib1fvARB), or a
122fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * selector enum (e.g., glMultiTexCoord2fv) this is 8.
123fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
124fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned header_size;
125fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
126fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
127fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Set to \c GL_TRUE if this array is enabled.  Otherwise, it is set
128fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * to \c GL_FALSE.
129fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
130fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean  enabled;
131fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
132fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
133fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * For multi-arrayed data (e.g., texture coordinates, generic vertex
134fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * program attributes, etc.), this specifies which array this is.
135fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
136fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned index;
137fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
138fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
139fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Per-array-type key.  For most arrays, this will be the GL enum for
140fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY
141fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data,
142fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * etc.).
143fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
144fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLenum key;
145fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
146fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
147fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * If this array can be used with the "classic" \c glDrawArrays protocol,
148fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * this is set to \c GL_TRUE.  Otherwise, it is set to \c GL_FALSE.
149fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
150fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean old_DrawArrays_possible;
151fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick};
152fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
153fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
154fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
155fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Array state that is pushed / poped by \c glPushClientAttrib and
156fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c glPopClientAttrib.
157fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
158fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstruct array_stack_state {
159fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
160fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Pointer to the application supplied data.
161fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
162fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const void * data;
163fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
164fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
165fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Enum representing the type of the application supplied data.
166fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
167fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLenum data_type;
168fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
169fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
170fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Stride value supplied by the application.  This value is not used
171fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * internally.  It is only kept so that it can be queried by the
172fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * application using glGet*v.
173fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
174fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei user_stride;
175fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
176fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
177fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Number of data values in each element.
178fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
179fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLint count;
180fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
181fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
182fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Per-array-type key.  For most arrays, this will be the GL enum for
183fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY
184fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data,
185fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * etc.).
186fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
187fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLenum key;
188fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
189fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
190fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * For multi-arrayed data (e.g., texture coordinates, generic vertex
191fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * program attributes, etc.), this specifies which array this is.
192fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
193fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned index;
194fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
195fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
196fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Set to \c GL_TRUE if this array is enabled.  Otherwise, it is set
197fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * to \c GL_FALSE.
198fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
199fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean  enabled;
200fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick};
201fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
202fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
203fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
204fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Collection of all the vertex array state.
205fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
206fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstruct array_state_vector {
207fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
208fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Number of arrays tracked by \c ::arrays.
209fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
210fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t num_arrays;
211fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
212fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
213fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Array of vertex array state.  This array contains all of the valid
214fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * vertex arrays.  If a vertex array isn't in this array, then it isn't
215fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * valid.  For example, if an implementation does not support
216fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * EXT_fog_coord, there won't be a GL_FOG_COORD_ARRAY entry in this
217fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * array.
218fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
219fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * arrays;
220fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
221fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
222fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Number of currently enabled arrays.  The value of this field is
223fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * only valid if \c array_info_cache_valid is true.
224fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
225fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t enabled_array_count;
226fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
227fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
228fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \name ARRAY_INFO cache.
229fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
230fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * These fields track the state of the ARRAY_INFO cache.  The
231fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c array_info_cache_size is the size of the actual data stored in
232fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c array_info_cache.  \c array_info_cache_buffer_size is the size of
233fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * the buffer.  This will always be greater than or equal to
234fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c array_info_cache_size.
235fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
236fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c large_header doesn't completely belong in this group.  This is a
237fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * pointer to a buffer to hold the header information for DrawArrays in
238fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * a RenderLarge command.  This buffer is immediately before
239fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c array_info_cache.  The idea is that the header data will be written
240fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * to \c large_header and a single call to \c __glXSendLargeChunk can be
241fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * made to send the header and the ARRAY_INFO data.
242fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
243fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \note
244fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c array_info_cache_size and \c array_info_cache_buffer_size do
245fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * NOT include the size of \c large_header.
246fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
247fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /*@{*/
248fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t array_info_cache_size;
249fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t array_info_cache_buffer_size;
250fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    void * array_info_cache;
251fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * large_header;
252fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /*@}*/
253fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
254fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
255fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
256fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Is the cache of ARRAY_INFO data valid?  The cache can become invalid
257fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * when one of several state changes occur.  Among these chages are
258fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * modifying the array settings for an enabled array and enabling /
259fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * disabling an array.
260fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
261fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean array_info_cache_valid;
262fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
263fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
264fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Is it possible to use the GL 1.1 / EXT_vertex_arrays protocol?  Use
265fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * of this protocol is disabled with really old servers (i.e., servers
266fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * that don't support GL 1.1 or EXT_vertex_arrays) or when an environment
267fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * variable is set.
268fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
269fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \todo
270fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * GL 1.1 and EXT_vertex_arrays use identical protocol, but have different
271fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * opcodes for \c glDrawArrays.  For servers that advertise one or the
272fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * other, there should be a way to select which opcode to use.
273fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
274fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean old_DrawArrays_possible;
275fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
276fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
277fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Is it possible to use the new GL X.X / ARB_vertex_buffer_object
278fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * protocol?
279fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
280fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \todo
281fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * This protocol has not yet been defined by the ARB, but is currently a
282fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * work in progress.  This field is a place-holder.
283fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
284fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean new_DrawArrays_possible;
285fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
286fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
287fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Active texture unit set by \c glClientActiveTexture.
288fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
289fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \sa __glXGetActiveTextureUnit
290fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
291fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned active_texture_unit;
292fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
293fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
294fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Number of supported texture units.  Even if ARB_multitexture /
295fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * GL 1.3 are not supported, this will be at least 1.  When multitexture
296fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * is supported, this will be the value queried by calling
297fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \c glGetIntegerv with \c GL_MAX_TEXTURE_UNITS.
298fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
299fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \todo
300fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Investigate if this should be the value of \c GL_MAX_TEXTURE_COORDS
301fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * instead (if GL 2.0 / ARB_fragment_shader / ARB_fragment_program /
302fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * NV_fragment_program are supported).
303fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
304fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned num_texture_units;
305fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
306fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /**
30740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     * Number of generic vertex program attribs.  If GL_ARB_vertex_program
30840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     * is not supported, this will be zero.  Otherwise it will be the value
30940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     * queries by calling \c glGetProgramiv with \c GL_VERTEX_PROGRAM_ARB
31040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     * and \c GL_MAX_PROGRAM_ATTRIBS_ARB.
31140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick     */
31240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    unsigned num_vertex_program_attribs;
31340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
31440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    /**
315fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \n Methods for implementing various GL functions.
316fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
317fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * These method pointers are only valid \c array_info_cache_valid is set.
318fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * When each function starts, it much check \c array_info_cache_valid.
319fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * If it is not set, it must call \c fill_array_info_cache and call
320fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * the new method.
321fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
322fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \sa fill_array_info_cache
323fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
324fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * \todo
325fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * Write code to plug these functions directly into the dispatch table.
326fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
327fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /*@{*/
328fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    void (*DrawArrays)( GLenum, GLint, GLsizei );
329fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    void (*DrawElements)( GLenum mode, GLsizei count, GLenum type,
330fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			  const GLvoid *indices );
331fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /*@}*/
332fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
333fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_stack_state * stack;
334fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned active_texture_unit_stack[ __GL_CLIENT_ATTRIB_STACK_DEPTH ];
335fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned stack_index;
336fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick};
337fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
338fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
339fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count );
340fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawArrays_old ( GLenum mode, GLint first, GLsizei count );
341fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
342fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
343fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLvoid *indices );
344fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void emit_DrawElements_old ( GLenum mode, GLsizei count, GLenum type,
345fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLvoid *indices );
346fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
347fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
348fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLubyte * emit_element_none( GLubyte * dst,
349fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays, unsigned index );
350fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLubyte * emit_element_old( GLubyte * dst,
351fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays, unsigned index );
352fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic struct array_state * get_array_entry(
353fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays, GLenum key, unsigned index );
354fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic void fill_array_info_cache( struct array_state_vector * arrays );
35540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickstatic GLboolean validate_mode(__GLXcontext *gc, GLenum mode);
35640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickstatic GLboolean validate_count(__GLXcontext *gc, GLsizei count);
35703dc437363429d275b7f8cae74201a8e7993a52bIan Romanickstatic GLboolean validate_type(__GLXcontext *gc, GLenum type);
358fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
359fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
360fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
361fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Table of sizes, in bytes, of a GL types.  All of the type enums are be in
362fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * the range 0x1400 - 0x140F.  That includes types added by extensions (i.e.,
363fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_HALF_FLOAT_NV).  This elements of this table correspond to the
364fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * type enums masked with 0x0f.
365fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
366fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \notes
367fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_HALF_FLOAT_NV is not included.  Neither are \c GL_2_BYTES,
368fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_3_BYTES, or \c GL_4_BYTES.
369fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
370fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickconst GLuint __glXTypeSize_table[16] = {
371fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
372fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick};
373fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
374fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
375fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
376fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
377fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Initialize vertex array state of a GLX context.
378fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
379fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param gc  GLX context whose vertex array state is to be initialized.
380fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
381fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \warning
382fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * This function may only be called after __GLXcontext::gl_extension_bits,
383fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * __GLXcontext::server_minor, and __GLXcontext::server_major have been
384fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * initialized.  These values are used to determine what vertex arrays are
385fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * supported.
386fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
387fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \bug
388fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Return values from malloc are not properly tested.
389fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
390fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
391fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXInitVertexArrayState( __GLXcontext * gc )
392fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
393fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
394fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays;
395fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
396fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned array_count;
397fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned texture_units = 1;
398fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
39940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    unsigned j;
40003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    unsigned vertex_program_attribs = 0;
401fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
402fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean got_fog = GL_FALSE;
403fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean got_secondary_color = GL_FALSE;
404fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
405fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
406fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays = malloc( sizeof( struct array_state_vector ) );
407fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    state->array_state = arrays;
408fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->enabled_array_count = 0;
409fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache = NULL;
410fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_size = 0;
411fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_buffer_size = 0;
412fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_valid= GL_FALSE;
413fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
414fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
415fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->new_DrawArrays_possible = GL_FALSE;
416fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->DrawArrays = NULL;
417fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
418fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit = 0;
419fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
420fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
421fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Determine how many arrays are actually needed.  Only arrays that
422fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * are supported by the server are create.  For example, if the server
423fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * supports only 2 texture units, then only 2 texture coordinate arrays
424fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * are created.
425fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     *
426fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
427fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
428fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * GL_EDGE_FLAG_ARRAY are supported.
429fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
430fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
431fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    array_count = 5;
432fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
433fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_EXT_fog_coord_bit )
434fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 || (gc->server_major > 1) || (gc->server_minor >= 4) ) {
435fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	got_fog = GL_TRUE;
436fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	array_count++;
437fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
438fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
439fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_EXT_secondary_color_bit )
440fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 || (gc->server_major > 1) || (gc->server_minor >= 4) ) {
441fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	got_secondary_color = GL_TRUE;
442fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	array_count++;
443fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
444fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
445fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_ARB_multitexture_bit )
446fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 || (gc->server_major > 1) || (gc->server_minor >= 3) ) {
44703dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	__indirect_glGetIntegerv( GL_MAX_TEXTURE_UNITS, & texture_units );
448fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
449fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
45040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( __glExtensionBitIsEnabled( gc, GL_ARB_vertex_program_bit ) ) {
45103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	__indirect_glGetProgramivARB( GL_VERTEX_PROGRAM_ARB,
45203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick				      GL_MAX_PROGRAM_ATTRIBS_ARB,
45303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick				      & vertex_program_attribs );
45440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
45540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
456fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->num_texture_units = texture_units;
45740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    arrays->num_vertex_program_attribs = vertex_program_attribs;
45840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    array_count += texture_units + vertex_program_attribs;
459fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->num_arrays = array_count;
460fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays = malloc( sizeof( struct array_state ) * array_count );
461fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
462fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memset( arrays->arrays, 0,
463fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		   sizeof( struct array_state ) * array_count );
464fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
465fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
466fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].data_type = GL_FLOAT;
467fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].count = 3;
468fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].key = GL_NORMAL_ARRAY;
46940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    arrays->arrays[0].normalized = GL_TRUE;
470fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
471fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
472fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].data_type = GL_FLOAT;
473fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].count = 4;
474fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].key = GL_COLOR_ARRAY;
47540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    arrays->arrays[1].normalized = GL_TRUE;
476fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
477fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
478fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].data_type = GL_FLOAT;
479fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].count = 1;
480fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].key = GL_INDEX_ARRAY;
481fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
482fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
483fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
484fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].count = 1;
485fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
486fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
487fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
488fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < texture_units ; i++ ) {
489fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].data_type = GL_FLOAT;
490fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].count = 4;
491fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
49240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
493fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
494fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].index = i;
495fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
496fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0;
497fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
498fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
499fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    i = 4 + texture_units;
500fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
501fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( got_fog ) {
502fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].data_type = GL_FLOAT;
503fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].count = 1;
504fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
505fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
506fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	i++;
507fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
508fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
509fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( got_secondary_color ) {
510fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].data_type = GL_FLOAT;
511fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].count = 3;
512fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
513fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
51440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[i].normalized = GL_TRUE;
515fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	i++;
516fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
517fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
518fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
51940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    for ( j = 0 ; j < vertex_program_attribs ; j++ ) {
52040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	const unsigned idx = (vertex_program_attribs - (j + 1));
52140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
52240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
52340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].data_type = GL_FLOAT;
52440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].count = 4;
52540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
52640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
52740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].old_DrawArrays_possible = 0;
52840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].index = idx;
52940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
53040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->arrays[idx + i].header[1] = idx;
53140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
53240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
53340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    i += vertex_program_attribs;
53440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
53540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
536fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Vertex array *must* be last becuase of the way that
537fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * emit_DrawArrays_none works.
538fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
539fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
540fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].data_type = GL_FLOAT;
541fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].count = 4;
542fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].key = GL_VERTEX_ARRAY;
543fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
544fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
545fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
546fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack_index = 0;
547fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack = malloc( sizeof( struct array_stack_state )
548fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    * arrays->num_arrays );
549fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
550fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
551fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
552fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
553fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Calculate the size of a single vertex for the "none" protocol.  This is
554fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * essentially the size of all the immediate-mode commands required to
555fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * implement the enabled vertex arrays.
556fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
557fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic size_t
558fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickcalculate_single_vertex_size_none( const struct array_state_vector * arrays )
559fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
560fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size = 0;
561fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned   i;
562fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
563fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
564fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
565fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    	if ( arrays->arrays[i].enabled ) {
56640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    single_vertex_size += ((uint16_t *)arrays->arrays[i].header)[0];
567fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
568fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
569fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
570fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return single_vertex_size;
571fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
572fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
573fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
574fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
575fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit a single element using non-DrawArrays protocol.
576fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
577fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLubyte *
578fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_element_none( GLubyte * dst,
579fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		   const struct array_state_vector * arrays,
580fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		   unsigned index )
581fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
582fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
583fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
584fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
585fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
586fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
587fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    const size_t offset = index * arrays->arrays[i].true_stride;
588fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
58940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    /* The generic attributes can have more data than is in the
59040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * elements.  This is because a vertex array can be a 2 element,
59140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * normalized, unsigned short, but the "closest" immediate mode
59240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * protocol is for a 4Nus.  Since the sizes are small, the
59340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     * performance impact on modern processors should be negligible.
59440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	     */
59540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    (void) memset( dst, 0,
59640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick			   ((uint16_t *)arrays->arrays[i].header)[0] );
59740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
598fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) memcpy( dst, arrays->arrays[i].header,
599fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   arrays->arrays[i].header_size );
600fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
601fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    dst += arrays->arrays[i].header_size;
602fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
603fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) memcpy( dst, ((GLubyte *) arrays->arrays[i].data) + offset,
604fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   arrays->arrays[i].element_size );
605fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
606fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    dst += __GLX_PAD( arrays->arrays[i].element_size );
607fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
608fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
609fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
610fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return dst;
611fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
612fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
613fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
614fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
615fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit a single element using "old" DrawArrays protocol from
616fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * EXT_vertex_arrays / OpenGL 1.1.
617fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
618fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLubyte *
619fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_element_old( GLubyte * dst,
620fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		  const struct array_state_vector * arrays,
621fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		  unsigned index )
622fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
623fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
624fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
625fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
626fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
627fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
628fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    const size_t offset = index * arrays->arrays[i].true_stride;
629fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
630fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) memcpy( dst, ((GLubyte *) arrays->arrays[i].data) + offset,
631fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   arrays->arrays[i].element_size );
632fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
633fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    dst += __GLX_PAD( arrays->arrays[i].element_size );
634fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
635fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
636fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
637fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return dst;
638fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
639fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
640fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
641fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstruct array_state *
642fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickget_array_entry( const struct array_state_vector * arrays,
643fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		 GLenum key, unsigned index )
644fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
645fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
646fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
647fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
648fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (arrays->arrays[i].key == key)
649fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	     && (arrays->arrays[i].index == index) ) {
650fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return & arrays->arrays[i];
651fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
652fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
653fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
654fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return NULL;
655fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
656fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
657fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
658fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLboolean
659fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickallocate_array_info_cache( struct array_state_vector * arrays,
660fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			   size_t required_size )
661fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
662fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( arrays->array_info_cache_buffer_size < required_size ) {
663fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	GLubyte * temp = realloc( arrays->array_info_cache, required_size + 20 );
664fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
665fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( temp == NULL ) {
666fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return GL_FALSE;
667fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
668fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
669fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->large_header = temp;
670fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache = temp + 20;
671fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_buffer_size = required_size;
672fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
673fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
674fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_size = required_size;
675fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return GL_TRUE;
676fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
677fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
678fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
679fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
680fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
681fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
682fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickfill_array_info_cache( struct array_state_vector * arrays )
683fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
684fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLboolean old_DrawArrays_possible;
685fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
686fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
687fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
688fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Determine how many arrays are enabled.
689fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
690fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
691fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->enabled_array_count = 0;
692fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    old_DrawArrays_possible = arrays->old_DrawArrays_possible;
693fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
694fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
695fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    arrays->enabled_array_count++;
696fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
697fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
698fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
699fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
700fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
701fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( arrays->new_DrawArrays_possible ) {
702fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( ! arrays->new_DrawArrays_possible );
703fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
704fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else if ( old_DrawArrays_possible ) {
705fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	const size_t required_size = arrays->enabled_array_count * 12;
706fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	uint32_t * info;
707fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
708fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
709fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! allocate_array_info_cache( arrays, required_size ) ) {
710fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
711fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
712fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
713fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
714fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	info = (uint32_t *) arrays->array_info_cache;
715fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
716fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( arrays->arrays[i].enabled ) {
717fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		*(info++) = arrays->arrays[i].data_type;
718fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		*(info++) = arrays->arrays[i].count;
719fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		*(info++) = arrays->arrays[i].key;
720fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
721fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
722fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
723fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        arrays->array_info_cache_valid = GL_TRUE;
724fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawArrays = emit_DrawArrays_old;
725fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements = emit_DrawElements_old;
726fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
727fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
728fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawArrays = emit_DrawArrays_none;
729fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements = emit_DrawElements_none;
730fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
731fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
732fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
733fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
734fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
735fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit a \c glDrawArrays command using the "none" protocol.  That is,
736fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * emit immediate-mode commands that are equivalent to the requiested
737fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c glDrawArrays command.  This is used with servers that don't support
738fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
739fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * vertex state is enabled that is not compatible with that protocol.
740fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
741fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
742fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawArrays_none( GLenum mode, GLint first, GLsizei count )
743fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
744fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
745fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
746fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
747fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
748fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
749fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
750fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
751fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
752fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
753fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t end_cmd[2]   = { 4, X_GLrop_End };
754fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
755fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
756fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = calculate_single_vertex_size_none( arrays );
757fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
758fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = gc->pc;
759fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
760fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, begin_cmd, 4 );
761fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    *(int *)(pc +  4) = mode;
762fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
763fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 8;
764fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
765fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < count ; i++ ) {
766fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (pc + single_vertex_size) >= gc->bufEnd ) {
767fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = __glXFlushRenderBuffer(gc, gc->pc);
768fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
769fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
770fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = emit_element_none( pc, arrays, first + i );
771fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
772fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
773fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (pc + 4) >= gc->bufEnd ) {
774fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = __glXFlushRenderBuffer(gc, gc->pc);
775fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
776fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
777fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, end_cmd, 4 );
778fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 4;
779fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
780fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    gc->pc = pc;
781fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( gc->pc > gc->limit ) {
782fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) __glXFlushRenderBuffer(gc, gc->pc);
783fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
784fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
785fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
786fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
787fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
788fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
789fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * protocol.
790fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
791fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param gc                    GLX context.
792fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param arrays                Array state.
793fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param elements_per_request  Location to store the number of elements that
794fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              can fit in a single Render / RenderLarge
795fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              command.
796fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param total_request         Total number of requests for a RenderLarge
797fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              command.  If a Render command is used, this
798fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *                              will be zero.
799fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param mode                  Drawing mode.
800fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \param count                 Number of vertices.
801fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
802fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \returns
803fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * A pointer to the buffer for array data.
804fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
805fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLubyte *
806fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawArrays_header_old( __GLXcontext * gc,
807fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    struct array_state_vector * arrays,
808fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    size_t * elements_per_request,
809fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    size_t * total_requests,
810fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			    GLenum mode, GLsizei count )
811fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
812fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t command_size;
813fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
814fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const unsigned header_size = 16;
815fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
816fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
817fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
818fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
819fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Determine the size of the whole command.  This includes the header,
820fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * the ARRAY_INFO data and the array data.  Once this size is calculated,
821fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * it will be known whether a Render or RenderLarge command is needed.
822fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
823fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
824fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = 0;
825fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
826fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( arrays->arrays[i].enabled ) {
827fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    single_vertex_size += __GLX_PAD( arrays->arrays[i].element_size );
828fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
829fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
830fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
831fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    command_size = arrays->array_info_cache_size + header_size
832fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      + (single_vertex_size * count);
833fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
834fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
835fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Write the header for either a Render command or a RenderLarge
836fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     * command.  After the header is written, write the ARRAY_INFO data.
837fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
838fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
839fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( command_size > gc->maxSmallRenderCommandSize ) {
840fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	/* maxSize is the maximum amount of data can be stuffed into a single
841fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * packet.  sz_xGLXRenderReq is added because bufSize is the maximum
842fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * packet size minus sz_xGLXRenderReq.
843fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 */
844fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
845fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	  - sz_xGLXRenderLargeReq;
846fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	unsigned vertex_requests;
847fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
848fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
849fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	/* Calculate the number of data packets that will be required to send
850fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * the whole command.  To do this, the number of verticies that
851fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * will fit in a single buffer must be calculated.
852fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 *
853fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * The important value here is elements_per_request.  This is the
854fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * number of complete array elements that will fit in a single
855fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * buffer.  There may be some wasted space at the end of the buffer,
856fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 * but splitting elements across buffer boundries would be painful.
857fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	 */
858fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
859fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	elements_per_request[0] = maxSize / single_vertex_size;
860fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
861fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	vertex_requests = (count + elements_per_request[0] - 1)
862fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	  / elements_per_request[0];
863fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
864fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*total_requests = vertex_requests + 1;
865fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
866fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
867fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXFlushRenderBuffer(gc, gc->pc);
868fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
869fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	command_size += 4;
870fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
871fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = arrays->large_header;
872fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  0) = command_size;
873fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  4) = X_GLrop_DrawArrays;
874fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  8) = count;
875fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc + 12) = arrays->enabled_array_count;
876fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc + 16) = mode;
877fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
878fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSendLargeChunk( gc, 1, *total_requests, pc,
879fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			     header_size + 4 + arrays->array_info_cache_size );
880fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
881fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = gc->pc;
882fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
883fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
884fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (gc->pc + command_size) >= gc->bufEnd ) {
885fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) __glXFlushRenderBuffer(gc, gc->pc);
886fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
887fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
888fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = gc->pc;
889fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint16_t *)(pc +  0) = command_size;
890fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint16_t *)(pc +  2) = X_GLrop_DrawArrays;
891fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  4) = count;
892fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc +  8) = arrays->enabled_array_count;
893fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*(uint32_t *)(pc + 12) = mode;
894fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
895fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc += header_size;
896fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
897fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) memcpy( pc, arrays->array_info_cache,
898fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		       arrays->array_info_cache_size );
899fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc += arrays->array_info_cache_size;
900fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
901fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*elements_per_request = count;
902fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*total_requests = 0;
903fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
904fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
905fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
906fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return pc;
907fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
908fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
909fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
910fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
911fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
912fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
913fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawArrays_old( GLenum mode, GLint first, GLsizei count )
914fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
915fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
916fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
917fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
918fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
919fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
920fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
921fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t elements_per_request;
922fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned total_requests = 0;
923fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
924fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t total_sent = 0;
925fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
926fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
927fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
928fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				     & total_requests, mode, count);
929fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
930fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
931fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Write the arrays.
932fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
933fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
934fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( total_requests == 0 ) {
935fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( elements_per_request >= count );
936fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
937fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < count ; i++ ) {
938fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = emit_element_old( pc, arrays, i + first );
939fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
940fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
941fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( pc <= gc->bufEnd );
942fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
943fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = pc;
944fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( gc->pc > gc->limit ) {
945fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) __glXFlushRenderBuffer(gc, gc->pc);
946fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
947fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
948fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
949fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	unsigned req;
950fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
951fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
952fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( req = 2 ; req <= total_requests ; req++ ) {
953fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( count < elements_per_request ) {
954fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		elements_per_request = count;
955fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
956fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
957fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = gc->pc;
958fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
959fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, i + first );
960fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
961fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
962fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    first += elements_per_request;
963fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
964fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    total_sent += (size_t) (pc - gc->pc);
965fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSendLargeChunk( gc, req, total_requests, gc->pc,
966fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 pc - gc->pc );
967fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
968fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    count -= elements_per_request;
969fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
970fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
971fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
972fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
973fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
974fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
975fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
976fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			const GLvoid *indices )
977fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
978fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
979fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
980fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
981fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
982fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
983fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t end_cmd[2]   = { 4, X_GLrop_End };
984fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
985fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
986fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
987fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
988fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
989fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
990fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = calculate_single_vertex_size_none( arrays );
991fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
992fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
993fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {
994fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
995fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
996fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
997fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = gc->pc;
998fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
999fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, begin_cmd, 4 );
1000fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    *(int *)(pc +  4) = mode;
1001fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1002fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 8;
1003fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1004fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < count ; i++ ) {
100503dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	unsigned  index = 0;
1006fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1007fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( (pc + single_vertex_size) >= gc->bufEnd ) {
1008fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = __glXFlushRenderBuffer(gc, gc->pc);
1009fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1010fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1011fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch( type ) {
1012fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_INT:
1013fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    index = (unsigned) (((GLuint *) indices)[i]);
1014fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1015fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_SHORT:
1016fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    index = (unsigned) (((GLushort *) indices)[i]);
1017fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1018fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_BYTE:
1019fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    index = (unsigned) (((GLubyte *) indices)[i]);
1020fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1021fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1022fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = emit_element_none( pc, arrays, index );
1023fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1024fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1025fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (pc + 4) >= gc->bufEnd ) {
1026fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	pc = __glXFlushRenderBuffer(gc, gc->pc);
1027fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1028fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1029fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    (void) memcpy( pc, end_cmd, 4 );
1030fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc += 4;
1031fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1032fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    gc->pc = pc;
1033fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( gc->pc > gc->limit ) {
1034fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) __glXFlushRenderBuffer(gc, gc->pc);
1035fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1036fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1037fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1038fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1039fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1040fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1041fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
1042fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickemit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
1043fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		       const GLvoid *indices )
1044fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1045fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1046fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1047fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1048fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1049fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1050fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLubyte * pc;
1051fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t elements_per_request;
1052fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned total_requests = 0;
1053fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned i;
1054fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned req;
1055fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLuint   * ui_ptr = (const GLuint   *) indices;
1056fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLushort * us_ptr = (const GLushort *) indices;
1057fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLubyte  * ub_ptr = (const GLubyte  *) indices;
1058fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1059fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1060fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
1061fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				     & total_requests, mode, count);
1062fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1063fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1064fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    /* Write the arrays.
1065fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick     */
1066fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1067fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    req = 2;
1068fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    while ( count > 0 ) {
1069fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( count < elements_per_request ) {
1070fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    elements_per_request = count;
1071fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1072fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1073fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch( type ) {
1074fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_INT:
1075fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
1076fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		const GLint index = (GLint) *(ui_ptr++);
1077fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, index );
1078fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1079fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1080fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_SHORT:
1081fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
1082fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		const GLint index = (GLint) *(us_ptr++);
1083fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, index );
1084fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1085fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1086fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_UNSIGNED_BYTE:
1087fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    for ( i = 0 ; i < elements_per_request ; i++ ) {
1088fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		const GLint index = (GLint) *(ub_ptr++);
1089fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		pc = emit_element_old( pc, arrays, index );
1090fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1091fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
1092fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1093fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1094fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( total_requests != 0 ) {
1095fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSendLargeChunk( gc, req, total_requests, gc->pc,
1096fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 pc - gc->pc );
1097fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    pc = gc->pc;
1098fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    req++;
1099fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1100fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1101fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	count -= elements_per_request;
1102fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1103fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1104fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1105fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( (total_requests == 0) || ((req - 1) == total_requests) );
1106fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1107fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( total_requests == 0 ) {
1108fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	assert( pc <= gc->bufEnd );
1109fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1110fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = pc;
1111fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( gc->pc > gc->limit ) {
1112fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    (void) __glXFlushRenderBuffer(gc, gc->pc);
1113fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1114fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1115fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1116fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1117fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1118fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1119fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
1120fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * If it is not valid, then an error code is set in the GLX context.
1121fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
1122fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \returns
1123fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
1124fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1125fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLboolean
1126fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvalidate_mode(__GLXcontext *gc, GLenum mode)
1127fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1128fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch(mode) {
1129fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_POINTS:
1130fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_LINE_STRIP:
1131fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_LINE_LOOP:
1132fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_LINES:
1133fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_TRIANGLE_STRIP:
1134fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_TRIANGLE_FAN:
1135fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_TRIANGLES:
1136fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_QUAD_STRIP:
1137fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_QUADS:
1138fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      case GL_POLYGON:
1139fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	break;
1140fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      default:
1141fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1142fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return GL_FALSE;
1143fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1144fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1145fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return GL_TRUE;
1146fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1147fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1148fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1149fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1150fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
1151fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
1152fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * being set.  A value of zero will not result in an error being set, but
1153fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * will result in \c GL_FALSE being returned.
1154fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick *
1155fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \returns
1156fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
1157fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1158fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickstatic GLboolean
1159fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvalidate_count(__GLXcontext *gc, GLsizei count)
1160fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1161fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (count < 0) {
1162fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSetError(gc, GL_INVALID_VALUE);
1163fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1164fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1165fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (count > 0);
1166fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1167fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1168fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
116903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick/**
117003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * Validate that the \c type parameter to \c glDrawElements, et. al. is
117103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * valid.  Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
117203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * \c GL_UNSIGNED_INT are valid.
117303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick *
117403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * \returns
117503dc437363429d275b7f8cae74201a8e7993a52bIan Romanick * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
117603dc437363429d275b7f8cae74201a8e7993a52bIan Romanick */
117703dc437363429d275b7f8cae74201a8e7993a52bIan Romanickstatic GLboolean validate_type(__GLXcontext *gc, GLenum type)
117803dc437363429d275b7f8cae74201a8e7993a52bIan Romanick{
117903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    switch( type ) {
118003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    case GL_UNSIGNED_INT:
118103dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    case GL_UNSIGNED_SHORT:
118203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    case GL_UNSIGNED_BYTE:
118303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	return GL_TRUE;
118403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick     default:
118503dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	__glXSetError(gc, GL_INVALID_ENUM);
118603dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	return GL_FALSE;
118703dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    }
118803dc437363429d275b7f8cae74201a8e7993a52bIan Romanick}
118903dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
119003dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
1191fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
1192fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1193fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1194fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1195fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1196fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1197fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1198fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1199fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( validate_mode(gc, mode) && validate_count(gc, count) ) {
1200fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1201fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1202fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1203fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1204fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawArrays(mode, first, count);
1205fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1206fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1207fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1208fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1209fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glArrayElement(GLint index)
1210fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1211fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1212fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1213fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1214fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1215fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1216fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    size_t single_vertex_size;
1217fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1218fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1219fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    single_vertex_size = calculate_single_vertex_size_none( arrays );
1220fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1221fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {
1222fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
1223fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1224fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1225fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    gc->pc = emit_element_none( gc->pc, arrays, index );
1226fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1227fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( gc->pc > gc->limit ) {
1228fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(void) __glXFlushRenderBuffer(gc, gc->pc);
1229fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1230fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1231fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1232fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1233fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
1234fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		    const GLvoid *indices)
1235fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1236fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1237fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1238fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1239fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1240fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1241fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
124203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    if ( validate_mode(gc, mode) && validate_count(gc, count)
124303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	 && validate_type(gc, type) ) {
1244fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1245fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1246fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1247fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1248fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements(mode, count, type, indices);
1249fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1250fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1251fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1252fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1253fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1254fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				    GLsizei count, GLenum type,
1255fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				    const GLvoid *indices)
1256fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1257fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1258fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1259fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1260fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1261fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1262fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
126303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    if ( validate_mode(gc, mode) && validate_count(gc, count)
126403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	 && validate_type(gc, type) ) {
1265fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if (end < start) {
1266fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSetError(gc, GL_INVALID_VALUE);
1267fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
1268fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1269fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1270fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1271fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1272fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1273fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1274fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->DrawElements(mode, count, type, indices);
1275fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1276fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1277fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1278fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1279fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count,
1280fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		       GLsizei primcount)
1281fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1282fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1283fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1284fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1285fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1286fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei  i;
1287fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1288fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1289fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( validate_mode(gc, mode) ) {
1290fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1291fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1292fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1293fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1294fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < primcount ; i++ ) {
1295fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( validate_count( gc, count[i] ) ) {
1296fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		arrays->DrawArrays(mode, first[i], count[i]);
1297fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1298fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1299fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1300fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1301fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1302fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1303fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count,
1304fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			 GLenum type, const GLvoid ** indices,
1305fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			 GLsizei primcount)
1306fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1307fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1308fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const __GLXattribute * state =
1309fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick       (const __GLXattribute *)(gc->client_state_private);
1310fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1311fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    GLsizei  i;
1312fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1313fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
131403dc437363429d275b7f8cae74201a8e7993a52bIan Romanick    if ( validate_mode(gc, mode) && validate_type(gc, type) ) {
1315fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	if ( ! arrays->array_info_cache_valid ) {
1316fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    fill_array_info_cache( arrays );
1317fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1318fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1319fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	for ( i = 0 ; i < primcount ; i++ ) {
1320fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    if ( validate_count( gc, count[i] ) ) {
1321fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		arrays->DrawElements(mode, count[i], type, indices[i]);
1322fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    }
1323fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1324fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1325fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1326fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1327fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1328fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, HDR_SIZE, OPCODE) \
1329fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    do { \
1330fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->data = PTR; \
1331fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->data_type = TYPE; \
1332fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->user_stride = STRIDE; \
1333fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->count = COUNT; \
1334fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	\
1335fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1336fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->true_stride = (STRIDE == 0) \
1337fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	  ? (a)->element_size : STRIDE; \
1338fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	\
1339fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	(a)->header_size = HDR_SIZE; \
1340fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1341fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	((uint16_t *) (a)->header)[1] = OPCODE; \
1342fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    } while(0)
1343fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1344fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1345fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glVertexPointer( GLint size, GLenum type, GLsizei stride,
1346fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 const GLvoid * pointer )
1347fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1348fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t short_ops[5] = {
1349fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1350fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1351fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t int_ops[5] = {
1352fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1353fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1354fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t float_ops[5] = {
1355fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1356fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1357fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t double_ops[5] = {
1358fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1359fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1360fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1361fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1362fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1363fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1364fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1365fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1366fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1367fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size < 2 || size > 4 || stride < 0) {
1368fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1369fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1370fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1371fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1372fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1373fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:	opcode = short_ops[size]; break;
1374fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:	opcode = int_ops[size]; break;
1375fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:	opcode = float_ops[size]; break;
1376fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:	opcode = double_ops[size]; break;
1377fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1378fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1379fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1380fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1381fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1382fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_VERTEX_ARRAY, 0 );
1383fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1384fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 4, opcode );
1385fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1386fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1387fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1388fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1389fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1390fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1391fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1392fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glNormalPointer( GLenum type, GLsizei stride,
1393fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				 const GLvoid * pointer )
1394fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1395fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1396fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1397fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1398fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1399fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1400fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1401fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1402fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1403fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1404fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1405fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1406fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1407fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1408fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_BYTE:	opcode = X_GLrop_Normal3bv; break;
1409fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:	opcode = X_GLrop_Normal3sv; break;
1410fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:	opcode = X_GLrop_Normal3iv; break;
1411fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:	opcode = X_GLrop_Normal3fv; break;
1412fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:	opcode = X_GLrop_Normal3dv; break;
1413fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1414fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1415fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1416fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1417fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1418fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_NORMAL_ARRAY, 0 );
1419fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1420fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 3, 4, opcode );
1421fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1422fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1423fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1424fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1425fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1426fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1427fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1428fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glColorPointer( GLint size, GLenum type, GLsizei stride,
1429fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1430fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1431fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t byte_ops[5] = {
1432fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1433fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1434fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t ubyte_ops[5] = {
1435fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1436fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1437fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t short_ops[5] = {
1438fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1439fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1440fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t ushort_ops[5] = {
1441fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1442fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1443fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t int_ops[5] = {
1444fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1445fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1446fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t uint_ops[5] = {
1447fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1448fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1449fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t float_ops[5] = {
1450fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1451fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1452fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t double_ops[5] = {
1453fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1454fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1455fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1456fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1457fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1458fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1459fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1460fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1461fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1462fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size < 3 || size > 4 || stride < 0) {
1463fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1464fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1465fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1466fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1467fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1468fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_BYTE:		opcode = byte_ops[size]; break;
1469fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_BYTE:	opcode = ubyte_ops[size]; break;
1470fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:		opcode = short_ops[size]; break;
1471fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_SHORT:	opcode = ushort_ops[size]; break;
1472fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:		opcode = int_ops[size]; break;
1473fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_INT:	opcode = uint_ops[size]; break;
1474fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = float_ops[size]; break;
1475fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = double_ops[size]; break;
1476fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1477fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1478fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1479fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1480fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1481fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_COLOR_ARRAY, 0 );
1482fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1483fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 4, opcode );
1484fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1485fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1486fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1487fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1488fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1489fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1490fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1491fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glIndexPointer( GLenum type, GLsizei stride,
1492fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1493fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1494fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1495fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1496fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1497fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1498fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1499fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1500fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1501fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1502fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1503fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1504fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1505fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1506fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1507fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_BYTE:	opcode = X_GLrop_Indexubv; break;
1508fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:		opcode = X_GLrop_Indexsv; break;
1509fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:		opcode = X_GLrop_Indexiv; break;
1510fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = X_GLrop_Indexfv; break;
1511fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = X_GLrop_Indexdv; break;
1512fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1513fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1514fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1515fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1516fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1517fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_INDEX_ARRAY, 0 );
1518fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1519fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 1, 4, opcode );
1520fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1521fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1522fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1523fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1524fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1525fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1526fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1527fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glEdgeFlagPointer( GLsizei stride, const GLvoid * pointer )
1528fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1529fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1530fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1531fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1532fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1533fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1534fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1535fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1536fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1537fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1538fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1539fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1540fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1541fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_EDGE_FLAG_ARRAY, 0 );
1542fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1543fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, GL_UNSIGNED_BYTE, stride, 1, 4, X_GLrop_EdgeFlagv );
1544fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1545fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1546fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1547fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1548fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1549fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1550fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1551fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glTexCoordPointer( GLint size, GLenum type, GLsizei stride,
1552fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				   const GLvoid * pointer )
1553fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1554fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t short_ops[5] = {
1555fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv, X_GLrop_TexCoord4sv
1556fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1557fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t int_ops[5] = {
1558fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv, X_GLrop_TexCoord4iv
1559fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1560fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t float_ops[5] = {
1561fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, X_GLrop_TexCoord4fv
1562fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1563fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t double_ops[5] = {
1564fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv, X_GLrop_TexCoord4dv
1565fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1566fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1567fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mshort_ops[5] = {
1568fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB, X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
1569fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1570fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mint_ops[5] = {
1571fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB, X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
1572fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1573fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mfloat_ops[5] = {
1574fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB, X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
1575fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1576fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    static const uint16_t mdouble_ops[5] = {
1577fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB, X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
1578fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    };
1579fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1580fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1581fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1582fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1583fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1584fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1585fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned header_size;
1586fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned index;
1587fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1588fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1589fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size < 1 || size > 4 || stride < 0) {
1590fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1591fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1592fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1593fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1594fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    index = arrays->active_texture_unit;
1595fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( index == 0 ) {
1596fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch ( type ) {
1597fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_SHORT:		opcode = short_ops[size]; break;
1598fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_INT:		opcode = int_ops[size]; break;
1599fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_FLOAT:		opcode = float_ops[size]; break;
1600fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_DOUBLE:		opcode = double_ops[size]; break;
1601fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	default:
1602fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
1603fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
1604fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1605fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1606fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	header_size = 4;
1607fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1608fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    else {
1609fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch ( type ) {
1610fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_SHORT:		opcode = mshort_ops[size]; break;
1611fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_INT:		opcode = mint_ops[size]; break;
1612fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_FLOAT:		opcode = mfloat_ops[size]; break;
1613fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_DOUBLE:		opcode = mdouble_ops[size]; break;
1614fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	default:
1615fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
1616fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    return;
1617fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
1618fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1619fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	header_size = 8;
1620fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1621fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1622fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_TEXTURE_COORD_ARRAY, index );
1623fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    assert( a != NULL );
1624fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, header_size, opcode );
1625fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1626fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1627fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1628fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1629fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1630fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1631fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1632fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glSecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride,
1633fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1634fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1635fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1636fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1637fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1638fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1639fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1640fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1641fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1642fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (size != 3 || stride < 0) {
1643fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1644fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1645fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1646fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1647fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1648fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_BYTE:		opcode = 4126; break;
1649fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_BYTE:	opcode = 4131; break;
1650fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_SHORT:		opcode = 4127; break;
1651fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_SHORT:	opcode = 4132; break;
1652fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_INT:		opcode = 4128; break;
1653fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_UNSIGNED_INT:	opcode = 4133; break;
1654fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = 4129; break;
1655fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = 4130; break;
1656fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1657fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1658fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1659fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1660fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1661fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_SECONDARY_COLOR_ARRAY, 0 );
1662fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a == NULL ) {
1663fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_OPERATION);
1664fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1665fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1666fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1667fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 4, opcode );
1668fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1669fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1670fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1671fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1672fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1673fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1674fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1675fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glFogCoordPointerEXT( GLenum type, GLsizei stride,
1676fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				const GLvoid * pointer )
1677fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1678fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    uint16_t opcode;
1679fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
1680fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1681fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1682fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1683fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1684fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1685fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if (stride < 0) {
1686fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
1687fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1688fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1689fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1690fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    switch ( type ) {
1691fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_FLOAT:		opcode = 4124; break;
1692fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    case GL_DOUBLE:		opcode = 4125; break;
1693fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    default:
1694fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_ENUM);
1695fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1696fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1697fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1698fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, GL_FOG_COORD_ARRAY, 0 );
1699fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a == NULL ) {
1700fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        __glXSetError(gc, GL_INVALID_OPERATION);
1701fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick        return;
1702fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1703fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1704fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 1, 4, opcode );
1705fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1706fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a->enabled ) {
1707fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1708fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1709fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1710fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1711fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
171240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickvoid __indirect_glVertexAttribPointerARB(GLuint index, GLint size,
171340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 GLenum type, GLboolean normalized,
171440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 GLsizei stride,
171540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 const GLvoid * pointer)
171640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick{
171740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    static const uint16_t short_ops[5]  = { 0, 4189, 4190, 4191, 4192 };
171840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    static const uint16_t float_ops[5]  = { 0, 4193, 4194, 4195, 4196 };
171940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    static const uint16_t double_ops[5] = { 0, 4197, 4198, 4199, 4200 };
172040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
172140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    uint16_t opcode;
172240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
172340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
172440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    struct array_state_vector * arrays = state->array_state;
172540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    struct array_state * a;
172640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    unsigned true_immediate_count;
172740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    unsigned true_immediate_size;
172840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
172940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
173040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( (size < 1) || (size > 4) || (stride < 0)
173140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	 || (index > arrays->num_vertex_program_attribs) ){
173240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        __glXSetError(gc, GL_INVALID_VALUE);
173340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        return;
173440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
173540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
173640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
173740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	switch( type ) {
173840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_BYTE:           opcode = X_GLrop_VertexAttrib4NbvARB;  break;
173940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_BYTE:  opcode = X_GLrop_VertexAttrib4NubvARB; break;
174040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_SHORT:          opcode = X_GLrop_VertexAttrib4NsvARB;  break;
174140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_SHORT: opcode = X_GLrop_VertexAttrib4NusvARB; break;
174240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_INT:            opcode = X_GLrop_VertexAttrib4NivARB;  break;
174340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_INT:   opcode = X_GLrop_VertexAttrib4NuivARB; break;
174440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	default:
174540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
174640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    return;
174740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	}
174840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
174940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	true_immediate_count = 4;
175040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
175140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    else {
175203dc437363429d275b7f8cae74201a8e7993a52bIan Romanick	true_immediate_count = size;
175303dc437363429d275b7f8cae74201a8e7993a52bIan Romanick
175440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	switch( type ) {
175540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_BYTE:
175640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4bvARB;
175740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
175840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
175940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_BYTE:
176040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4ubvARB;
176140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
176240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
176340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_SHORT:
176440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = short_ops[size];
176540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
176640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_SHORT:
176740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4usvARB;
176840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
176940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
177040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_INT:
177140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick            opcode = X_GLrop_VertexAttrib4ivARB;
177240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
177340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
177440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_UNSIGNED_INT:
177540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = X_GLrop_VertexAttrib4uivARB;
177640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    true_immediate_count = 4;
177740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
177840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_FLOAT:
177940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = float_ops[size];
178040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
178140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	case GL_DOUBLE:
178240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    opcode = double_ops[size];
178340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    break;
178440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	default:
178540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    __glXSetError(gc, GL_INVALID_ENUM);
178640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    return;
178740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	}
178840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
178940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
179040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    a = get_array_entry( arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index );
179140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( a == NULL ) {
179240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        __glXSetError(gc, GL_INVALID_OPERATION);
179340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick        return;
179440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
179540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
179640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 8, opcode );
179740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
179840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    true_immediate_size = __glXTypeSize(type) * true_immediate_count;
179940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size
180040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					      + true_immediate_size);
180140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
180240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( a->enabled ) {
180340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
180440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
180540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick}
180640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
180740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
180840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick/**
180940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * I don't have 100% confidence that this is correct.  The different rules
181040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * about whether or not generic vertex attributes alias "classic" vertex
181140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
181240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * ARB_vertex_shader, and NV_vertex_program are a bit confusing.  My
181340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * feeling is that the client-side doesn't have to worry about it.  The
181440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * client just sends all the data to the server and lets the server deal
181540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick * with it.
181640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick */
181740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanickvoid __indirect_glVertexAttribPointerNV( GLuint index, GLint size,
181840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 GLenum type, GLsizei stride,
181940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					 const GLvoid * pointer)
182040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick{
182140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    __GLXcontext *gc = __glXGetCurrentContext();
182240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    GLboolean normalized = GL_FALSE;
182340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
182440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
182540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    switch( type ) {
182640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_UNSIGNED_BYTE:
182740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	if ( size != 4 ) {
182840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    __glXSetError(gc, GL_INVALID_VALUE);
182940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	    return;
183040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	}
183140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	normalized = GL_TRUE;
183240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
183340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_SHORT:
183440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_FLOAT:
183540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    case GL_DOUBLE:
183640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	__indirect_glVertexAttribPointerARB(index, size, type,
183740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					    normalized,
183840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick					    stride, pointer);
183940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	return;
184040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    default:
184140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	__glXSetError(gc, GL_INVALID_ENUM);
184240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	return;
184340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
184440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick}
184540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
184640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
1847fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid __indirect_glClientActiveTextureARB(GLenum texture)
1848fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1849fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXcontext * const gc = __glXGetCurrentContext();
1850fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    __GLXattribute * const state = (__GLXattribute *)(gc->client_state_private);
1851fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * const arrays = state->array_state;
1852fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const GLint unit = (GLint) texture - GL_TEXTURE0;
1853fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1854fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1855fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (unit < 0) || (unit > arrays->num_texture_units) ) {
1856fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSetError(gc, GL_INVALID_ENUM);
1857fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	return;
1858fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1859fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1860fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit = unit;
1861fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1862fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1863fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1864fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1865fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1866fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1867fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXSetArrayEnable( __GLXattribute * state,
1868fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLboolean enable )
1869fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1870fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1871fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state * a;
1872fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1873fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1874fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( key == GL_TEXTURE_COORD_ARRAY ) {
1875fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	index = arrays->active_texture_unit;
1876fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1877fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1878fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    a = get_array_entry( arrays, key, index );
1879fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1880fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( (a != NULL) && (a->enabled != enable) ) {
1881fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	a->enabled = enable;
1882fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->array_info_cache_valid = GL_FALSE;
1883fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1884fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1885fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1886fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1887fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1888fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1889fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
1890fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXArrayDisableAll( __GLXattribute * state )
1891fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1892fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
1893fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
1894fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1895fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1896fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1897fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	arrays->arrays[i].enabled = GL_FALSE;
1898fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1899fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1900fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->array_info_cache_valid = GL_FALSE;
1901fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1902fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1903fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1904fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1905fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1906fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1907fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayEnable( const __GLXattribute * const state,
1908fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1909fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1910fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1911fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1912fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1913fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1914fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1915fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->enabled;
1916fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1917fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1918fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1919fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1920fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1921fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1922fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1923fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1924fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1925fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayType( const __GLXattribute * const state,
1926fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1927fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1928fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1929fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1930fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1931fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1932fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1933fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->enabled;
1934fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1935fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1936fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1937fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1938fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1939fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1940fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1941fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1942fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1943fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArraySize( const __GLXattribute * const state,
1944fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1945fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1946fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1947fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1948fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1949fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1950fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1951fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->count;
1952fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1953fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1954fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1955fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1956fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1957fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1958fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1959fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1960fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1961fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayStride( const __GLXattribute * const state,
1962fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		     GLenum key, unsigned index, GLintptr * dest )
1963fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1964fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1965fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1966fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1967fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1968fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
1969fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	*dest = (GLintptr) a->user_stride;
1970fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
1971fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1972fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
1973fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
1974fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1975fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1976fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
1977fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
1978fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLboolean
1979fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetArrayPointer( const __GLXattribute * const state,
1980fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick		      GLenum key, unsigned index, void ** dest )
1981fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
1982fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state_vector * arrays = state->array_state;
1983fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1984fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						    key, index );
1985fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1986fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
1987fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    if ( a != NULL ) {
198840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	*dest = (void *) (a->data);
198940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    }
199040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
199140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    return (a != NULL);
199240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick}
199340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
199440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
199540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick/**
199640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick */
199740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan RomanickGLboolean
199840af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick__glXGetArrayNormalized( const __GLXattribute * const state,
199940af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick			 GLenum key, unsigned index, GLintptr * dest )
200040af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick{
200140af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    const struct array_state_vector * arrays = state->array_state;
200240af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
200340af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick						    key, index );
200440af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
200540af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick
200640af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick    if ( a != NULL ) {
200740af76bbaa9e8909d63d8eeab4689ed2dfe1e19cIan Romanick	*dest = (GLintptr) a->normalized;
2008fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
2009fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2010fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return (a != NULL);
2011fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
2012fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2013fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2014fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick/**
2015fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick */
2016fdb07636f2e6324c5250cd5ee97778b7f5933beaIan RomanickGLuint
2017fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXGetActiveTextureUnit( const __GLXattribute * const state )
2018fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
2019fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    return state->array_state->active_texture_unit;
2020fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
2021fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2022fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2023fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
2024fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXPushArrayState( __GLXattribute * state )
2025fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
2026fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
2027fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_stack_state * stack = & arrays->stack[ (arrays->stack_index * arrays->num_arrays)];
2028fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
2029fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2030fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2031fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
2032fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].data = arrays->arrays[i].data;
2033fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].data_type = arrays->arrays[i].data_type;
2034fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].user_stride = arrays->arrays[i].user_stride;
2035fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].count = arrays->arrays[i].count;
2036fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].key = arrays->arrays[i].key;
2037fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	stack[i].enabled = arrays->arrays[i].enabled;
2038fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
2039fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2040fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit_stack[ arrays->stack_index ] =
2041fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick      arrays->active_texture_unit;
2042fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2043fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack_index++;
2044fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
2045fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2046fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2047fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanickvoid
2048fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick__glXPopArrayState( __GLXattribute * state )
2049fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick{
2050fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_state_vector * arrays = state->array_state;
2051fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    struct array_stack_state * stack;
2052fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    unsigned  i;
2053fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2054fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2055fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->stack_index--;
2056fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    stack = & arrays->stack[ (arrays->stack_index * arrays->num_arrays) ];
2057fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2058fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
2059fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	switch ( stack[i].key ) {
2060fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_NORMAL_ARRAY:
2061fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glNormalPointer( stack[i].data_type,
2062fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					stack[i].user_stride,
2063fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					stack[i].data );
2064fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2065fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_COLOR_ARRAY:
2066fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glColorPointer( stack[i].count,
2067fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].data_type,
2068fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].user_stride,
2069fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].data );
2070fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2071fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_INDEX_ARRAY:
2072fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glIndexPointer( stack[i].data_type,
2073fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].user_stride,
2074fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick				       stack[i].data );
2075fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2076fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_EDGE_FLAG_ARRAY:
2077fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glEdgeFlagPointer( stack[i].user_stride,
2078fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].data );
2079fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2080fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_TEXTURE_COORD_ARRAY:
2081fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    arrays->active_texture_unit = stack[i].index;
2082fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glTexCoordPointer( stack[i].count,
2083fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].data_type,
2084fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].user_stride,
2085fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					  stack[i].data );
2086fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2087fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_SECONDARY_COLOR_ARRAY:
2088fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glSecondaryColorPointerEXT( stack[i].count,
2089fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						   stack[i].data_type,
2090fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						   stack[i].user_stride,
2091fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick						   stack[i].data );
2092fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2093fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	case GL_FOG_COORDINATE_ARRAY:
2094fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    __indirect_glFogCoordPointerEXT( stack[i].data_type,
2095fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					     stack[i].user_stride,
2096fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick					     stack[i].data );
2097fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	    break;
2098fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2099fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	}
2100fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2101fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick	__glXSetArrayEnable( state, stack[i].key, stack[i].index,
2102fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick			     stack[i].enabled );
2103fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    }
2104fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick
2105fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick    arrays->active_texture_unit = arrays->active_texture_unit_stack[ arrays->stack_index ];
2106fdb07636f2e6324c5250cd5ee97778b7f5933beaIan Romanick}
2107