xref: /aosp_15_r20/external/mesa3d/src/glx/indirect_vertex_array.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * (C) Copyright IBM Corporation 2004, 2005
3*61046927SAndroid Build Coastguard Worker  * All Rights Reserved.
4*61046927SAndroid Build Coastguard Worker  *
5*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
6*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
7*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
8*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sub license,
9*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
10*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
11*61046927SAndroid Build Coastguard Worker  *
12*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
13*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
14*61046927SAndroid Build Coastguard Worker  * Software.
15*61046927SAndroid Build Coastguard Worker  *
16*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker  * IBM,
20*61046927SAndroid Build Coastguard Worker  * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21*61046927SAndroid Build Coastguard Worker  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22*61046927SAndroid Build Coastguard Worker  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23*61046927SAndroid Build Coastguard Worker  * SOFTWARE.
24*61046927SAndroid Build Coastguard Worker  */
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include <inttypes.h>
27*61046927SAndroid Build Coastguard Worker #include <assert.h>
28*61046927SAndroid Build Coastguard Worker #include <string.h>
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker #include "util/compiler.h"
31*61046927SAndroid Build Coastguard Worker 
32*61046927SAndroid Build Coastguard Worker #include "glxclient.h"
33*61046927SAndroid Build Coastguard Worker #include "indirect.h"
34*61046927SAndroid Build Coastguard Worker #include <GL/glxproto.h>
35*61046927SAndroid Build Coastguard Worker #include "glxextensions.h"
36*61046927SAndroid Build Coastguard Worker #include "indirect_vertex_array.h"
37*61046927SAndroid Build Coastguard Worker #include "indirect_vertex_array_priv.h"
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker #define __GLX_PAD(n) (((n)+3) & ~3)
40*61046927SAndroid Build Coastguard Worker 
41*61046927SAndroid Build Coastguard Worker /**
42*61046927SAndroid Build Coastguard Worker  * \file indirect_vertex_array.c
43*61046927SAndroid Build Coastguard Worker  * Implement GLX protocol for vertex arrays and vertex buffer objects.
44*61046927SAndroid Build Coastguard Worker  *
45*61046927SAndroid Build Coastguard Worker  * The most important function in this fill is \c fill_array_info_cache.
46*61046927SAndroid Build Coastguard Worker  * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
47*61046927SAndroid Build Coastguard Worker  * in the DrawArrays protocol.  Certain operations, such as enabling or
48*61046927SAndroid Build Coastguard Worker  * disabling an array, can invalidate this cache.  \c fill_array_info_cache
49*61046927SAndroid Build Coastguard Worker  * fills-in this data.  Additionally, it examines the enabled state and
50*61046927SAndroid Build Coastguard Worker  * other factors to determine what "version" of DrawArrays protocoal can be
51*61046927SAndroid Build Coastguard Worker  * used.
52*61046927SAndroid Build Coastguard Worker  *
53*61046927SAndroid Build Coastguard Worker  * Current, only two versions of DrawArrays protocol are implemented.  The
54*61046927SAndroid Build Coastguard Worker  * first version is the "none" protocol.  This is the fallback when the
55*61046927SAndroid Build Coastguard Worker  * server does not support GL 1.1 / EXT_vertex_arrays.  It is implemented
56*61046927SAndroid Build Coastguard Worker  * by sending batches of immediate mode commands that are equivalent to the
57*61046927SAndroid Build Coastguard Worker  * DrawArrays protocol.
58*61046927SAndroid Build Coastguard Worker  *
59*61046927SAndroid Build Coastguard Worker  * The other protocol that is currently implemented is the "old" protocol.
60*61046927SAndroid Build Coastguard Worker  * This is the GL 1.1 DrawArrays protocol.  The only difference between GL
61*61046927SAndroid Build Coastguard Worker  * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
62*61046927SAndroid Build Coastguard Worker  * This protocol is called "old" because the ARB is in the process of
63*61046927SAndroid Build Coastguard Worker  * defining a new protocol, which will probably be called either "new" or
64*61046927SAndroid Build Coastguard Worker  * "vbo", to support multiple texture coordinate arrays, generic attributes,
65*61046927SAndroid Build Coastguard Worker  * and vertex buffer objects.
66*61046927SAndroid Build Coastguard Worker  *
67*61046927SAndroid Build Coastguard Worker  * \author Ian Romanick <[email protected]>
68*61046927SAndroid Build Coastguard Worker  */
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count);
71*61046927SAndroid Build Coastguard Worker static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
74*61046927SAndroid Build Coastguard Worker                                    const GLvoid * indices);
75*61046927SAndroid Build Coastguard Worker static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
76*61046927SAndroid Build Coastguard Worker                                   const GLvoid * indices);
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker 
79*61046927SAndroid Build Coastguard Worker static GLubyte *emit_element_none(GLubyte * dst,
80*61046927SAndroid Build Coastguard Worker                                   const struct array_state_vector *arrays,
81*61046927SAndroid Build Coastguard Worker                                   unsigned index);
82*61046927SAndroid Build Coastguard Worker static GLubyte *emit_element_old(GLubyte * dst,
83*61046927SAndroid Build Coastguard Worker                                  const struct array_state_vector *arrays,
84*61046927SAndroid Build Coastguard Worker                                  unsigned index);
85*61046927SAndroid Build Coastguard Worker static struct array_state *get_array_entry(const struct array_state_vector
86*61046927SAndroid Build Coastguard Worker                                            *arrays, GLenum key,
87*61046927SAndroid Build Coastguard Worker                                            unsigned index);
88*61046927SAndroid Build Coastguard Worker static void fill_array_info_cache(struct array_state_vector *arrays);
89*61046927SAndroid Build Coastguard Worker static GLboolean validate_mode(struct glx_context * gc, GLenum mode);
90*61046927SAndroid Build Coastguard Worker static GLboolean validate_count(struct glx_context * gc, GLsizei count);
91*61046927SAndroid Build Coastguard Worker static GLboolean validate_type(struct glx_context * gc, GLenum type);
92*61046927SAndroid Build Coastguard Worker 
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker /**
95*61046927SAndroid Build Coastguard Worker  * Table of sizes, in bytes, of a GL types.  All of the type enums are be in
96*61046927SAndroid Build Coastguard Worker  * the range 0x1400 - 0x140F.  That includes types added by extensions (i.e.,
97*61046927SAndroid Build Coastguard Worker  * \c GL_HALF_FLOAT_NV).  This elements of this table correspond to the
98*61046927SAndroid Build Coastguard Worker  * type enums masked with 0x0f.
99*61046927SAndroid Build Coastguard Worker  *
100*61046927SAndroid Build Coastguard Worker  * \notes
101*61046927SAndroid Build Coastguard Worker  * \c GL_HALF_FLOAT_NV is not included.  Neither are \c GL_2_BYTES,
102*61046927SAndroid Build Coastguard Worker  * \c GL_3_BYTES, or \c GL_4_BYTES.
103*61046927SAndroid Build Coastguard Worker  */
104*61046927SAndroid Build Coastguard Worker const GLuint __glXTypeSize_table[16] = {
105*61046927SAndroid Build Coastguard Worker    1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
106*61046927SAndroid Build Coastguard Worker };
107*61046927SAndroid Build Coastguard Worker 
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker /**
110*61046927SAndroid Build Coastguard Worker  * Free the per-context array state that was allocated with
111*61046927SAndroid Build Coastguard Worker  * __glXInitVertexArrayState().
112*61046927SAndroid Build Coastguard Worker  */
113*61046927SAndroid Build Coastguard Worker void
__glXFreeVertexArrayState(struct glx_context * gc)114*61046927SAndroid Build Coastguard Worker __glXFreeVertexArrayState(struct glx_context * gc)
115*61046927SAndroid Build Coastguard Worker {
116*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
117*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    if (arrays) {
120*61046927SAndroid Build Coastguard Worker       free(arrays->stack);
121*61046927SAndroid Build Coastguard Worker       arrays->stack = NULL;
122*61046927SAndroid Build Coastguard Worker       free(arrays->arrays);
123*61046927SAndroid Build Coastguard Worker       arrays->arrays = NULL;
124*61046927SAndroid Build Coastguard Worker       free(arrays);
125*61046927SAndroid Build Coastguard Worker       state->array_state = NULL;
126*61046927SAndroid Build Coastguard Worker    }
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker 
129*61046927SAndroid Build Coastguard Worker 
130*61046927SAndroid Build Coastguard Worker /**
131*61046927SAndroid Build Coastguard Worker  * Initialize vertex array state of a GLX context.
132*61046927SAndroid Build Coastguard Worker  *
133*61046927SAndroid Build Coastguard Worker  * \param gc  GLX context whose vertex array state is to be initialized.
134*61046927SAndroid Build Coastguard Worker  *
135*61046927SAndroid Build Coastguard Worker  * \warning
136*61046927SAndroid Build Coastguard Worker  * This function may only be called after struct glx_context::gl_extension_bits,
137*61046927SAndroid Build Coastguard Worker  * struct glx_context::server_minor, and __GLXcontext::server_major have been
138*61046927SAndroid Build Coastguard Worker  * initialized.  These values are used to determine what vertex arrays are
139*61046927SAndroid Build Coastguard Worker  * supported.
140*61046927SAndroid Build Coastguard Worker  */
141*61046927SAndroid Build Coastguard Worker void
__glXInitVertexArrayState(struct glx_context * gc)142*61046927SAndroid Build Coastguard Worker __glXInitVertexArrayState(struct glx_context * gc)
143*61046927SAndroid Build Coastguard Worker {
144*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
145*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays;
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker    unsigned array_count;
148*61046927SAndroid Build Coastguard Worker    int texture_units = 1, vertex_program_attribs = 0;
149*61046927SAndroid Build Coastguard Worker    unsigned i, j;
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker    GLboolean got_fog = GL_FALSE;
152*61046927SAndroid Build Coastguard Worker    GLboolean got_secondary_color = GL_FALSE;
153*61046927SAndroid Build Coastguard Worker 
154*61046927SAndroid Build Coastguard Worker 
155*61046927SAndroid Build Coastguard Worker    arrays = calloc(1, sizeof(struct array_state_vector));
156*61046927SAndroid Build Coastguard Worker    state->array_state = arrays;
157*61046927SAndroid Build Coastguard Worker 
158*61046927SAndroid Build Coastguard Worker    if (arrays == NULL) {
159*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_OUT_OF_MEMORY);
160*61046927SAndroid Build Coastguard Worker       return;
161*61046927SAndroid Build Coastguard Worker    }
162*61046927SAndroid Build Coastguard Worker 
163*61046927SAndroid Build Coastguard Worker    arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
164*61046927SAndroid Build Coastguard Worker    arrays->new_DrawArrays_possible = GL_FALSE;
165*61046927SAndroid Build Coastguard Worker    arrays->DrawArrays = NULL;
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker    arrays->active_texture_unit = 0;
168*61046927SAndroid Build Coastguard Worker 
169*61046927SAndroid Build Coastguard Worker 
170*61046927SAndroid Build Coastguard Worker    /* Determine how many arrays are actually needed.  Only arrays that
171*61046927SAndroid Build Coastguard Worker     * are supported by the server are create.  For example, if the server
172*61046927SAndroid Build Coastguard Worker     * supports only 2 texture units, then only 2 texture coordinate arrays
173*61046927SAndroid Build Coastguard Worker     * are created.
174*61046927SAndroid Build Coastguard Worker     *
175*61046927SAndroid Build Coastguard Worker     * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
176*61046927SAndroid Build Coastguard Worker     * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
177*61046927SAndroid Build Coastguard Worker     * GL_EDGE_FLAG_ARRAY are supported.
178*61046927SAndroid Build Coastguard Worker     */
179*61046927SAndroid Build Coastguard Worker 
180*61046927SAndroid Build Coastguard Worker    array_count = 5;
181*61046927SAndroid Build Coastguard Worker 
182*61046927SAndroid Build Coastguard Worker    if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
183*61046927SAndroid Build Coastguard Worker        || (gc->server_major > 1) || (gc->server_minor >= 4)) {
184*61046927SAndroid Build Coastguard Worker       got_fog = GL_TRUE;
185*61046927SAndroid Build Coastguard Worker       array_count++;
186*61046927SAndroid Build Coastguard Worker    }
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker    if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
189*61046927SAndroid Build Coastguard Worker        || (gc->server_major > 1) || (gc->server_minor >= 4)) {
190*61046927SAndroid Build Coastguard Worker       got_secondary_color = GL_TRUE;
191*61046927SAndroid Build Coastguard Worker       array_count++;
192*61046927SAndroid Build Coastguard Worker    }
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker    if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit)
195*61046927SAndroid Build Coastguard Worker        || (gc->server_major > 1) || (gc->server_minor >= 3)) {
196*61046927SAndroid Build Coastguard Worker       __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
197*61046927SAndroid Build Coastguard Worker    }
198*61046927SAndroid Build Coastguard Worker 
199*61046927SAndroid Build Coastguard Worker    if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) {
200*61046927SAndroid Build Coastguard Worker       __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
201*61046927SAndroid Build Coastguard Worker                                    GL_MAX_PROGRAM_ATTRIBS_ARB,
202*61046927SAndroid Build Coastguard Worker                                    &vertex_program_attribs);
203*61046927SAndroid Build Coastguard Worker    }
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker    arrays->num_texture_units = texture_units;
206*61046927SAndroid Build Coastguard Worker    arrays->num_vertex_program_attribs = vertex_program_attribs;
207*61046927SAndroid Build Coastguard Worker    array_count += texture_units + vertex_program_attribs;
208*61046927SAndroid Build Coastguard Worker    arrays->num_arrays = array_count;
209*61046927SAndroid Build Coastguard Worker    arrays->arrays = calloc(array_count, sizeof(struct array_state));
210*61046927SAndroid Build Coastguard Worker 
211*61046927SAndroid Build Coastguard Worker    if (arrays->arrays == NULL) {
212*61046927SAndroid Build Coastguard Worker       state->array_state = NULL;
213*61046927SAndroid Build Coastguard Worker       free(arrays);
214*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_OUT_OF_MEMORY);
215*61046927SAndroid Build Coastguard Worker       return;
216*61046927SAndroid Build Coastguard Worker    }
217*61046927SAndroid Build Coastguard Worker 
218*61046927SAndroid Build Coastguard Worker    arrays->arrays[0].data_type = GL_FLOAT;
219*61046927SAndroid Build Coastguard Worker    arrays->arrays[0].count = 3;
220*61046927SAndroid Build Coastguard Worker    arrays->arrays[0].key = GL_NORMAL_ARRAY;
221*61046927SAndroid Build Coastguard Worker    arrays->arrays[0].normalized = GL_TRUE;
222*61046927SAndroid Build Coastguard Worker    arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
223*61046927SAndroid Build Coastguard Worker 
224*61046927SAndroid Build Coastguard Worker    arrays->arrays[1].data_type = GL_FLOAT;
225*61046927SAndroid Build Coastguard Worker    arrays->arrays[1].count = 4;
226*61046927SAndroid Build Coastguard Worker    arrays->arrays[1].key = GL_COLOR_ARRAY;
227*61046927SAndroid Build Coastguard Worker    arrays->arrays[1].normalized = GL_TRUE;
228*61046927SAndroid Build Coastguard Worker    arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
229*61046927SAndroid Build Coastguard Worker 
230*61046927SAndroid Build Coastguard Worker    arrays->arrays[2].data_type = GL_FLOAT;
231*61046927SAndroid Build Coastguard Worker    arrays->arrays[2].count = 1;
232*61046927SAndroid Build Coastguard Worker    arrays->arrays[2].key = GL_INDEX_ARRAY;
233*61046927SAndroid Build Coastguard Worker    arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
236*61046927SAndroid Build Coastguard Worker    arrays->arrays[3].count = 1;
237*61046927SAndroid Build Coastguard Worker    arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
238*61046927SAndroid Build Coastguard Worker    arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
239*61046927SAndroid Build Coastguard Worker 
240*61046927SAndroid Build Coastguard Worker    for (i = 0; i < texture_units; i++) {
241*61046927SAndroid Build Coastguard Worker       arrays->arrays[4 + i].data_type = GL_FLOAT;
242*61046927SAndroid Build Coastguard Worker       arrays->arrays[4 + i].count = 4;
243*61046927SAndroid Build Coastguard Worker       arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker       arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
246*61046927SAndroid Build Coastguard Worker       arrays->arrays[4 + i].index = i;
247*61046927SAndroid Build Coastguard Worker    }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker    i = 4 + texture_units;
250*61046927SAndroid Build Coastguard Worker 
251*61046927SAndroid Build Coastguard Worker    if (got_fog) {
252*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].data_type = GL_FLOAT;
253*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].count = 1;
254*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
255*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
256*61046927SAndroid Build Coastguard Worker       i++;
257*61046927SAndroid Build Coastguard Worker    }
258*61046927SAndroid Build Coastguard Worker 
259*61046927SAndroid Build Coastguard Worker    if (got_secondary_color) {
260*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].data_type = GL_FLOAT;
261*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].count = 3;
262*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
263*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
264*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].normalized = GL_TRUE;
265*61046927SAndroid Build Coastguard Worker       i++;
266*61046927SAndroid Build Coastguard Worker    }
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker    for (j = 0; j < vertex_program_attribs; j++) {
270*61046927SAndroid Build Coastguard Worker       const unsigned idx = (vertex_program_attribs - (j + 1));
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker       arrays->arrays[idx + i].data_type = GL_FLOAT;
274*61046927SAndroid Build Coastguard Worker       arrays->arrays[idx + i].count = 4;
275*61046927SAndroid Build Coastguard Worker       arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker       arrays->arrays[idx + i].old_DrawArrays_possible = 0;
278*61046927SAndroid Build Coastguard Worker       arrays->arrays[idx + i].index = idx;
279*61046927SAndroid Build Coastguard Worker    }
280*61046927SAndroid Build Coastguard Worker 
281*61046927SAndroid Build Coastguard Worker    i += vertex_program_attribs;
282*61046927SAndroid Build Coastguard Worker 
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker    /* Vertex array *must* be last because of the way that
285*61046927SAndroid Build Coastguard Worker     * emit_DrawArrays_none works.
286*61046927SAndroid Build Coastguard Worker     */
287*61046927SAndroid Build Coastguard Worker 
288*61046927SAndroid Build Coastguard Worker    arrays->arrays[i].data_type = GL_FLOAT;
289*61046927SAndroid Build Coastguard Worker    arrays->arrays[i].count = 4;
290*61046927SAndroid Build Coastguard Worker    arrays->arrays[i].key = GL_VERTEX_ARRAY;
291*61046927SAndroid Build Coastguard Worker    arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
292*61046927SAndroid Build Coastguard Worker 
293*61046927SAndroid Build Coastguard Worker    assert((i + 1) == arrays->num_arrays);
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    arrays->stack_index = 0;
296*61046927SAndroid Build Coastguard Worker    arrays->stack = malloc(sizeof(struct array_stack_state)
297*61046927SAndroid Build Coastguard Worker                           * arrays->num_arrays
298*61046927SAndroid Build Coastguard Worker                           * __GL_CLIENT_ATTRIB_STACK_DEPTH);
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker    if (arrays->stack == NULL) {
301*61046927SAndroid Build Coastguard Worker       state->array_state = NULL;
302*61046927SAndroid Build Coastguard Worker       free(arrays->arrays);
303*61046927SAndroid Build Coastguard Worker       free(arrays);
304*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_OUT_OF_MEMORY);
305*61046927SAndroid Build Coastguard Worker       return;
306*61046927SAndroid Build Coastguard Worker    }
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker 
310*61046927SAndroid Build Coastguard Worker /**
311*61046927SAndroid Build Coastguard Worker  * Calculate the size of a single vertex for the "none" protocol.  This is
312*61046927SAndroid Build Coastguard Worker  * essentially the size of all the immediate-mode commands required to
313*61046927SAndroid Build Coastguard Worker  * implement the enabled vertex arrays.
314*61046927SAndroid Build Coastguard Worker  */
315*61046927SAndroid Build Coastguard Worker static size_t
calculate_single_vertex_size_none(const struct array_state_vector * arrays)316*61046927SAndroid Build Coastguard Worker calculate_single_vertex_size_none(const struct array_state_vector *arrays)
317*61046927SAndroid Build Coastguard Worker {
318*61046927SAndroid Build Coastguard Worker    size_t single_vertex_size = 0;
319*61046927SAndroid Build Coastguard Worker    unsigned i;
320*61046927SAndroid Build Coastguard Worker 
321*61046927SAndroid Build Coastguard Worker 
322*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
323*61046927SAndroid Build Coastguard Worker       if (arrays->arrays[i].enabled) {
324*61046927SAndroid Build Coastguard Worker          single_vertex_size += arrays->arrays[i].header[0];
325*61046927SAndroid Build Coastguard Worker       }
326*61046927SAndroid Build Coastguard Worker    }
327*61046927SAndroid Build Coastguard Worker 
328*61046927SAndroid Build Coastguard Worker    return single_vertex_size;
329*61046927SAndroid Build Coastguard Worker }
330*61046927SAndroid Build Coastguard Worker 
331*61046927SAndroid Build Coastguard Worker 
332*61046927SAndroid Build Coastguard Worker /**
333*61046927SAndroid Build Coastguard Worker  * Emit a single element using non-DrawArrays protocol.
334*61046927SAndroid Build Coastguard Worker  */
335*61046927SAndroid Build Coastguard Worker GLubyte *
emit_element_none(GLubyte * dst,const struct array_state_vector * arrays,unsigned index)336*61046927SAndroid Build Coastguard Worker emit_element_none(GLubyte * dst,
337*61046927SAndroid Build Coastguard Worker                   const struct array_state_vector * arrays, unsigned index)
338*61046927SAndroid Build Coastguard Worker {
339*61046927SAndroid Build Coastguard Worker    unsigned i;
340*61046927SAndroid Build Coastguard Worker 
341*61046927SAndroid Build Coastguard Worker 
342*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
343*61046927SAndroid Build Coastguard Worker       if (arrays->arrays[i].enabled) {
344*61046927SAndroid Build Coastguard Worker          const size_t offset = index * arrays->arrays[i].true_stride;
345*61046927SAndroid Build Coastguard Worker 
346*61046927SAndroid Build Coastguard Worker          /* The generic attributes can have more data than is in the
347*61046927SAndroid Build Coastguard Worker           * elements.  This is because a vertex array can be a 2 element,
348*61046927SAndroid Build Coastguard Worker           * normalized, unsigned short, but the "closest" immediate mode
349*61046927SAndroid Build Coastguard Worker           * protocol is for a 4Nus.  Since the sizes are small, the
350*61046927SAndroid Build Coastguard Worker           * performance impact on modern processors should be negligible.
351*61046927SAndroid Build Coastguard Worker           */
352*61046927SAndroid Build Coastguard Worker          (void) memset(dst, 0, arrays->arrays[i].header[0]);
353*61046927SAndroid Build Coastguard Worker 
354*61046927SAndroid Build Coastguard Worker          (void) memcpy(dst, arrays->arrays[i].header, 4);
355*61046927SAndroid Build Coastguard Worker 
356*61046927SAndroid Build Coastguard Worker          dst += 4;
357*61046927SAndroid Build Coastguard Worker 
358*61046927SAndroid Build Coastguard Worker          if (arrays->arrays[i].key == GL_TEXTURE_COORD_ARRAY &&
359*61046927SAndroid Build Coastguard Worker              arrays->arrays[i].index > 0) {
360*61046927SAndroid Build Coastguard Worker             /* Multi-texture coordinate arrays require the texture target
361*61046927SAndroid Build Coastguard Worker              * to be sent.  For doubles it is after the data, for everything
362*61046927SAndroid Build Coastguard Worker              * else it is before.
363*61046927SAndroid Build Coastguard Worker              */
364*61046927SAndroid Build Coastguard Worker             GLenum texture = arrays->arrays[i].index + GL_TEXTURE0;
365*61046927SAndroid Build Coastguard Worker             if (arrays->arrays[i].data_type == GL_DOUBLE) {
366*61046927SAndroid Build Coastguard Worker                (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
367*61046927SAndroid Build Coastguard Worker                              arrays->arrays[i].element_size);
368*61046927SAndroid Build Coastguard Worker                dst += arrays->arrays[i].element_size;
369*61046927SAndroid Build Coastguard Worker                (void) memcpy(dst, &texture, 4);
370*61046927SAndroid Build Coastguard Worker                dst += 4;
371*61046927SAndroid Build Coastguard Worker             } else {
372*61046927SAndroid Build Coastguard Worker                (void) memcpy(dst, &texture, 4);
373*61046927SAndroid Build Coastguard Worker                dst += 4;
374*61046927SAndroid Build Coastguard Worker                (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
375*61046927SAndroid Build Coastguard Worker                              arrays->arrays[i].element_size);
376*61046927SAndroid Build Coastguard Worker                dst += __GLX_PAD(arrays->arrays[i].element_size);
377*61046927SAndroid Build Coastguard Worker             }
378*61046927SAndroid Build Coastguard Worker          } else if (arrays->arrays[i].key == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
379*61046927SAndroid Build Coastguard Worker             /* Vertex attribute data requires the index sent first.
380*61046927SAndroid Build Coastguard Worker              */
381*61046927SAndroid Build Coastguard Worker             (void) memcpy(dst, &arrays->arrays[i].index, 4);
382*61046927SAndroid Build Coastguard Worker             dst += 4;
383*61046927SAndroid Build Coastguard Worker             (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
384*61046927SAndroid Build Coastguard Worker                           arrays->arrays[i].element_size);
385*61046927SAndroid Build Coastguard Worker             dst += __GLX_PAD(arrays->arrays[i].element_size);
386*61046927SAndroid Build Coastguard Worker          } else {
387*61046927SAndroid Build Coastguard Worker             (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
388*61046927SAndroid Build Coastguard Worker                           arrays->arrays[i].element_size);
389*61046927SAndroid Build Coastguard Worker             dst += __GLX_PAD(arrays->arrays[i].element_size);
390*61046927SAndroid Build Coastguard Worker          }
391*61046927SAndroid Build Coastguard Worker       }
392*61046927SAndroid Build Coastguard Worker    }
393*61046927SAndroid Build Coastguard Worker 
394*61046927SAndroid Build Coastguard Worker    return dst;
395*61046927SAndroid Build Coastguard Worker }
396*61046927SAndroid Build Coastguard Worker 
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker /**
399*61046927SAndroid Build Coastguard Worker  * Emit a single element using "old" DrawArrays protocol from
400*61046927SAndroid Build Coastguard Worker  * EXT_vertex_arrays / OpenGL 1.1.
401*61046927SAndroid Build Coastguard Worker  */
402*61046927SAndroid Build Coastguard Worker GLubyte *
emit_element_old(GLubyte * dst,const struct array_state_vector * arrays,unsigned index)403*61046927SAndroid Build Coastguard Worker emit_element_old(GLubyte * dst,
404*61046927SAndroid Build Coastguard Worker                  const struct array_state_vector * arrays, unsigned index)
405*61046927SAndroid Build Coastguard Worker {
406*61046927SAndroid Build Coastguard Worker    unsigned i;
407*61046927SAndroid Build Coastguard Worker 
408*61046927SAndroid Build Coastguard Worker 
409*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
410*61046927SAndroid Build Coastguard Worker       if (arrays->arrays[i].enabled) {
411*61046927SAndroid Build Coastguard Worker          const size_t offset = index * arrays->arrays[i].true_stride;
412*61046927SAndroid Build Coastguard Worker 
413*61046927SAndroid Build Coastguard Worker          (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
414*61046927SAndroid Build Coastguard Worker                        arrays->arrays[i].element_size);
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker          dst += __GLX_PAD(arrays->arrays[i].element_size);
417*61046927SAndroid Build Coastguard Worker       }
418*61046927SAndroid Build Coastguard Worker    }
419*61046927SAndroid Build Coastguard Worker 
420*61046927SAndroid Build Coastguard Worker    return dst;
421*61046927SAndroid Build Coastguard Worker }
422*61046927SAndroid Build Coastguard Worker 
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker struct array_state *
get_array_entry(const struct array_state_vector * arrays,GLenum key,unsigned index)425*61046927SAndroid Build Coastguard Worker get_array_entry(const struct array_state_vector *arrays,
426*61046927SAndroid Build Coastguard Worker                 GLenum key, unsigned index)
427*61046927SAndroid Build Coastguard Worker {
428*61046927SAndroid Build Coastguard Worker    unsigned i;
429*61046927SAndroid Build Coastguard Worker 
430*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
431*61046927SAndroid Build Coastguard Worker       if ((arrays->arrays[i].key == key)
432*61046927SAndroid Build Coastguard Worker           && (arrays->arrays[i].index == index)) {
433*61046927SAndroid Build Coastguard Worker          return &arrays->arrays[i];
434*61046927SAndroid Build Coastguard Worker       }
435*61046927SAndroid Build Coastguard Worker    }
436*61046927SAndroid Build Coastguard Worker 
437*61046927SAndroid Build Coastguard Worker    return NULL;
438*61046927SAndroid Build Coastguard Worker }
439*61046927SAndroid Build Coastguard Worker 
440*61046927SAndroid Build Coastguard Worker 
441*61046927SAndroid Build Coastguard Worker static GLboolean
allocate_array_info_cache(struct array_state_vector * arrays,size_t required_size)442*61046927SAndroid Build Coastguard Worker allocate_array_info_cache(struct array_state_vector *arrays,
443*61046927SAndroid Build Coastguard Worker                           size_t required_size)
444*61046927SAndroid Build Coastguard Worker {
445*61046927SAndroid Build Coastguard Worker #define MAX_HEADER_SIZE 20
446*61046927SAndroid Build Coastguard Worker    if (arrays->array_info_cache_buffer_size < required_size) {
447*61046927SAndroid Build Coastguard Worker       GLubyte *temp = realloc(arrays->array_info_cache_base,
448*61046927SAndroid Build Coastguard Worker                               required_size + MAX_HEADER_SIZE);
449*61046927SAndroid Build Coastguard Worker 
450*61046927SAndroid Build Coastguard Worker       if (temp == NULL) {
451*61046927SAndroid Build Coastguard Worker          return GL_FALSE;
452*61046927SAndroid Build Coastguard Worker       }
453*61046927SAndroid Build Coastguard Worker 
454*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_base = temp;
455*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache = temp + MAX_HEADER_SIZE;
456*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_buffer_size = required_size;
457*61046927SAndroid Build Coastguard Worker    }
458*61046927SAndroid Build Coastguard Worker 
459*61046927SAndroid Build Coastguard Worker    arrays->array_info_cache_size = required_size;
460*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
461*61046927SAndroid Build Coastguard Worker }
462*61046927SAndroid Build Coastguard Worker 
463*61046927SAndroid Build Coastguard Worker 
464*61046927SAndroid Build Coastguard Worker /**
465*61046927SAndroid Build Coastguard Worker  */
466*61046927SAndroid Build Coastguard Worker void
fill_array_info_cache(struct array_state_vector * arrays)467*61046927SAndroid Build Coastguard Worker fill_array_info_cache(struct array_state_vector *arrays)
468*61046927SAndroid Build Coastguard Worker {
469*61046927SAndroid Build Coastguard Worker    GLboolean old_DrawArrays_possible;
470*61046927SAndroid Build Coastguard Worker    unsigned i;
471*61046927SAndroid Build Coastguard Worker 
472*61046927SAndroid Build Coastguard Worker 
473*61046927SAndroid Build Coastguard Worker    /* Determine how many arrays are enabled.
474*61046927SAndroid Build Coastguard Worker     */
475*61046927SAndroid Build Coastguard Worker 
476*61046927SAndroid Build Coastguard Worker    arrays->enabled_client_array_count = 0;
477*61046927SAndroid Build Coastguard Worker    old_DrawArrays_possible = arrays->old_DrawArrays_possible;
478*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
479*61046927SAndroid Build Coastguard Worker       if (arrays->arrays[i].enabled) {
480*61046927SAndroid Build Coastguard Worker          arrays->enabled_client_array_count++;
481*61046927SAndroid Build Coastguard Worker          old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
482*61046927SAndroid Build Coastguard Worker       }
483*61046927SAndroid Build Coastguard Worker    }
484*61046927SAndroid Build Coastguard Worker 
485*61046927SAndroid Build Coastguard Worker    if (arrays->new_DrawArrays_possible) {
486*61046927SAndroid Build Coastguard Worker       assert(!arrays->new_DrawArrays_possible);
487*61046927SAndroid Build Coastguard Worker    }
488*61046927SAndroid Build Coastguard Worker    else if (old_DrawArrays_possible) {
489*61046927SAndroid Build Coastguard Worker       const size_t required_size = arrays->enabled_client_array_count * 12;
490*61046927SAndroid Build Coastguard Worker       uint32_t *info;
491*61046927SAndroid Build Coastguard Worker 
492*61046927SAndroid Build Coastguard Worker 
493*61046927SAndroid Build Coastguard Worker       if (!allocate_array_info_cache(arrays, required_size)) {
494*61046927SAndroid Build Coastguard Worker          return;
495*61046927SAndroid Build Coastguard Worker       }
496*61046927SAndroid Build Coastguard Worker 
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker       info = (uint32_t *) arrays->array_info_cache;
499*61046927SAndroid Build Coastguard Worker       for (i = 0; i < arrays->num_arrays; i++) {
500*61046927SAndroid Build Coastguard Worker          if (arrays->arrays[i].enabled) {
501*61046927SAndroid Build Coastguard Worker             *(info++) = arrays->arrays[i].data_type;
502*61046927SAndroid Build Coastguard Worker             *(info++) = arrays->arrays[i].count;
503*61046927SAndroid Build Coastguard Worker             *(info++) = arrays->arrays[i].key;
504*61046927SAndroid Build Coastguard Worker          }
505*61046927SAndroid Build Coastguard Worker       }
506*61046927SAndroid Build Coastguard Worker 
507*61046927SAndroid Build Coastguard Worker       arrays->DrawArrays = emit_DrawArrays_old;
508*61046927SAndroid Build Coastguard Worker       arrays->DrawElements = emit_DrawElements_old;
509*61046927SAndroid Build Coastguard Worker    }
510*61046927SAndroid Build Coastguard Worker    else {
511*61046927SAndroid Build Coastguard Worker       arrays->DrawArrays = emit_DrawArrays_none;
512*61046927SAndroid Build Coastguard Worker       arrays->DrawElements = emit_DrawElements_none;
513*61046927SAndroid Build Coastguard Worker    }
514*61046927SAndroid Build Coastguard Worker 
515*61046927SAndroid Build Coastguard Worker    arrays->array_info_cache_valid = GL_TRUE;
516*61046927SAndroid Build Coastguard Worker }
517*61046927SAndroid Build Coastguard Worker 
518*61046927SAndroid Build Coastguard Worker 
519*61046927SAndroid Build Coastguard Worker /**
520*61046927SAndroid Build Coastguard Worker  * Emit a \c glDrawArrays command using the "none" protocol.  That is,
521*61046927SAndroid Build Coastguard Worker  * emit immediate-mode commands that are equivalent to the requested
522*61046927SAndroid Build Coastguard Worker  * \c glDrawArrays command.  This is used with servers that don't support
523*61046927SAndroid Build Coastguard Worker  * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
524*61046927SAndroid Build Coastguard Worker  * vertex state is enabled that is not compatible with that protocol.
525*61046927SAndroid Build Coastguard Worker  */
526*61046927SAndroid Build Coastguard Worker void
emit_DrawArrays_none(GLenum mode,GLint first,GLsizei count)527*61046927SAndroid Build Coastguard Worker emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
528*61046927SAndroid Build Coastguard Worker {
529*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
530*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
531*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
532*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
533*61046927SAndroid Build Coastguard Worker 
534*61046927SAndroid Build Coastguard Worker    size_t single_vertex_size;
535*61046927SAndroid Build Coastguard Worker    GLubyte *pc;
536*61046927SAndroid Build Coastguard Worker    unsigned i;
537*61046927SAndroid Build Coastguard Worker    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
538*61046927SAndroid Build Coastguard Worker    static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
539*61046927SAndroid Build Coastguard Worker 
540*61046927SAndroid Build Coastguard Worker 
541*61046927SAndroid Build Coastguard Worker    single_vertex_size = calculate_single_vertex_size_none(arrays);
542*61046927SAndroid Build Coastguard Worker 
543*61046927SAndroid Build Coastguard Worker    pc = gc->pc;
544*61046927SAndroid Build Coastguard Worker 
545*61046927SAndroid Build Coastguard Worker    (void) memcpy(pc, begin_cmd, 4);
546*61046927SAndroid Build Coastguard Worker    *(int *) (pc + 4) = mode;
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    pc += 8;
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker    for (i = 0; i < count; i++) {
551*61046927SAndroid Build Coastguard Worker       if ((pc + single_vertex_size) >= gc->bufEnd) {
552*61046927SAndroid Build Coastguard Worker          pc = __glXFlushRenderBuffer(gc, pc);
553*61046927SAndroid Build Coastguard Worker       }
554*61046927SAndroid Build Coastguard Worker 
555*61046927SAndroid Build Coastguard Worker       pc = emit_element_none(pc, arrays, first + i);
556*61046927SAndroid Build Coastguard Worker    }
557*61046927SAndroid Build Coastguard Worker 
558*61046927SAndroid Build Coastguard Worker    if ((pc + 4) >= gc->bufEnd) {
559*61046927SAndroid Build Coastguard Worker       pc = __glXFlushRenderBuffer(gc, pc);
560*61046927SAndroid Build Coastguard Worker    }
561*61046927SAndroid Build Coastguard Worker 
562*61046927SAndroid Build Coastguard Worker    (void) memcpy(pc, end_cmd, 4);
563*61046927SAndroid Build Coastguard Worker    pc += 4;
564*61046927SAndroid Build Coastguard Worker 
565*61046927SAndroid Build Coastguard Worker    gc->pc = pc;
566*61046927SAndroid Build Coastguard Worker    if (gc->pc > gc->limit) {
567*61046927SAndroid Build Coastguard Worker       (void) __glXFlushRenderBuffer(gc, gc->pc);
568*61046927SAndroid Build Coastguard Worker    }
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker 
571*61046927SAndroid Build Coastguard Worker 
572*61046927SAndroid Build Coastguard Worker /**
573*61046927SAndroid Build Coastguard Worker  * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
574*61046927SAndroid Build Coastguard Worker  * protocol.
575*61046927SAndroid Build Coastguard Worker  *
576*61046927SAndroid Build Coastguard Worker  * \param gc                    GLX context.
577*61046927SAndroid Build Coastguard Worker  * \param arrays                Array state.
578*61046927SAndroid Build Coastguard Worker  * \param elements_per_request  Location to store the number of elements that
579*61046927SAndroid Build Coastguard Worker  *                              can fit in a single Render / RenderLarge
580*61046927SAndroid Build Coastguard Worker  *                              command.
581*61046927SAndroid Build Coastguard Worker  * \param total_request         Total number of requests for a RenderLarge
582*61046927SAndroid Build Coastguard Worker  *                              command.  If a Render command is used, this
583*61046927SAndroid Build Coastguard Worker  *                              will be zero.
584*61046927SAndroid Build Coastguard Worker  * \param mode                  Drawing mode.
585*61046927SAndroid Build Coastguard Worker  * \param count                 Number of vertices.
586*61046927SAndroid Build Coastguard Worker  *
587*61046927SAndroid Build Coastguard Worker  * \returns
588*61046927SAndroid Build Coastguard Worker  * A pointer to the buffer for array data.
589*61046927SAndroid Build Coastguard Worker  */
590*61046927SAndroid Build Coastguard Worker static GLubyte *
emit_DrawArrays_header_old(struct glx_context * gc,struct array_state_vector * arrays,size_t * elements_per_request,unsigned int * total_requests,GLenum mode,GLsizei count)591*61046927SAndroid Build Coastguard Worker emit_DrawArrays_header_old(struct glx_context * gc,
592*61046927SAndroid Build Coastguard Worker                            struct array_state_vector *arrays,
593*61046927SAndroid Build Coastguard Worker                            size_t * elements_per_request,
594*61046927SAndroid Build Coastguard Worker                            unsigned int *total_requests,
595*61046927SAndroid Build Coastguard Worker                            GLenum mode, GLsizei count)
596*61046927SAndroid Build Coastguard Worker {
597*61046927SAndroid Build Coastguard Worker    size_t command_size;
598*61046927SAndroid Build Coastguard Worker    size_t single_vertex_size;
599*61046927SAndroid Build Coastguard Worker    const unsigned header_size = 16;
600*61046927SAndroid Build Coastguard Worker    unsigned i;
601*61046927SAndroid Build Coastguard Worker    GLubyte *pc;
602*61046927SAndroid Build Coastguard Worker 
603*61046927SAndroid Build Coastguard Worker 
604*61046927SAndroid Build Coastguard Worker    /* Determine the size of the whole command.  This includes the header,
605*61046927SAndroid Build Coastguard Worker     * the ARRAY_INFO data and the array data.  Once this size is calculated,
606*61046927SAndroid Build Coastguard Worker     * it will be known whether a Render or RenderLarge command is needed.
607*61046927SAndroid Build Coastguard Worker     */
608*61046927SAndroid Build Coastguard Worker 
609*61046927SAndroid Build Coastguard Worker    single_vertex_size = 0;
610*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
611*61046927SAndroid Build Coastguard Worker       if (arrays->arrays[i].enabled) {
612*61046927SAndroid Build Coastguard Worker          single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
613*61046927SAndroid Build Coastguard Worker       }
614*61046927SAndroid Build Coastguard Worker    }
615*61046927SAndroid Build Coastguard Worker 
616*61046927SAndroid Build Coastguard Worker    command_size = arrays->array_info_cache_size + header_size
617*61046927SAndroid Build Coastguard Worker       + (single_vertex_size * count);
618*61046927SAndroid Build Coastguard Worker 
619*61046927SAndroid Build Coastguard Worker 
620*61046927SAndroid Build Coastguard Worker    /* Write the header for either a Render command or a RenderLarge
621*61046927SAndroid Build Coastguard Worker     * command.  After the header is written, write the ARRAY_INFO data.
622*61046927SAndroid Build Coastguard Worker     */
623*61046927SAndroid Build Coastguard Worker 
624*61046927SAndroid Build Coastguard Worker    if (command_size > gc->maxSmallRenderCommandSize) {
625*61046927SAndroid Build Coastguard Worker       /* maxSize is the maximum amount of data can be stuffed into a single
626*61046927SAndroid Build Coastguard Worker        * packet.  sz_xGLXRenderReq is added because bufSize is the maximum
627*61046927SAndroid Build Coastguard Worker        * packet size minus sz_xGLXRenderReq.
628*61046927SAndroid Build Coastguard Worker        */
629*61046927SAndroid Build Coastguard Worker       const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
630*61046927SAndroid Build Coastguard Worker          - sz_xGLXRenderLargeReq;
631*61046927SAndroid Build Coastguard Worker       unsigned vertex_requests;
632*61046927SAndroid Build Coastguard Worker 
633*61046927SAndroid Build Coastguard Worker 
634*61046927SAndroid Build Coastguard Worker       /* Calculate the number of data packets that will be required to send
635*61046927SAndroid Build Coastguard Worker        * the whole command.  To do this, the number of vertices that
636*61046927SAndroid Build Coastguard Worker        * will fit in a single buffer must be calculated.
637*61046927SAndroid Build Coastguard Worker        *
638*61046927SAndroid Build Coastguard Worker        * The important value here is elements_per_request.  This is the
639*61046927SAndroid Build Coastguard Worker        * number of complete array elements that will fit in a single
640*61046927SAndroid Build Coastguard Worker        * buffer.  There may be some wasted space at the end of the buffer,
641*61046927SAndroid Build Coastguard Worker        * but splitting elements across buffer boundaries would be painful.
642*61046927SAndroid Build Coastguard Worker        */
643*61046927SAndroid Build Coastguard Worker 
644*61046927SAndroid Build Coastguard Worker       elements_per_request[0] = maxSize / single_vertex_size;
645*61046927SAndroid Build Coastguard Worker 
646*61046927SAndroid Build Coastguard Worker       vertex_requests = (count + elements_per_request[0] - 1)
647*61046927SAndroid Build Coastguard Worker          / elements_per_request[0];
648*61046927SAndroid Build Coastguard Worker 
649*61046927SAndroid Build Coastguard Worker       *total_requests = vertex_requests + 1;
650*61046927SAndroid Build Coastguard Worker 
651*61046927SAndroid Build Coastguard Worker 
652*61046927SAndroid Build Coastguard Worker       __glXFlushRenderBuffer(gc, gc->pc);
653*61046927SAndroid Build Coastguard Worker 
654*61046927SAndroid Build Coastguard Worker       command_size += 4;
655*61046927SAndroid Build Coastguard Worker 
656*61046927SAndroid Build Coastguard Worker       pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
657*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 0) = command_size;
658*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
659*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 8) = count;
660*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
661*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 16) = mode;
662*61046927SAndroid Build Coastguard Worker 
663*61046927SAndroid Build Coastguard Worker       __glXSendLargeChunk(gc, 1, *total_requests, pc,
664*61046927SAndroid Build Coastguard Worker                           header_size + 4 + arrays->array_info_cache_size);
665*61046927SAndroid Build Coastguard Worker 
666*61046927SAndroid Build Coastguard Worker       pc = gc->pc;
667*61046927SAndroid Build Coastguard Worker    }
668*61046927SAndroid Build Coastguard Worker    else {
669*61046927SAndroid Build Coastguard Worker       if ((gc->pc + command_size) >= gc->bufEnd) {
670*61046927SAndroid Build Coastguard Worker          (void) __glXFlushRenderBuffer(gc, gc->pc);
671*61046927SAndroid Build Coastguard Worker       }
672*61046927SAndroid Build Coastguard Worker 
673*61046927SAndroid Build Coastguard Worker       pc = gc->pc;
674*61046927SAndroid Build Coastguard Worker       *(uint16_t *) (pc + 0) = command_size;
675*61046927SAndroid Build Coastguard Worker       *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
676*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 4) = count;
677*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
678*61046927SAndroid Build Coastguard Worker       *(uint32_t *) (pc + 12) = mode;
679*61046927SAndroid Build Coastguard Worker 
680*61046927SAndroid Build Coastguard Worker       pc += header_size;
681*61046927SAndroid Build Coastguard Worker 
682*61046927SAndroid Build Coastguard Worker       (void) memcpy(pc, arrays->array_info_cache,
683*61046927SAndroid Build Coastguard Worker                     arrays->array_info_cache_size);
684*61046927SAndroid Build Coastguard Worker       pc += arrays->array_info_cache_size;
685*61046927SAndroid Build Coastguard Worker 
686*61046927SAndroid Build Coastguard Worker       *elements_per_request = count;
687*61046927SAndroid Build Coastguard Worker       *total_requests = 0;
688*61046927SAndroid Build Coastguard Worker    }
689*61046927SAndroid Build Coastguard Worker 
690*61046927SAndroid Build Coastguard Worker 
691*61046927SAndroid Build Coastguard Worker    return pc;
692*61046927SAndroid Build Coastguard Worker }
693*61046927SAndroid Build Coastguard Worker 
694*61046927SAndroid Build Coastguard Worker 
695*61046927SAndroid Build Coastguard Worker /**
696*61046927SAndroid Build Coastguard Worker  */
697*61046927SAndroid Build Coastguard Worker void
emit_DrawArrays_old(GLenum mode,GLint first,GLsizei count)698*61046927SAndroid Build Coastguard Worker emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
699*61046927SAndroid Build Coastguard Worker {
700*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
701*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
702*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
703*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
704*61046927SAndroid Build Coastguard Worker 
705*61046927SAndroid Build Coastguard Worker    GLubyte *pc;
706*61046927SAndroid Build Coastguard Worker    size_t elements_per_request;
707*61046927SAndroid Build Coastguard Worker    unsigned total_requests = 0;
708*61046927SAndroid Build Coastguard Worker    unsigned i;
709*61046927SAndroid Build Coastguard Worker 
710*61046927SAndroid Build Coastguard Worker 
711*61046927SAndroid Build Coastguard Worker    pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
712*61046927SAndroid Build Coastguard Worker                                    &total_requests, mode, count);
713*61046927SAndroid Build Coastguard Worker 
714*61046927SAndroid Build Coastguard Worker 
715*61046927SAndroid Build Coastguard Worker    /* Write the arrays.
716*61046927SAndroid Build Coastguard Worker     */
717*61046927SAndroid Build Coastguard Worker 
718*61046927SAndroid Build Coastguard Worker    if (total_requests == 0) {
719*61046927SAndroid Build Coastguard Worker       assert(elements_per_request >= count);
720*61046927SAndroid Build Coastguard Worker 
721*61046927SAndroid Build Coastguard Worker       for (i = 0; i < count; i++) {
722*61046927SAndroid Build Coastguard Worker          pc = emit_element_old(pc, arrays, i + first);
723*61046927SAndroid Build Coastguard Worker       }
724*61046927SAndroid Build Coastguard Worker 
725*61046927SAndroid Build Coastguard Worker       assert(pc <= gc->bufEnd);
726*61046927SAndroid Build Coastguard Worker 
727*61046927SAndroid Build Coastguard Worker       gc->pc = pc;
728*61046927SAndroid Build Coastguard Worker       if (gc->pc > gc->limit) {
729*61046927SAndroid Build Coastguard Worker          (void) __glXFlushRenderBuffer(gc, gc->pc);
730*61046927SAndroid Build Coastguard Worker       }
731*61046927SAndroid Build Coastguard Worker    }
732*61046927SAndroid Build Coastguard Worker    else {
733*61046927SAndroid Build Coastguard Worker       unsigned req;
734*61046927SAndroid Build Coastguard Worker 
735*61046927SAndroid Build Coastguard Worker 
736*61046927SAndroid Build Coastguard Worker       for (req = 2; req <= total_requests; req++) {
737*61046927SAndroid Build Coastguard Worker          if (count < elements_per_request) {
738*61046927SAndroid Build Coastguard Worker             elements_per_request = count;
739*61046927SAndroid Build Coastguard Worker          }
740*61046927SAndroid Build Coastguard Worker 
741*61046927SAndroid Build Coastguard Worker          pc = gc->pc;
742*61046927SAndroid Build Coastguard Worker          for (i = 0; i < elements_per_request; i++) {
743*61046927SAndroid Build Coastguard Worker             pc = emit_element_old(pc, arrays, i + first);
744*61046927SAndroid Build Coastguard Worker          }
745*61046927SAndroid Build Coastguard Worker 
746*61046927SAndroid Build Coastguard Worker          first += elements_per_request;
747*61046927SAndroid Build Coastguard Worker 
748*61046927SAndroid Build Coastguard Worker          __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
749*61046927SAndroid Build Coastguard Worker 
750*61046927SAndroid Build Coastguard Worker          count -= elements_per_request;
751*61046927SAndroid Build Coastguard Worker       }
752*61046927SAndroid Build Coastguard Worker    }
753*61046927SAndroid Build Coastguard Worker }
754*61046927SAndroid Build Coastguard Worker 
755*61046927SAndroid Build Coastguard Worker 
756*61046927SAndroid Build Coastguard Worker void
emit_DrawElements_none(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)757*61046927SAndroid Build Coastguard Worker emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
758*61046927SAndroid Build Coastguard Worker                        const GLvoid * indices)
759*61046927SAndroid Build Coastguard Worker {
760*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
761*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
762*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
763*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
764*61046927SAndroid Build Coastguard Worker    static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
765*61046927SAndroid Build Coastguard Worker    static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
766*61046927SAndroid Build Coastguard Worker 
767*61046927SAndroid Build Coastguard Worker    GLubyte *pc;
768*61046927SAndroid Build Coastguard Worker    size_t single_vertex_size;
769*61046927SAndroid Build Coastguard Worker    unsigned i;
770*61046927SAndroid Build Coastguard Worker 
771*61046927SAndroid Build Coastguard Worker 
772*61046927SAndroid Build Coastguard Worker    single_vertex_size = calculate_single_vertex_size_none(arrays);
773*61046927SAndroid Build Coastguard Worker 
774*61046927SAndroid Build Coastguard Worker 
775*61046927SAndroid Build Coastguard Worker    if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
776*61046927SAndroid Build Coastguard Worker       gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
777*61046927SAndroid Build Coastguard Worker    }
778*61046927SAndroid Build Coastguard Worker 
779*61046927SAndroid Build Coastguard Worker    pc = gc->pc;
780*61046927SAndroid Build Coastguard Worker 
781*61046927SAndroid Build Coastguard Worker    (void) memcpy(pc, begin_cmd, 4);
782*61046927SAndroid Build Coastguard Worker    *(int *) (pc + 4) = mode;
783*61046927SAndroid Build Coastguard Worker 
784*61046927SAndroid Build Coastguard Worker    pc += 8;
785*61046927SAndroid Build Coastguard Worker 
786*61046927SAndroid Build Coastguard Worker    for (i = 0; i < count; i++) {
787*61046927SAndroid Build Coastguard Worker       unsigned index = 0;
788*61046927SAndroid Build Coastguard Worker 
789*61046927SAndroid Build Coastguard Worker       if ((pc + single_vertex_size) >= gc->bufEnd) {
790*61046927SAndroid Build Coastguard Worker          pc = __glXFlushRenderBuffer(gc, pc);
791*61046927SAndroid Build Coastguard Worker       }
792*61046927SAndroid Build Coastguard Worker 
793*61046927SAndroid Build Coastguard Worker       switch (type) {
794*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_INT:
795*61046927SAndroid Build Coastguard Worker          index = (unsigned) (((GLuint *) indices)[i]);
796*61046927SAndroid Build Coastguard Worker          break;
797*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_SHORT:
798*61046927SAndroid Build Coastguard Worker          index = (unsigned) (((GLushort *) indices)[i]);
799*61046927SAndroid Build Coastguard Worker          break;
800*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_BYTE:
801*61046927SAndroid Build Coastguard Worker          index = (unsigned) (((GLubyte *) indices)[i]);
802*61046927SAndroid Build Coastguard Worker          break;
803*61046927SAndroid Build Coastguard Worker       }
804*61046927SAndroid Build Coastguard Worker       pc = emit_element_none(pc, arrays, index);
805*61046927SAndroid Build Coastguard Worker    }
806*61046927SAndroid Build Coastguard Worker 
807*61046927SAndroid Build Coastguard Worker    if ((pc + 4) >= gc->bufEnd) {
808*61046927SAndroid Build Coastguard Worker       pc = __glXFlushRenderBuffer(gc, pc);
809*61046927SAndroid Build Coastguard Worker    }
810*61046927SAndroid Build Coastguard Worker 
811*61046927SAndroid Build Coastguard Worker    (void) memcpy(pc, end_cmd, 4);
812*61046927SAndroid Build Coastguard Worker    pc += 4;
813*61046927SAndroid Build Coastguard Worker 
814*61046927SAndroid Build Coastguard Worker    gc->pc = pc;
815*61046927SAndroid Build Coastguard Worker    if (gc->pc > gc->limit) {
816*61046927SAndroid Build Coastguard Worker       (void) __glXFlushRenderBuffer(gc, gc->pc);
817*61046927SAndroid Build Coastguard Worker    }
818*61046927SAndroid Build Coastguard Worker }
819*61046927SAndroid Build Coastguard Worker 
820*61046927SAndroid Build Coastguard Worker 
821*61046927SAndroid Build Coastguard Worker /**
822*61046927SAndroid Build Coastguard Worker  */
823*61046927SAndroid Build Coastguard Worker void
emit_DrawElements_old(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)824*61046927SAndroid Build Coastguard Worker emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
825*61046927SAndroid Build Coastguard Worker                       const GLvoid * indices)
826*61046927SAndroid Build Coastguard Worker {
827*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
828*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
829*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
830*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
831*61046927SAndroid Build Coastguard Worker 
832*61046927SAndroid Build Coastguard Worker    GLubyte *pc;
833*61046927SAndroid Build Coastguard Worker    size_t elements_per_request;
834*61046927SAndroid Build Coastguard Worker    unsigned total_requests = 0;
835*61046927SAndroid Build Coastguard Worker    unsigned i;
836*61046927SAndroid Build Coastguard Worker    unsigned req;
837*61046927SAndroid Build Coastguard Worker    unsigned req_element = 0;
838*61046927SAndroid Build Coastguard Worker 
839*61046927SAndroid Build Coastguard Worker 
840*61046927SAndroid Build Coastguard Worker    pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
841*61046927SAndroid Build Coastguard Worker                                    &total_requests, mode, count);
842*61046927SAndroid Build Coastguard Worker 
843*61046927SAndroid Build Coastguard Worker 
844*61046927SAndroid Build Coastguard Worker    /* Write the arrays.
845*61046927SAndroid Build Coastguard Worker     */
846*61046927SAndroid Build Coastguard Worker 
847*61046927SAndroid Build Coastguard Worker    req = 2;
848*61046927SAndroid Build Coastguard Worker    while (count > 0) {
849*61046927SAndroid Build Coastguard Worker       if (count < elements_per_request) {
850*61046927SAndroid Build Coastguard Worker          elements_per_request = count;
851*61046927SAndroid Build Coastguard Worker       }
852*61046927SAndroid Build Coastguard Worker 
853*61046927SAndroid Build Coastguard Worker       switch (type) {
854*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_INT:{
855*61046927SAndroid Build Coastguard Worker             const GLuint *ui_ptr = (const GLuint *) indices + req_element;
856*61046927SAndroid Build Coastguard Worker 
857*61046927SAndroid Build Coastguard Worker             for (i = 0; i < elements_per_request; i++) {
858*61046927SAndroid Build Coastguard Worker                const GLint index = (GLint) * (ui_ptr++);
859*61046927SAndroid Build Coastguard Worker                pc = emit_element_old(pc, arrays, index);
860*61046927SAndroid Build Coastguard Worker             }
861*61046927SAndroid Build Coastguard Worker             break;
862*61046927SAndroid Build Coastguard Worker          }
863*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_SHORT:{
864*61046927SAndroid Build Coastguard Worker             const GLushort *us_ptr = (const GLushort *) indices + req_element;
865*61046927SAndroid Build Coastguard Worker 
866*61046927SAndroid Build Coastguard Worker             for (i = 0; i < elements_per_request; i++) {
867*61046927SAndroid Build Coastguard Worker                const GLint index = (GLint) * (us_ptr++);
868*61046927SAndroid Build Coastguard Worker                pc = emit_element_old(pc, arrays, index);
869*61046927SAndroid Build Coastguard Worker             }
870*61046927SAndroid Build Coastguard Worker             break;
871*61046927SAndroid Build Coastguard Worker          }
872*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_BYTE:{
873*61046927SAndroid Build Coastguard Worker             const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;
874*61046927SAndroid Build Coastguard Worker 
875*61046927SAndroid Build Coastguard Worker             for (i = 0; i < elements_per_request; i++) {
876*61046927SAndroid Build Coastguard Worker                const GLint index = (GLint) * (ub_ptr++);
877*61046927SAndroid Build Coastguard Worker                pc = emit_element_old(pc, arrays, index);
878*61046927SAndroid Build Coastguard Worker             }
879*61046927SAndroid Build Coastguard Worker             break;
880*61046927SAndroid Build Coastguard Worker          }
881*61046927SAndroid Build Coastguard Worker       }
882*61046927SAndroid Build Coastguard Worker 
883*61046927SAndroid Build Coastguard Worker       if (total_requests != 0) {
884*61046927SAndroid Build Coastguard Worker          __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
885*61046927SAndroid Build Coastguard Worker          pc = gc->pc;
886*61046927SAndroid Build Coastguard Worker          req++;
887*61046927SAndroid Build Coastguard Worker       }
888*61046927SAndroid Build Coastguard Worker 
889*61046927SAndroid Build Coastguard Worker       count -= elements_per_request;
890*61046927SAndroid Build Coastguard Worker       req_element += elements_per_request;
891*61046927SAndroid Build Coastguard Worker    }
892*61046927SAndroid Build Coastguard Worker 
893*61046927SAndroid Build Coastguard Worker 
894*61046927SAndroid Build Coastguard Worker    assert((total_requests == 0) || ((req - 1) == total_requests));
895*61046927SAndroid Build Coastguard Worker 
896*61046927SAndroid Build Coastguard Worker    if (total_requests == 0) {
897*61046927SAndroid Build Coastguard Worker       assert(pc <= gc->bufEnd);
898*61046927SAndroid Build Coastguard Worker 
899*61046927SAndroid Build Coastguard Worker       gc->pc = pc;
900*61046927SAndroid Build Coastguard Worker       if (gc->pc > gc->limit) {
901*61046927SAndroid Build Coastguard Worker          (void) __glXFlushRenderBuffer(gc, gc->pc);
902*61046927SAndroid Build Coastguard Worker       }
903*61046927SAndroid Build Coastguard Worker    }
904*61046927SAndroid Build Coastguard Worker }
905*61046927SAndroid Build Coastguard Worker 
906*61046927SAndroid Build Coastguard Worker 
907*61046927SAndroid Build Coastguard Worker /**
908*61046927SAndroid Build Coastguard Worker  * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
909*61046927SAndroid Build Coastguard Worker  * If it is not valid, then an error code is set in the GLX context.
910*61046927SAndroid Build Coastguard Worker  *
911*61046927SAndroid Build Coastguard Worker  * \returns
912*61046927SAndroid Build Coastguard Worker  * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
913*61046927SAndroid Build Coastguard Worker  */
914*61046927SAndroid Build Coastguard Worker static GLboolean
validate_mode(struct glx_context * gc,GLenum mode)915*61046927SAndroid Build Coastguard Worker validate_mode(struct glx_context * gc, GLenum mode)
916*61046927SAndroid Build Coastguard Worker {
917*61046927SAndroid Build Coastguard Worker    switch (mode) {
918*61046927SAndroid Build Coastguard Worker    case GL_POINTS:
919*61046927SAndroid Build Coastguard Worker    case GL_LINE_STRIP:
920*61046927SAndroid Build Coastguard Worker    case GL_LINE_LOOP:
921*61046927SAndroid Build Coastguard Worker    case GL_LINES:
922*61046927SAndroid Build Coastguard Worker    case GL_TRIANGLE_STRIP:
923*61046927SAndroid Build Coastguard Worker    case GL_TRIANGLE_FAN:
924*61046927SAndroid Build Coastguard Worker    case GL_TRIANGLES:
925*61046927SAndroid Build Coastguard Worker    case GL_QUAD_STRIP:
926*61046927SAndroid Build Coastguard Worker    case GL_QUADS:
927*61046927SAndroid Build Coastguard Worker    case GL_POLYGON:
928*61046927SAndroid Build Coastguard Worker       break;
929*61046927SAndroid Build Coastguard Worker    default:
930*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
931*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
932*61046927SAndroid Build Coastguard Worker    }
933*61046927SAndroid Build Coastguard Worker 
934*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
935*61046927SAndroid Build Coastguard Worker }
936*61046927SAndroid Build Coastguard Worker 
937*61046927SAndroid Build Coastguard Worker 
938*61046927SAndroid Build Coastguard Worker /**
939*61046927SAndroid Build Coastguard Worker  * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
940*61046927SAndroid Build Coastguard Worker  * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
941*61046927SAndroid Build Coastguard Worker  * being set.  A value of zero will not result in an error being set, but
942*61046927SAndroid Build Coastguard Worker  * will result in \c GL_FALSE being returned.
943*61046927SAndroid Build Coastguard Worker  *
944*61046927SAndroid Build Coastguard Worker  * \returns
945*61046927SAndroid Build Coastguard Worker  * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
946*61046927SAndroid Build Coastguard Worker  */
947*61046927SAndroid Build Coastguard Worker static GLboolean
validate_count(struct glx_context * gc,GLsizei count)948*61046927SAndroid Build Coastguard Worker validate_count(struct glx_context * gc, GLsizei count)
949*61046927SAndroid Build Coastguard Worker {
950*61046927SAndroid Build Coastguard Worker    if (count < 0) {
951*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
952*61046927SAndroid Build Coastguard Worker    }
953*61046927SAndroid Build Coastguard Worker 
954*61046927SAndroid Build Coastguard Worker    return (count > 0);
955*61046927SAndroid Build Coastguard Worker }
956*61046927SAndroid Build Coastguard Worker 
957*61046927SAndroid Build Coastguard Worker 
958*61046927SAndroid Build Coastguard Worker /**
959*61046927SAndroid Build Coastguard Worker  * Validate that the \c type parameter to \c glDrawElements, et. al. is
960*61046927SAndroid Build Coastguard Worker  * valid.  Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
961*61046927SAndroid Build Coastguard Worker  * \c GL_UNSIGNED_INT are valid.
962*61046927SAndroid Build Coastguard Worker  *
963*61046927SAndroid Build Coastguard Worker  * \returns
964*61046927SAndroid Build Coastguard Worker  * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
965*61046927SAndroid Build Coastguard Worker  */
966*61046927SAndroid Build Coastguard Worker static GLboolean
validate_type(struct glx_context * gc,GLenum type)967*61046927SAndroid Build Coastguard Worker validate_type(struct glx_context * gc, GLenum type)
968*61046927SAndroid Build Coastguard Worker {
969*61046927SAndroid Build Coastguard Worker    switch (type) {
970*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_INT:
971*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_SHORT:
972*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_BYTE:
973*61046927SAndroid Build Coastguard Worker       return GL_TRUE;
974*61046927SAndroid Build Coastguard Worker    default:
975*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
976*61046927SAndroid Build Coastguard Worker       return GL_FALSE;
977*61046927SAndroid Build Coastguard Worker    }
978*61046927SAndroid Build Coastguard Worker }
979*61046927SAndroid Build Coastguard Worker 
980*61046927SAndroid Build Coastguard Worker 
981*61046927SAndroid Build Coastguard Worker void
__indirect_glDrawArrays(GLenum mode,GLint first,GLsizei count)982*61046927SAndroid Build Coastguard Worker __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
983*61046927SAndroid Build Coastguard Worker {
984*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
985*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
986*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
987*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
988*61046927SAndroid Build Coastguard Worker 
989*61046927SAndroid Build Coastguard Worker 
990*61046927SAndroid Build Coastguard Worker    if (validate_mode(gc, mode) && validate_count(gc, count)) {
991*61046927SAndroid Build Coastguard Worker       if (!arrays->array_info_cache_valid) {
992*61046927SAndroid Build Coastguard Worker          fill_array_info_cache(arrays);
993*61046927SAndroid Build Coastguard Worker       }
994*61046927SAndroid Build Coastguard Worker 
995*61046927SAndroid Build Coastguard Worker       arrays->DrawArrays(mode, first, count);
996*61046927SAndroid Build Coastguard Worker    }
997*61046927SAndroid Build Coastguard Worker }
998*61046927SAndroid Build Coastguard Worker 
999*61046927SAndroid Build Coastguard Worker 
1000*61046927SAndroid Build Coastguard Worker void
__indirect_glArrayElement(GLint index)1001*61046927SAndroid Build Coastguard Worker __indirect_glArrayElement(GLint index)
1002*61046927SAndroid Build Coastguard Worker {
1003*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1004*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
1005*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
1006*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1007*61046927SAndroid Build Coastguard Worker 
1008*61046927SAndroid Build Coastguard Worker    size_t single_vertex_size;
1009*61046927SAndroid Build Coastguard Worker 
1010*61046927SAndroid Build Coastguard Worker 
1011*61046927SAndroid Build Coastguard Worker    single_vertex_size = calculate_single_vertex_size_none(arrays);
1012*61046927SAndroid Build Coastguard Worker 
1013*61046927SAndroid Build Coastguard Worker    if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
1014*61046927SAndroid Build Coastguard Worker       gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
1015*61046927SAndroid Build Coastguard Worker    }
1016*61046927SAndroid Build Coastguard Worker 
1017*61046927SAndroid Build Coastguard Worker    gc->pc = emit_element_none(gc->pc, arrays, index);
1018*61046927SAndroid Build Coastguard Worker 
1019*61046927SAndroid Build Coastguard Worker    if (gc->pc > gc->limit) {
1020*61046927SAndroid Build Coastguard Worker       (void) __glXFlushRenderBuffer(gc, gc->pc);
1021*61046927SAndroid Build Coastguard Worker    }
1022*61046927SAndroid Build Coastguard Worker }
1023*61046927SAndroid Build Coastguard Worker 
1024*61046927SAndroid Build Coastguard Worker 
1025*61046927SAndroid Build Coastguard Worker void
__indirect_glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1026*61046927SAndroid Build Coastguard Worker __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
1027*61046927SAndroid Build Coastguard Worker                           const GLvoid * indices)
1028*61046927SAndroid Build Coastguard Worker {
1029*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1030*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
1031*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
1032*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1033*61046927SAndroid Build Coastguard Worker 
1034*61046927SAndroid Build Coastguard Worker 
1035*61046927SAndroid Build Coastguard Worker    if (validate_mode(gc, mode) && validate_count(gc, count)
1036*61046927SAndroid Build Coastguard Worker        && validate_type(gc, type)) {
1037*61046927SAndroid Build Coastguard Worker       if (!arrays->array_info_cache_valid) {
1038*61046927SAndroid Build Coastguard Worker          fill_array_info_cache(arrays);
1039*61046927SAndroid Build Coastguard Worker       }
1040*61046927SAndroid Build Coastguard Worker 
1041*61046927SAndroid Build Coastguard Worker       arrays->DrawElements(mode, count, type, indices);
1042*61046927SAndroid Build Coastguard Worker    }
1043*61046927SAndroid Build Coastguard Worker }
1044*61046927SAndroid Build Coastguard Worker 
1045*61046927SAndroid Build Coastguard Worker 
1046*61046927SAndroid Build Coastguard Worker void
__indirect_glDrawRangeElements(GLenum mode,GLuint start,GLuint end,GLsizei count,GLenum type,const GLvoid * indices)1047*61046927SAndroid Build Coastguard Worker __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1048*61046927SAndroid Build Coastguard Worker                                GLsizei count, GLenum type,
1049*61046927SAndroid Build Coastguard Worker                                const GLvoid * indices)
1050*61046927SAndroid Build Coastguard Worker {
1051*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1052*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
1053*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
1054*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1055*61046927SAndroid Build Coastguard Worker 
1056*61046927SAndroid Build Coastguard Worker 
1057*61046927SAndroid Build Coastguard Worker    if (validate_mode(gc, mode) && validate_count(gc, count)
1058*61046927SAndroid Build Coastguard Worker        && validate_type(gc, type)) {
1059*61046927SAndroid Build Coastguard Worker       if (end < start) {
1060*61046927SAndroid Build Coastguard Worker          __glXSetError(gc, GL_INVALID_VALUE);
1061*61046927SAndroid Build Coastguard Worker          return;
1062*61046927SAndroid Build Coastguard Worker       }
1063*61046927SAndroid Build Coastguard Worker 
1064*61046927SAndroid Build Coastguard Worker       if (!arrays->array_info_cache_valid) {
1065*61046927SAndroid Build Coastguard Worker          fill_array_info_cache(arrays);
1066*61046927SAndroid Build Coastguard Worker       }
1067*61046927SAndroid Build Coastguard Worker 
1068*61046927SAndroid Build Coastguard Worker       arrays->DrawElements(mode, count, type, indices);
1069*61046927SAndroid Build Coastguard Worker    }
1070*61046927SAndroid Build Coastguard Worker }
1071*61046927SAndroid Build Coastguard Worker 
1072*61046927SAndroid Build Coastguard Worker 
1073*61046927SAndroid Build Coastguard Worker void
__indirect_glMultiDrawArrays(GLenum mode,const GLint * first,const GLsizei * count,GLsizei primcount)1074*61046927SAndroid Build Coastguard Worker __indirect_glMultiDrawArrays(GLenum mode, const GLint *first,
1075*61046927SAndroid Build Coastguard Worker                                 const GLsizei *count, GLsizei primcount)
1076*61046927SAndroid Build Coastguard Worker {
1077*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1078*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
1079*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
1080*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1081*61046927SAndroid Build Coastguard Worker    GLsizei i;
1082*61046927SAndroid Build Coastguard Worker 
1083*61046927SAndroid Build Coastguard Worker 
1084*61046927SAndroid Build Coastguard Worker    if (validate_mode(gc, mode)) {
1085*61046927SAndroid Build Coastguard Worker       if (!arrays->array_info_cache_valid) {
1086*61046927SAndroid Build Coastguard Worker          fill_array_info_cache(arrays);
1087*61046927SAndroid Build Coastguard Worker       }
1088*61046927SAndroid Build Coastguard Worker 
1089*61046927SAndroid Build Coastguard Worker       for (i = 0; i < primcount; i++) {
1090*61046927SAndroid Build Coastguard Worker          if (validate_count(gc, count[i])) {
1091*61046927SAndroid Build Coastguard Worker             arrays->DrawArrays(mode, first[i], count[i]);
1092*61046927SAndroid Build Coastguard Worker          }
1093*61046927SAndroid Build Coastguard Worker       }
1094*61046927SAndroid Build Coastguard Worker    }
1095*61046927SAndroid Build Coastguard Worker }
1096*61046927SAndroid Build Coastguard Worker 
1097*61046927SAndroid Build Coastguard Worker 
1098*61046927SAndroid Build Coastguard Worker void
__indirect_glMultiDrawElements(GLenum mode,const GLsizei * count,GLenum type,const GLvoid * const * indices,GLsizei primcount)1099*61046927SAndroid Build Coastguard Worker __indirect_glMultiDrawElements(GLenum mode, const GLsizei * count,
1100*61046927SAndroid Build Coastguard Worker                                GLenum type, const GLvoid * const * indices,
1101*61046927SAndroid Build Coastguard Worker                                GLsizei primcount)
1102*61046927SAndroid Build Coastguard Worker {
1103*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1104*61046927SAndroid Build Coastguard Worker    const __GLXattribute *state =
1105*61046927SAndroid Build Coastguard Worker       (const __GLXattribute *) (gc->client_state_private);
1106*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1107*61046927SAndroid Build Coastguard Worker    GLsizei i;
1108*61046927SAndroid Build Coastguard Worker 
1109*61046927SAndroid Build Coastguard Worker 
1110*61046927SAndroid Build Coastguard Worker    if (validate_mode(gc, mode) && validate_type(gc, type)) {
1111*61046927SAndroid Build Coastguard Worker       if (!arrays->array_info_cache_valid) {
1112*61046927SAndroid Build Coastguard Worker          fill_array_info_cache(arrays);
1113*61046927SAndroid Build Coastguard Worker       }
1114*61046927SAndroid Build Coastguard Worker 
1115*61046927SAndroid Build Coastguard Worker       for (i = 0; i < primcount; i++) {
1116*61046927SAndroid Build Coastguard Worker          if (validate_count(gc, count[i])) {
1117*61046927SAndroid Build Coastguard Worker             arrays->DrawElements(mode, count[i], type, indices[i]);
1118*61046927SAndroid Build Coastguard Worker          }
1119*61046927SAndroid Build Coastguard Worker       }
1120*61046927SAndroid Build Coastguard Worker    }
1121*61046927SAndroid Build Coastguard Worker }
1122*61046927SAndroid Build Coastguard Worker 
1123*61046927SAndroid Build Coastguard Worker 
1124*61046927SAndroid Build Coastguard Worker /* The HDR_SIZE macro argument is the command header size (4 bytes)
1125*61046927SAndroid Build Coastguard Worker  * plus any additional index word e.g. for texture units or vertex
1126*61046927SAndroid Build Coastguard Worker  * attributes.
1127*61046927SAndroid Build Coastguard Worker  */
1128*61046927SAndroid Build Coastguard Worker #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1129*61046927SAndroid Build Coastguard Worker   do {                                                                  \
1130*61046927SAndroid Build Coastguard Worker     (a)->data = PTR;                                                    \
1131*61046927SAndroid Build Coastguard Worker     (a)->data_type = TYPE;                                              \
1132*61046927SAndroid Build Coastguard Worker     (a)->user_stride = STRIDE;                                          \
1133*61046927SAndroid Build Coastguard Worker     (a)->count = COUNT;                                                 \
1134*61046927SAndroid Build Coastguard Worker     (a)->normalized = NORMALIZED;                                       \
1135*61046927SAndroid Build Coastguard Worker                                                                         \
1136*61046927SAndroid Build Coastguard Worker     (a)->element_size = __glXTypeSize( TYPE ) * COUNT;                  \
1137*61046927SAndroid Build Coastguard Worker     (a)->true_stride = (STRIDE == 0)                                    \
1138*61046927SAndroid Build Coastguard Worker       ? (a)->element_size : STRIDE;                                     \
1139*61046927SAndroid Build Coastguard Worker                                                                         \
1140*61046927SAndroid Build Coastguard Worker     (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size);           \
1141*61046927SAndroid Build Coastguard Worker     (a)->header[1] = OPCODE;                                            \
1142*61046927SAndroid Build Coastguard Worker   } while(0)
1143*61046927SAndroid Build Coastguard Worker 
1144*61046927SAndroid Build Coastguard Worker 
1145*61046927SAndroid Build Coastguard Worker void
__indirect_glVertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)1146*61046927SAndroid Build Coastguard Worker __indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
1147*61046927SAndroid Build Coastguard Worker                            const GLvoid * pointer)
1148*61046927SAndroid Build Coastguard Worker {
1149*61046927SAndroid Build Coastguard Worker    static const uint16_t short_ops[5] = {
1150*61046927SAndroid Build Coastguard Worker       0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1151*61046927SAndroid Build Coastguard Worker    };
1152*61046927SAndroid Build Coastguard Worker    static const uint16_t int_ops[5] = {
1153*61046927SAndroid Build Coastguard Worker       0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1154*61046927SAndroid Build Coastguard Worker    };
1155*61046927SAndroid Build Coastguard Worker    static const uint16_t float_ops[5] = {
1156*61046927SAndroid Build Coastguard Worker       0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1157*61046927SAndroid Build Coastguard Worker    };
1158*61046927SAndroid Build Coastguard Worker    static const uint16_t double_ops[5] = {
1159*61046927SAndroid Build Coastguard Worker       0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1160*61046927SAndroid Build Coastguard Worker    };
1161*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1162*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1163*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1164*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1165*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1166*61046927SAndroid Build Coastguard Worker 
1167*61046927SAndroid Build Coastguard Worker 
1168*61046927SAndroid Build Coastguard Worker    if (size < 2 || size > 4 || stride < 0) {
1169*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1170*61046927SAndroid Build Coastguard Worker       return;
1171*61046927SAndroid Build Coastguard Worker    }
1172*61046927SAndroid Build Coastguard Worker 
1173*61046927SAndroid Build Coastguard Worker    switch (type) {
1174*61046927SAndroid Build Coastguard Worker    case GL_SHORT:
1175*61046927SAndroid Build Coastguard Worker       opcode = short_ops[size];
1176*61046927SAndroid Build Coastguard Worker       break;
1177*61046927SAndroid Build Coastguard Worker    case GL_INT:
1178*61046927SAndroid Build Coastguard Worker       opcode = int_ops[size];
1179*61046927SAndroid Build Coastguard Worker       break;
1180*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1181*61046927SAndroid Build Coastguard Worker       opcode = float_ops[size];
1182*61046927SAndroid Build Coastguard Worker       break;
1183*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1184*61046927SAndroid Build Coastguard Worker       opcode = double_ops[size];
1185*61046927SAndroid Build Coastguard Worker       break;
1186*61046927SAndroid Build Coastguard Worker    default:
1187*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1188*61046927SAndroid Build Coastguard Worker       return;
1189*61046927SAndroid Build Coastguard Worker    }
1190*61046927SAndroid Build Coastguard Worker 
1191*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
1192*61046927SAndroid Build Coastguard Worker    assert(a != NULL);
1193*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
1194*61046927SAndroid Build Coastguard Worker                           opcode);
1195*61046927SAndroid Build Coastguard Worker 
1196*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1197*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1198*61046927SAndroid Build Coastguard Worker    }
1199*61046927SAndroid Build Coastguard Worker }
1200*61046927SAndroid Build Coastguard Worker 
1201*61046927SAndroid Build Coastguard Worker 
1202*61046927SAndroid Build Coastguard Worker void
__indirect_glNormalPointer(GLenum type,GLsizei stride,const GLvoid * pointer)1203*61046927SAndroid Build Coastguard Worker __indirect_glNormalPointer(GLenum type, GLsizei stride,
1204*61046927SAndroid Build Coastguard Worker                            const GLvoid * pointer)
1205*61046927SAndroid Build Coastguard Worker {
1206*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1207*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1208*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1209*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1210*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1211*61046927SAndroid Build Coastguard Worker 
1212*61046927SAndroid Build Coastguard Worker 
1213*61046927SAndroid Build Coastguard Worker    if (stride < 0) {
1214*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1215*61046927SAndroid Build Coastguard Worker       return;
1216*61046927SAndroid Build Coastguard Worker    }
1217*61046927SAndroid Build Coastguard Worker 
1218*61046927SAndroid Build Coastguard Worker    switch (type) {
1219*61046927SAndroid Build Coastguard Worker    case GL_BYTE:
1220*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Normal3bv;
1221*61046927SAndroid Build Coastguard Worker       break;
1222*61046927SAndroid Build Coastguard Worker    case GL_SHORT:
1223*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Normal3sv;
1224*61046927SAndroid Build Coastguard Worker       break;
1225*61046927SAndroid Build Coastguard Worker    case GL_INT:
1226*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Normal3iv;
1227*61046927SAndroid Build Coastguard Worker       break;
1228*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1229*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Normal3fv;
1230*61046927SAndroid Build Coastguard Worker       break;
1231*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1232*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Normal3dv;
1233*61046927SAndroid Build Coastguard Worker       break;
1234*61046927SAndroid Build Coastguard Worker    default:
1235*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1236*61046927SAndroid Build Coastguard Worker       return;
1237*61046927SAndroid Build Coastguard Worker    }
1238*61046927SAndroid Build Coastguard Worker 
1239*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
1240*61046927SAndroid Build Coastguard Worker    assert(a != NULL);
1241*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);
1242*61046927SAndroid Build Coastguard Worker 
1243*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1244*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1245*61046927SAndroid Build Coastguard Worker    }
1246*61046927SAndroid Build Coastguard Worker }
1247*61046927SAndroid Build Coastguard Worker 
1248*61046927SAndroid Build Coastguard Worker 
1249*61046927SAndroid Build Coastguard Worker void
__indirect_glColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)1250*61046927SAndroid Build Coastguard Worker __indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
1251*61046927SAndroid Build Coastguard Worker                           const GLvoid * pointer)
1252*61046927SAndroid Build Coastguard Worker {
1253*61046927SAndroid Build Coastguard Worker    static const uint16_t byte_ops[5] = {
1254*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1255*61046927SAndroid Build Coastguard Worker    };
1256*61046927SAndroid Build Coastguard Worker    static const uint16_t ubyte_ops[5] = {
1257*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1258*61046927SAndroid Build Coastguard Worker    };
1259*61046927SAndroid Build Coastguard Worker    static const uint16_t short_ops[5] = {
1260*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1261*61046927SAndroid Build Coastguard Worker    };
1262*61046927SAndroid Build Coastguard Worker    static const uint16_t ushort_ops[5] = {
1263*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1264*61046927SAndroid Build Coastguard Worker    };
1265*61046927SAndroid Build Coastguard Worker    static const uint16_t int_ops[5] = {
1266*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1267*61046927SAndroid Build Coastguard Worker    };
1268*61046927SAndroid Build Coastguard Worker    static const uint16_t uint_ops[5] = {
1269*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1270*61046927SAndroid Build Coastguard Worker    };
1271*61046927SAndroid Build Coastguard Worker    static const uint16_t float_ops[5] = {
1272*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1273*61046927SAndroid Build Coastguard Worker    };
1274*61046927SAndroid Build Coastguard Worker    static const uint16_t double_ops[5] = {
1275*61046927SAndroid Build Coastguard Worker       0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1276*61046927SAndroid Build Coastguard Worker    };
1277*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1278*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1279*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1280*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1281*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1282*61046927SAndroid Build Coastguard Worker 
1283*61046927SAndroid Build Coastguard Worker 
1284*61046927SAndroid Build Coastguard Worker    if (size < 3 || size > 4 || stride < 0) {
1285*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1286*61046927SAndroid Build Coastguard Worker       return;
1287*61046927SAndroid Build Coastguard Worker    }
1288*61046927SAndroid Build Coastguard Worker 
1289*61046927SAndroid Build Coastguard Worker    switch (type) {
1290*61046927SAndroid Build Coastguard Worker    case GL_BYTE:
1291*61046927SAndroid Build Coastguard Worker       opcode = byte_ops[size];
1292*61046927SAndroid Build Coastguard Worker       break;
1293*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_BYTE:
1294*61046927SAndroid Build Coastguard Worker       opcode = ubyte_ops[size];
1295*61046927SAndroid Build Coastguard Worker       break;
1296*61046927SAndroid Build Coastguard Worker    case GL_SHORT:
1297*61046927SAndroid Build Coastguard Worker       opcode = short_ops[size];
1298*61046927SAndroid Build Coastguard Worker       break;
1299*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_SHORT:
1300*61046927SAndroid Build Coastguard Worker       opcode = ushort_ops[size];
1301*61046927SAndroid Build Coastguard Worker       break;
1302*61046927SAndroid Build Coastguard Worker    case GL_INT:
1303*61046927SAndroid Build Coastguard Worker       opcode = int_ops[size];
1304*61046927SAndroid Build Coastguard Worker       break;
1305*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_INT:
1306*61046927SAndroid Build Coastguard Worker       opcode = uint_ops[size];
1307*61046927SAndroid Build Coastguard Worker       break;
1308*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1309*61046927SAndroid Build Coastguard Worker       opcode = float_ops[size];
1310*61046927SAndroid Build Coastguard Worker       break;
1311*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1312*61046927SAndroid Build Coastguard Worker       opcode = double_ops[size];
1313*61046927SAndroid Build Coastguard Worker       break;
1314*61046927SAndroid Build Coastguard Worker    default:
1315*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1316*61046927SAndroid Build Coastguard Worker       return;
1317*61046927SAndroid Build Coastguard Worker    }
1318*61046927SAndroid Build Coastguard Worker 
1319*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
1320*61046927SAndroid Build Coastguard Worker    assert(a != NULL);
1321*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1322*61046927SAndroid Build Coastguard Worker 
1323*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1324*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1325*61046927SAndroid Build Coastguard Worker    }
1326*61046927SAndroid Build Coastguard Worker }
1327*61046927SAndroid Build Coastguard Worker 
1328*61046927SAndroid Build Coastguard Worker 
1329*61046927SAndroid Build Coastguard Worker void
__indirect_glIndexPointer(GLenum type,GLsizei stride,const GLvoid * pointer)1330*61046927SAndroid Build Coastguard Worker __indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
1331*61046927SAndroid Build Coastguard Worker {
1332*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1333*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1334*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1335*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1336*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1337*61046927SAndroid Build Coastguard Worker 
1338*61046927SAndroid Build Coastguard Worker 
1339*61046927SAndroid Build Coastguard Worker    if (stride < 0) {
1340*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1341*61046927SAndroid Build Coastguard Worker       return;
1342*61046927SAndroid Build Coastguard Worker    }
1343*61046927SAndroid Build Coastguard Worker 
1344*61046927SAndroid Build Coastguard Worker    switch (type) {
1345*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_BYTE:
1346*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Indexubv;
1347*61046927SAndroid Build Coastguard Worker       break;
1348*61046927SAndroid Build Coastguard Worker    case GL_SHORT:
1349*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Indexsv;
1350*61046927SAndroid Build Coastguard Worker       break;
1351*61046927SAndroid Build Coastguard Worker    case GL_INT:
1352*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Indexiv;
1353*61046927SAndroid Build Coastguard Worker       break;
1354*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1355*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Indexfv;
1356*61046927SAndroid Build Coastguard Worker       break;
1357*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1358*61046927SAndroid Build Coastguard Worker       opcode = X_GLrop_Indexdv;
1359*61046927SAndroid Build Coastguard Worker       break;
1360*61046927SAndroid Build Coastguard Worker    default:
1361*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1362*61046927SAndroid Build Coastguard Worker       return;
1363*61046927SAndroid Build Coastguard Worker    }
1364*61046927SAndroid Build Coastguard Worker 
1365*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
1366*61046927SAndroid Build Coastguard Worker    assert(a != NULL);
1367*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1368*61046927SAndroid Build Coastguard Worker 
1369*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1370*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1371*61046927SAndroid Build Coastguard Worker    }
1372*61046927SAndroid Build Coastguard Worker }
1373*61046927SAndroid Build Coastguard Worker 
1374*61046927SAndroid Build Coastguard Worker 
1375*61046927SAndroid Build Coastguard Worker void
__indirect_glEdgeFlagPointer(GLsizei stride,const GLvoid * pointer)1376*61046927SAndroid Build Coastguard Worker __indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
1377*61046927SAndroid Build Coastguard Worker {
1378*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1379*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1380*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1381*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1382*61046927SAndroid Build Coastguard Worker 
1383*61046927SAndroid Build Coastguard Worker 
1384*61046927SAndroid Build Coastguard Worker    if (stride < 0) {
1385*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1386*61046927SAndroid Build Coastguard Worker       return;
1387*61046927SAndroid Build Coastguard Worker    }
1388*61046927SAndroid Build Coastguard Worker 
1389*61046927SAndroid Build Coastguard Worker 
1390*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
1391*61046927SAndroid Build Coastguard Worker    assert(a != NULL);
1392*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1393*61046927SAndroid Build Coastguard Worker                           4, X_GLrop_EdgeFlagv);
1394*61046927SAndroid Build Coastguard Worker 
1395*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1396*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1397*61046927SAndroid Build Coastguard Worker    }
1398*61046927SAndroid Build Coastguard Worker }
1399*61046927SAndroid Build Coastguard Worker 
1400*61046927SAndroid Build Coastguard Worker 
1401*61046927SAndroid Build Coastguard Worker void
__indirect_glTexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)1402*61046927SAndroid Build Coastguard Worker __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
1403*61046927SAndroid Build Coastguard Worker                              const GLvoid * pointer)
1404*61046927SAndroid Build Coastguard Worker {
1405*61046927SAndroid Build Coastguard Worker    static const uint16_t short_ops[5] = {
1406*61046927SAndroid Build Coastguard Worker       0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
1407*61046927SAndroid Build Coastguard Worker       X_GLrop_TexCoord4sv
1408*61046927SAndroid Build Coastguard Worker    };
1409*61046927SAndroid Build Coastguard Worker    static const uint16_t int_ops[5] = {
1410*61046927SAndroid Build Coastguard Worker       0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
1411*61046927SAndroid Build Coastguard Worker       X_GLrop_TexCoord4iv
1412*61046927SAndroid Build Coastguard Worker    };
1413*61046927SAndroid Build Coastguard Worker    static const uint16_t float_ops[5] = {
1414*61046927SAndroid Build Coastguard Worker       0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
1415*61046927SAndroid Build Coastguard Worker       X_GLrop_TexCoord4fv
1416*61046927SAndroid Build Coastguard Worker    };
1417*61046927SAndroid Build Coastguard Worker    static const uint16_t double_ops[5] = {
1418*61046927SAndroid Build Coastguard Worker       0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
1419*61046927SAndroid Build Coastguard Worker       X_GLrop_TexCoord4dv
1420*61046927SAndroid Build Coastguard Worker    };
1421*61046927SAndroid Build Coastguard Worker 
1422*61046927SAndroid Build Coastguard Worker    static const uint16_t mshort_ops[5] = {
1423*61046927SAndroid Build Coastguard Worker       0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
1424*61046927SAndroid Build Coastguard Worker       X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
1425*61046927SAndroid Build Coastguard Worker    };
1426*61046927SAndroid Build Coastguard Worker    static const uint16_t mint_ops[5] = {
1427*61046927SAndroid Build Coastguard Worker       0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
1428*61046927SAndroid Build Coastguard Worker       X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
1429*61046927SAndroid Build Coastguard Worker    };
1430*61046927SAndroid Build Coastguard Worker    static const uint16_t mfloat_ops[5] = {
1431*61046927SAndroid Build Coastguard Worker       0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB,
1432*61046927SAndroid Build Coastguard Worker       X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
1433*61046927SAndroid Build Coastguard Worker    };
1434*61046927SAndroid Build Coastguard Worker    static const uint16_t mdouble_ops[5] = {
1435*61046927SAndroid Build Coastguard Worker       0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
1436*61046927SAndroid Build Coastguard Worker       X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
1437*61046927SAndroid Build Coastguard Worker    };
1438*61046927SAndroid Build Coastguard Worker 
1439*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1440*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1441*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1442*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1443*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1444*61046927SAndroid Build Coastguard Worker    unsigned header_size;
1445*61046927SAndroid Build Coastguard Worker    unsigned index;
1446*61046927SAndroid Build Coastguard Worker 
1447*61046927SAndroid Build Coastguard Worker 
1448*61046927SAndroid Build Coastguard Worker    if (size < 1 || size > 4 || stride < 0) {
1449*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1450*61046927SAndroid Build Coastguard Worker       return;
1451*61046927SAndroid Build Coastguard Worker    }
1452*61046927SAndroid Build Coastguard Worker 
1453*61046927SAndroid Build Coastguard Worker    index = arrays->active_texture_unit;
1454*61046927SAndroid Build Coastguard Worker    if (index == 0) {
1455*61046927SAndroid Build Coastguard Worker       switch (type) {
1456*61046927SAndroid Build Coastguard Worker       case GL_SHORT:
1457*61046927SAndroid Build Coastguard Worker          opcode = short_ops[size];
1458*61046927SAndroid Build Coastguard Worker          break;
1459*61046927SAndroid Build Coastguard Worker       case GL_INT:
1460*61046927SAndroid Build Coastguard Worker          opcode = int_ops[size];
1461*61046927SAndroid Build Coastguard Worker          break;
1462*61046927SAndroid Build Coastguard Worker       case GL_FLOAT:
1463*61046927SAndroid Build Coastguard Worker          opcode = float_ops[size];
1464*61046927SAndroid Build Coastguard Worker          break;
1465*61046927SAndroid Build Coastguard Worker       case GL_DOUBLE:
1466*61046927SAndroid Build Coastguard Worker          opcode = double_ops[size];
1467*61046927SAndroid Build Coastguard Worker          break;
1468*61046927SAndroid Build Coastguard Worker       default:
1469*61046927SAndroid Build Coastguard Worker          __glXSetError(gc, GL_INVALID_ENUM);
1470*61046927SAndroid Build Coastguard Worker          return;
1471*61046927SAndroid Build Coastguard Worker       }
1472*61046927SAndroid Build Coastguard Worker 
1473*61046927SAndroid Build Coastguard Worker       header_size = 4;
1474*61046927SAndroid Build Coastguard Worker    }
1475*61046927SAndroid Build Coastguard Worker    else {
1476*61046927SAndroid Build Coastguard Worker       switch (type) {
1477*61046927SAndroid Build Coastguard Worker       case GL_SHORT:
1478*61046927SAndroid Build Coastguard Worker          opcode = mshort_ops[size];
1479*61046927SAndroid Build Coastguard Worker          break;
1480*61046927SAndroid Build Coastguard Worker       case GL_INT:
1481*61046927SAndroid Build Coastguard Worker          opcode = mint_ops[size];
1482*61046927SAndroid Build Coastguard Worker          break;
1483*61046927SAndroid Build Coastguard Worker       case GL_FLOAT:
1484*61046927SAndroid Build Coastguard Worker          opcode = mfloat_ops[size];
1485*61046927SAndroid Build Coastguard Worker          break;
1486*61046927SAndroid Build Coastguard Worker       case GL_DOUBLE:
1487*61046927SAndroid Build Coastguard Worker          opcode = mdouble_ops[size];
1488*61046927SAndroid Build Coastguard Worker          break;
1489*61046927SAndroid Build Coastguard Worker       default:
1490*61046927SAndroid Build Coastguard Worker          __glXSetError(gc, GL_INVALID_ENUM);
1491*61046927SAndroid Build Coastguard Worker          return;
1492*61046927SAndroid Build Coastguard Worker       }
1493*61046927SAndroid Build Coastguard Worker 
1494*61046927SAndroid Build Coastguard Worker       header_size = 8;
1495*61046927SAndroid Build Coastguard Worker    }
1496*61046927SAndroid Build Coastguard Worker 
1497*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
1498*61046927SAndroid Build Coastguard Worker    assert(a != NULL);
1499*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
1500*61046927SAndroid Build Coastguard Worker                           header_size, opcode);
1501*61046927SAndroid Build Coastguard Worker 
1502*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1503*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1504*61046927SAndroid Build Coastguard Worker    }
1505*61046927SAndroid Build Coastguard Worker }
1506*61046927SAndroid Build Coastguard Worker 
1507*61046927SAndroid Build Coastguard Worker 
1508*61046927SAndroid Build Coastguard Worker void
__indirect_glSecondaryColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)1509*61046927SAndroid Build Coastguard Worker __indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,
1510*61046927SAndroid Build Coastguard Worker                                       const GLvoid * pointer)
1511*61046927SAndroid Build Coastguard Worker {
1512*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1513*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1514*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1515*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1516*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1517*61046927SAndroid Build Coastguard Worker 
1518*61046927SAndroid Build Coastguard Worker 
1519*61046927SAndroid Build Coastguard Worker    if (size != 3 || stride < 0) {
1520*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1521*61046927SAndroid Build Coastguard Worker       return;
1522*61046927SAndroid Build Coastguard Worker    }
1523*61046927SAndroid Build Coastguard Worker 
1524*61046927SAndroid Build Coastguard Worker    switch (type) {
1525*61046927SAndroid Build Coastguard Worker    case GL_BYTE:
1526*61046927SAndroid Build Coastguard Worker       opcode = 4126;
1527*61046927SAndroid Build Coastguard Worker       break;
1528*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_BYTE:
1529*61046927SAndroid Build Coastguard Worker       opcode = 4131;
1530*61046927SAndroid Build Coastguard Worker       break;
1531*61046927SAndroid Build Coastguard Worker    case GL_SHORT:
1532*61046927SAndroid Build Coastguard Worker       opcode = 4127;
1533*61046927SAndroid Build Coastguard Worker       break;
1534*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_SHORT:
1535*61046927SAndroid Build Coastguard Worker       opcode = 4132;
1536*61046927SAndroid Build Coastguard Worker       break;
1537*61046927SAndroid Build Coastguard Worker    case GL_INT:
1538*61046927SAndroid Build Coastguard Worker       opcode = 4128;
1539*61046927SAndroid Build Coastguard Worker       break;
1540*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_INT:
1541*61046927SAndroid Build Coastguard Worker       opcode = 4133;
1542*61046927SAndroid Build Coastguard Worker       break;
1543*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1544*61046927SAndroid Build Coastguard Worker       opcode = 4129;
1545*61046927SAndroid Build Coastguard Worker       break;
1546*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1547*61046927SAndroid Build Coastguard Worker       opcode = 4130;
1548*61046927SAndroid Build Coastguard Worker       break;
1549*61046927SAndroid Build Coastguard Worker    default:
1550*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1551*61046927SAndroid Build Coastguard Worker       return;
1552*61046927SAndroid Build Coastguard Worker    }
1553*61046927SAndroid Build Coastguard Worker 
1554*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
1555*61046927SAndroid Build Coastguard Worker    if (a == NULL) {
1556*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_OPERATION);
1557*61046927SAndroid Build Coastguard Worker       return;
1558*61046927SAndroid Build Coastguard Worker    }
1559*61046927SAndroid Build Coastguard Worker 
1560*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1561*61046927SAndroid Build Coastguard Worker 
1562*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1563*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1564*61046927SAndroid Build Coastguard Worker    }
1565*61046927SAndroid Build Coastguard Worker }
1566*61046927SAndroid Build Coastguard Worker 
1567*61046927SAndroid Build Coastguard Worker 
1568*61046927SAndroid Build Coastguard Worker void
__indirect_glFogCoordPointer(GLenum type,GLsizei stride,const GLvoid * pointer)1569*61046927SAndroid Build Coastguard Worker __indirect_glFogCoordPointer(GLenum type, GLsizei stride,
1570*61046927SAndroid Build Coastguard Worker                                 const GLvoid * pointer)
1571*61046927SAndroid Build Coastguard Worker {
1572*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1573*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1574*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1575*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1576*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1577*61046927SAndroid Build Coastguard Worker 
1578*61046927SAndroid Build Coastguard Worker 
1579*61046927SAndroid Build Coastguard Worker    if (stride < 0) {
1580*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1581*61046927SAndroid Build Coastguard Worker       return;
1582*61046927SAndroid Build Coastguard Worker    }
1583*61046927SAndroid Build Coastguard Worker 
1584*61046927SAndroid Build Coastguard Worker    switch (type) {
1585*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1586*61046927SAndroid Build Coastguard Worker       opcode = 4124;
1587*61046927SAndroid Build Coastguard Worker       break;
1588*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1589*61046927SAndroid Build Coastguard Worker       opcode = 4125;
1590*61046927SAndroid Build Coastguard Worker       break;
1591*61046927SAndroid Build Coastguard Worker    default:
1592*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1593*61046927SAndroid Build Coastguard Worker       return;
1594*61046927SAndroid Build Coastguard Worker    }
1595*61046927SAndroid Build Coastguard Worker 
1596*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
1597*61046927SAndroid Build Coastguard Worker    if (a == NULL) {
1598*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_OPERATION);
1599*61046927SAndroid Build Coastguard Worker       return;
1600*61046927SAndroid Build Coastguard Worker    }
1601*61046927SAndroid Build Coastguard Worker 
1602*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1603*61046927SAndroid Build Coastguard Worker 
1604*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1605*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1606*61046927SAndroid Build Coastguard Worker    }
1607*61046927SAndroid Build Coastguard Worker }
1608*61046927SAndroid Build Coastguard Worker 
1609*61046927SAndroid Build Coastguard Worker 
1610*61046927SAndroid Build Coastguard Worker void
__indirect_glVertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * pointer)1611*61046927SAndroid Build Coastguard Worker __indirect_glVertexAttribPointer(GLuint index, GLint size,
1612*61046927SAndroid Build Coastguard Worker                                     GLenum type, GLboolean normalized,
1613*61046927SAndroid Build Coastguard Worker                                     GLsizei stride, const GLvoid * pointer)
1614*61046927SAndroid Build Coastguard Worker {
1615*61046927SAndroid Build Coastguard Worker    static const uint16_t short_ops[5] = {
1616*61046927SAndroid Build Coastguard Worker         0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB,
1617*61046927SAndroid Build Coastguard Worker         X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB
1618*61046927SAndroid Build Coastguard Worker    };
1619*61046927SAndroid Build Coastguard Worker    static const uint16_t float_ops[5] = {
1620*61046927SAndroid Build Coastguard Worker         0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB,
1621*61046927SAndroid Build Coastguard Worker         X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB
1622*61046927SAndroid Build Coastguard Worker    };
1623*61046927SAndroid Build Coastguard Worker    static const uint16_t double_ops[5] = {
1624*61046927SAndroid Build Coastguard Worker         0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB,
1625*61046927SAndroid Build Coastguard Worker         X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB
1626*61046927SAndroid Build Coastguard Worker    };
1627*61046927SAndroid Build Coastguard Worker 
1628*61046927SAndroid Build Coastguard Worker    uint16_t opcode;
1629*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1630*61046927SAndroid Build Coastguard Worker    __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1631*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1632*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1633*61046927SAndroid Build Coastguard Worker    unsigned true_immediate_count;
1634*61046927SAndroid Build Coastguard Worker    unsigned true_immediate_size;
1635*61046927SAndroid Build Coastguard Worker 
1636*61046927SAndroid Build Coastguard Worker 
1637*61046927SAndroid Build Coastguard Worker    if ((size < 1) || (size > 4) || (stride < 0)
1638*61046927SAndroid Build Coastguard Worker        || (index > arrays->num_vertex_program_attribs)) {
1639*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_VALUE);
1640*61046927SAndroid Build Coastguard Worker       return;
1641*61046927SAndroid Build Coastguard Worker    }
1642*61046927SAndroid Build Coastguard Worker 
1643*61046927SAndroid Build Coastguard Worker    if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
1644*61046927SAndroid Build Coastguard Worker       switch (type) {
1645*61046927SAndroid Build Coastguard Worker       case GL_BYTE:
1646*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4NbvARB;
1647*61046927SAndroid Build Coastguard Worker          break;
1648*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_BYTE:
1649*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4NubvARB;
1650*61046927SAndroid Build Coastguard Worker          break;
1651*61046927SAndroid Build Coastguard Worker       case GL_SHORT:
1652*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4NsvARB;
1653*61046927SAndroid Build Coastguard Worker          break;
1654*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_SHORT:
1655*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4NusvARB;
1656*61046927SAndroid Build Coastguard Worker          break;
1657*61046927SAndroid Build Coastguard Worker       case GL_INT:
1658*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4NivARB;
1659*61046927SAndroid Build Coastguard Worker          break;
1660*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_INT:
1661*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4NuivARB;
1662*61046927SAndroid Build Coastguard Worker          break;
1663*61046927SAndroid Build Coastguard Worker       default:
1664*61046927SAndroid Build Coastguard Worker          __glXSetError(gc, GL_INVALID_ENUM);
1665*61046927SAndroid Build Coastguard Worker          return;
1666*61046927SAndroid Build Coastguard Worker       }
1667*61046927SAndroid Build Coastguard Worker 
1668*61046927SAndroid Build Coastguard Worker       true_immediate_count = 4;
1669*61046927SAndroid Build Coastguard Worker    }
1670*61046927SAndroid Build Coastguard Worker    else {
1671*61046927SAndroid Build Coastguard Worker       true_immediate_count = size;
1672*61046927SAndroid Build Coastguard Worker 
1673*61046927SAndroid Build Coastguard Worker       switch (type) {
1674*61046927SAndroid Build Coastguard Worker       case GL_BYTE:
1675*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4bvARB;
1676*61046927SAndroid Build Coastguard Worker          true_immediate_count = 4;
1677*61046927SAndroid Build Coastguard Worker          break;
1678*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_BYTE:
1679*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4ubvARB;
1680*61046927SAndroid Build Coastguard Worker          true_immediate_count = 4;
1681*61046927SAndroid Build Coastguard Worker          break;
1682*61046927SAndroid Build Coastguard Worker       case GL_SHORT:
1683*61046927SAndroid Build Coastguard Worker          opcode = short_ops[size];
1684*61046927SAndroid Build Coastguard Worker          break;
1685*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_SHORT:
1686*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4usvARB;
1687*61046927SAndroid Build Coastguard Worker          true_immediate_count = 4;
1688*61046927SAndroid Build Coastguard Worker          break;
1689*61046927SAndroid Build Coastguard Worker       case GL_INT:
1690*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4ivARB;
1691*61046927SAndroid Build Coastguard Worker          true_immediate_count = 4;
1692*61046927SAndroid Build Coastguard Worker          break;
1693*61046927SAndroid Build Coastguard Worker       case GL_UNSIGNED_INT:
1694*61046927SAndroid Build Coastguard Worker          opcode = X_GLrop_VertexAttrib4uivARB;
1695*61046927SAndroid Build Coastguard Worker          true_immediate_count = 4;
1696*61046927SAndroid Build Coastguard Worker          break;
1697*61046927SAndroid Build Coastguard Worker       case GL_FLOAT:
1698*61046927SAndroid Build Coastguard Worker          opcode = float_ops[size];
1699*61046927SAndroid Build Coastguard Worker          break;
1700*61046927SAndroid Build Coastguard Worker       case GL_DOUBLE:
1701*61046927SAndroid Build Coastguard Worker          opcode = double_ops[size];
1702*61046927SAndroid Build Coastguard Worker          break;
1703*61046927SAndroid Build Coastguard Worker       default:
1704*61046927SAndroid Build Coastguard Worker          __glXSetError(gc, GL_INVALID_ENUM);
1705*61046927SAndroid Build Coastguard Worker          return;
1706*61046927SAndroid Build Coastguard Worker       }
1707*61046927SAndroid Build Coastguard Worker    }
1708*61046927SAndroid Build Coastguard Worker 
1709*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
1710*61046927SAndroid Build Coastguard Worker    if (a == NULL) {
1711*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_OPERATION);
1712*61046927SAndroid Build Coastguard Worker       return;
1713*61046927SAndroid Build Coastguard Worker    }
1714*61046927SAndroid Build Coastguard Worker 
1715*61046927SAndroid Build Coastguard Worker    COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
1716*61046927SAndroid Build Coastguard Worker                           opcode);
1717*61046927SAndroid Build Coastguard Worker 
1718*61046927SAndroid Build Coastguard Worker    true_immediate_size = __glXTypeSize(type) * true_immediate_count;
1719*61046927SAndroid Build Coastguard Worker    a->header[0] = __GLX_PAD(8 + true_immediate_size);
1720*61046927SAndroid Build Coastguard Worker 
1721*61046927SAndroid Build Coastguard Worker    if (a->enabled) {
1722*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1723*61046927SAndroid Build Coastguard Worker    }
1724*61046927SAndroid Build Coastguard Worker }
1725*61046927SAndroid Build Coastguard Worker 
1726*61046927SAndroid Build Coastguard Worker 
1727*61046927SAndroid Build Coastguard Worker /**
1728*61046927SAndroid Build Coastguard Worker  * I don't have 100% confidence that this is correct.  The different rules
1729*61046927SAndroid Build Coastguard Worker  * about whether or not generic vertex attributes alias "classic" vertex
1730*61046927SAndroid Build Coastguard Worker  * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1731*61046927SAndroid Build Coastguard Worker  * ARB_vertex_shader, and NV_vertex_program are a bit confusing.  My
1732*61046927SAndroid Build Coastguard Worker  * feeling is that the client-side doesn't have to worry about it.  The
1733*61046927SAndroid Build Coastguard Worker  * client just sends all the data to the server and lets the server deal
1734*61046927SAndroid Build Coastguard Worker  * with it.
1735*61046927SAndroid Build Coastguard Worker  */
1736*61046927SAndroid Build Coastguard Worker void
__indirect_glVertexAttribPointerNV(GLuint index,GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)1737*61046927SAndroid Build Coastguard Worker __indirect_glVertexAttribPointerNV(GLuint index, GLint size,
1738*61046927SAndroid Build Coastguard Worker                                    GLenum type, GLsizei stride,
1739*61046927SAndroid Build Coastguard Worker                                    const GLvoid * pointer)
1740*61046927SAndroid Build Coastguard Worker {
1741*61046927SAndroid Build Coastguard Worker    struct glx_context *gc = __glXGetCurrentContext();
1742*61046927SAndroid Build Coastguard Worker    GLboolean normalized = GL_FALSE;
1743*61046927SAndroid Build Coastguard Worker 
1744*61046927SAndroid Build Coastguard Worker 
1745*61046927SAndroid Build Coastguard Worker    switch (type) {
1746*61046927SAndroid Build Coastguard Worker    case GL_UNSIGNED_BYTE:
1747*61046927SAndroid Build Coastguard Worker       if (size != 4) {
1748*61046927SAndroid Build Coastguard Worker          __glXSetError(gc, GL_INVALID_VALUE);
1749*61046927SAndroid Build Coastguard Worker          return;
1750*61046927SAndroid Build Coastguard Worker       }
1751*61046927SAndroid Build Coastguard Worker       normalized = GL_TRUE;
1752*61046927SAndroid Build Coastguard Worker       FALLTHROUGH;
1753*61046927SAndroid Build Coastguard Worker    case GL_SHORT:
1754*61046927SAndroid Build Coastguard Worker    case GL_FLOAT:
1755*61046927SAndroid Build Coastguard Worker    case GL_DOUBLE:
1756*61046927SAndroid Build Coastguard Worker       __indirect_glVertexAttribPointer(index, size, type,
1757*61046927SAndroid Build Coastguard Worker                                           normalized, stride, pointer);
1758*61046927SAndroid Build Coastguard Worker       return;
1759*61046927SAndroid Build Coastguard Worker    default:
1760*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1761*61046927SAndroid Build Coastguard Worker       return;
1762*61046927SAndroid Build Coastguard Worker    }
1763*61046927SAndroid Build Coastguard Worker }
1764*61046927SAndroid Build Coastguard Worker 
1765*61046927SAndroid Build Coastguard Worker 
1766*61046927SAndroid Build Coastguard Worker void
__indirect_glClientActiveTexture(GLenum texture)1767*61046927SAndroid Build Coastguard Worker __indirect_glClientActiveTexture(GLenum texture)
1768*61046927SAndroid Build Coastguard Worker {
1769*61046927SAndroid Build Coastguard Worker    struct glx_context *const gc = __glXGetCurrentContext();
1770*61046927SAndroid Build Coastguard Worker    __GLXattribute *const state =
1771*61046927SAndroid Build Coastguard Worker       (__GLXattribute *) (gc->client_state_private);
1772*61046927SAndroid Build Coastguard Worker    struct array_state_vector *const arrays = state->array_state;
1773*61046927SAndroid Build Coastguard Worker    const GLint unit = (GLint) texture - GL_TEXTURE0;
1774*61046927SAndroid Build Coastguard Worker 
1775*61046927SAndroid Build Coastguard Worker 
1776*61046927SAndroid Build Coastguard Worker    if ((unit < 0) || (unit >= arrays->num_texture_units)) {
1777*61046927SAndroid Build Coastguard Worker       __glXSetError(gc, GL_INVALID_ENUM);
1778*61046927SAndroid Build Coastguard Worker       return;
1779*61046927SAndroid Build Coastguard Worker    }
1780*61046927SAndroid Build Coastguard Worker 
1781*61046927SAndroid Build Coastguard Worker    arrays->active_texture_unit = unit;
1782*61046927SAndroid Build Coastguard Worker }
1783*61046927SAndroid Build Coastguard Worker 
1784*61046927SAndroid Build Coastguard Worker 
1785*61046927SAndroid Build Coastguard Worker /**
1786*61046927SAndroid Build Coastguard Worker  * Modify the enable state for the selected array
1787*61046927SAndroid Build Coastguard Worker  */
1788*61046927SAndroid Build Coastguard Worker GLboolean
__glXSetArrayEnable(__GLXattribute * state,GLenum key,unsigned index,GLboolean enable)1789*61046927SAndroid Build Coastguard Worker __glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
1790*61046927SAndroid Build Coastguard Worker                     GLboolean enable)
1791*61046927SAndroid Build Coastguard Worker {
1792*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1793*61046927SAndroid Build Coastguard Worker    struct array_state *a;
1794*61046927SAndroid Build Coastguard Worker 
1795*61046927SAndroid Build Coastguard Worker 
1796*61046927SAndroid Build Coastguard Worker    /* Texture coordinate arrays have an implicit index set when the
1797*61046927SAndroid Build Coastguard Worker     * application calls glClientActiveTexture.
1798*61046927SAndroid Build Coastguard Worker     */
1799*61046927SAndroid Build Coastguard Worker    if (key == GL_TEXTURE_COORD_ARRAY) {
1800*61046927SAndroid Build Coastguard Worker       index = arrays->active_texture_unit;
1801*61046927SAndroid Build Coastguard Worker    }
1802*61046927SAndroid Build Coastguard Worker 
1803*61046927SAndroid Build Coastguard Worker    a = get_array_entry(arrays, key, index);
1804*61046927SAndroid Build Coastguard Worker 
1805*61046927SAndroid Build Coastguard Worker    if ((a != NULL) && (a->enabled != enable)) {
1806*61046927SAndroid Build Coastguard Worker       a->enabled = enable;
1807*61046927SAndroid Build Coastguard Worker       arrays->array_info_cache_valid = GL_FALSE;
1808*61046927SAndroid Build Coastguard Worker    }
1809*61046927SAndroid Build Coastguard Worker 
1810*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1811*61046927SAndroid Build Coastguard Worker }
1812*61046927SAndroid Build Coastguard Worker 
1813*61046927SAndroid Build Coastguard Worker 
1814*61046927SAndroid Build Coastguard Worker void
__glXArrayDisableAll(__GLXattribute * state)1815*61046927SAndroid Build Coastguard Worker __glXArrayDisableAll(__GLXattribute * state)
1816*61046927SAndroid Build Coastguard Worker {
1817*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1818*61046927SAndroid Build Coastguard Worker    unsigned i;
1819*61046927SAndroid Build Coastguard Worker 
1820*61046927SAndroid Build Coastguard Worker 
1821*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
1822*61046927SAndroid Build Coastguard Worker       arrays->arrays[i].enabled = GL_FALSE;
1823*61046927SAndroid Build Coastguard Worker    }
1824*61046927SAndroid Build Coastguard Worker 
1825*61046927SAndroid Build Coastguard Worker    arrays->array_info_cache_valid = GL_FALSE;
1826*61046927SAndroid Build Coastguard Worker }
1827*61046927SAndroid Build Coastguard Worker 
1828*61046927SAndroid Build Coastguard Worker 
1829*61046927SAndroid Build Coastguard Worker /**
1830*61046927SAndroid Build Coastguard Worker  */
1831*61046927SAndroid Build Coastguard Worker GLboolean
__glXGetArrayEnable(const __GLXattribute * const state,GLenum key,unsigned index,GLintptr * dest)1832*61046927SAndroid Build Coastguard Worker __glXGetArrayEnable(const __GLXattribute * const state,
1833*61046927SAndroid Build Coastguard Worker                     GLenum key, unsigned index, GLintptr * dest)
1834*61046927SAndroid Build Coastguard Worker {
1835*61046927SAndroid Build Coastguard Worker    const struct array_state_vector *arrays = state->array_state;
1836*61046927SAndroid Build Coastguard Worker    const struct array_state *a =
1837*61046927SAndroid Build Coastguard Worker       get_array_entry((struct array_state_vector *) arrays,
1838*61046927SAndroid Build Coastguard Worker                       key, index);
1839*61046927SAndroid Build Coastguard Worker 
1840*61046927SAndroid Build Coastguard Worker    if (a != NULL) {
1841*61046927SAndroid Build Coastguard Worker       *dest = (GLintptr) a->enabled;
1842*61046927SAndroid Build Coastguard Worker    }
1843*61046927SAndroid Build Coastguard Worker 
1844*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1845*61046927SAndroid Build Coastguard Worker }
1846*61046927SAndroid Build Coastguard Worker 
1847*61046927SAndroid Build Coastguard Worker 
1848*61046927SAndroid Build Coastguard Worker /**
1849*61046927SAndroid Build Coastguard Worker  */
1850*61046927SAndroid Build Coastguard Worker GLboolean
__glXGetArrayType(const __GLXattribute * const state,GLenum key,unsigned index,GLintptr * dest)1851*61046927SAndroid Build Coastguard Worker __glXGetArrayType(const __GLXattribute * const state,
1852*61046927SAndroid Build Coastguard Worker                   GLenum key, unsigned index, GLintptr * dest)
1853*61046927SAndroid Build Coastguard Worker {
1854*61046927SAndroid Build Coastguard Worker    const struct array_state_vector *arrays = state->array_state;
1855*61046927SAndroid Build Coastguard Worker    const struct array_state *a =
1856*61046927SAndroid Build Coastguard Worker       get_array_entry((struct array_state_vector *) arrays,
1857*61046927SAndroid Build Coastguard Worker                       key, index);
1858*61046927SAndroid Build Coastguard Worker 
1859*61046927SAndroid Build Coastguard Worker    if (a != NULL) {
1860*61046927SAndroid Build Coastguard Worker       *dest = (GLintptr) a->data_type;
1861*61046927SAndroid Build Coastguard Worker    }
1862*61046927SAndroid Build Coastguard Worker 
1863*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1864*61046927SAndroid Build Coastguard Worker }
1865*61046927SAndroid Build Coastguard Worker 
1866*61046927SAndroid Build Coastguard Worker 
1867*61046927SAndroid Build Coastguard Worker /**
1868*61046927SAndroid Build Coastguard Worker  */
1869*61046927SAndroid Build Coastguard Worker GLboolean
__glXGetArraySize(const __GLXattribute * const state,GLenum key,unsigned index,GLintptr * dest)1870*61046927SAndroid Build Coastguard Worker __glXGetArraySize(const __GLXattribute * const state,
1871*61046927SAndroid Build Coastguard Worker                   GLenum key, unsigned index, GLintptr * dest)
1872*61046927SAndroid Build Coastguard Worker {
1873*61046927SAndroid Build Coastguard Worker    const struct array_state_vector *arrays = state->array_state;
1874*61046927SAndroid Build Coastguard Worker    const struct array_state *a =
1875*61046927SAndroid Build Coastguard Worker       get_array_entry((struct array_state_vector *) arrays,
1876*61046927SAndroid Build Coastguard Worker                       key, index);
1877*61046927SAndroid Build Coastguard Worker 
1878*61046927SAndroid Build Coastguard Worker    if (a != NULL) {
1879*61046927SAndroid Build Coastguard Worker       *dest = (GLintptr) a->count;
1880*61046927SAndroid Build Coastguard Worker    }
1881*61046927SAndroid Build Coastguard Worker 
1882*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1883*61046927SAndroid Build Coastguard Worker }
1884*61046927SAndroid Build Coastguard Worker 
1885*61046927SAndroid Build Coastguard Worker 
1886*61046927SAndroid Build Coastguard Worker /**
1887*61046927SAndroid Build Coastguard Worker  */
1888*61046927SAndroid Build Coastguard Worker GLboolean
__glXGetArrayStride(const __GLXattribute * const state,GLenum key,unsigned index,GLintptr * dest)1889*61046927SAndroid Build Coastguard Worker __glXGetArrayStride(const __GLXattribute * const state,
1890*61046927SAndroid Build Coastguard Worker                     GLenum key, unsigned index, GLintptr * dest)
1891*61046927SAndroid Build Coastguard Worker {
1892*61046927SAndroid Build Coastguard Worker    const struct array_state_vector *arrays = state->array_state;
1893*61046927SAndroid Build Coastguard Worker    const struct array_state *a =
1894*61046927SAndroid Build Coastguard Worker       get_array_entry((struct array_state_vector *) arrays,
1895*61046927SAndroid Build Coastguard Worker                       key, index);
1896*61046927SAndroid Build Coastguard Worker 
1897*61046927SAndroid Build Coastguard Worker    if (a != NULL) {
1898*61046927SAndroid Build Coastguard Worker       *dest = (GLintptr) a->user_stride;
1899*61046927SAndroid Build Coastguard Worker    }
1900*61046927SAndroid Build Coastguard Worker 
1901*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1902*61046927SAndroid Build Coastguard Worker }
1903*61046927SAndroid Build Coastguard Worker 
1904*61046927SAndroid Build Coastguard Worker 
1905*61046927SAndroid Build Coastguard Worker /**
1906*61046927SAndroid Build Coastguard Worker  */
1907*61046927SAndroid Build Coastguard Worker GLboolean
__glXGetArrayPointer(const __GLXattribute * const state,GLenum key,unsigned index,void ** dest)1908*61046927SAndroid Build Coastguard Worker __glXGetArrayPointer(const __GLXattribute * const state,
1909*61046927SAndroid Build Coastguard Worker                      GLenum key, unsigned index, void **dest)
1910*61046927SAndroid Build Coastguard Worker {
1911*61046927SAndroid Build Coastguard Worker    const struct array_state_vector *arrays = state->array_state;
1912*61046927SAndroid Build Coastguard Worker    const struct array_state *a =
1913*61046927SAndroid Build Coastguard Worker       get_array_entry((struct array_state_vector *) arrays,
1914*61046927SAndroid Build Coastguard Worker                       key, index);
1915*61046927SAndroid Build Coastguard Worker 
1916*61046927SAndroid Build Coastguard Worker 
1917*61046927SAndroid Build Coastguard Worker    if (a != NULL) {
1918*61046927SAndroid Build Coastguard Worker       *dest = (void *) (a->data);
1919*61046927SAndroid Build Coastguard Worker    }
1920*61046927SAndroid Build Coastguard Worker 
1921*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1922*61046927SAndroid Build Coastguard Worker }
1923*61046927SAndroid Build Coastguard Worker 
1924*61046927SAndroid Build Coastguard Worker 
1925*61046927SAndroid Build Coastguard Worker /**
1926*61046927SAndroid Build Coastguard Worker  */
1927*61046927SAndroid Build Coastguard Worker GLboolean
__glXGetArrayNormalized(const __GLXattribute * const state,GLenum key,unsigned index,GLintptr * dest)1928*61046927SAndroid Build Coastguard Worker __glXGetArrayNormalized(const __GLXattribute * const state,
1929*61046927SAndroid Build Coastguard Worker                         GLenum key, unsigned index, GLintptr * dest)
1930*61046927SAndroid Build Coastguard Worker {
1931*61046927SAndroid Build Coastguard Worker    const struct array_state_vector *arrays = state->array_state;
1932*61046927SAndroid Build Coastguard Worker    const struct array_state *a =
1933*61046927SAndroid Build Coastguard Worker       get_array_entry((struct array_state_vector *) arrays,
1934*61046927SAndroid Build Coastguard Worker                       key, index);
1935*61046927SAndroid Build Coastguard Worker 
1936*61046927SAndroid Build Coastguard Worker 
1937*61046927SAndroid Build Coastguard Worker    if (a != NULL) {
1938*61046927SAndroid Build Coastguard Worker       *dest = (GLintptr) a->normalized;
1939*61046927SAndroid Build Coastguard Worker    }
1940*61046927SAndroid Build Coastguard Worker 
1941*61046927SAndroid Build Coastguard Worker    return (a != NULL);
1942*61046927SAndroid Build Coastguard Worker }
1943*61046927SAndroid Build Coastguard Worker 
1944*61046927SAndroid Build Coastguard Worker 
1945*61046927SAndroid Build Coastguard Worker /**
1946*61046927SAndroid Build Coastguard Worker  */
1947*61046927SAndroid Build Coastguard Worker GLuint
__glXGetActiveTextureUnit(const __GLXattribute * const state)1948*61046927SAndroid Build Coastguard Worker __glXGetActiveTextureUnit(const __GLXattribute * const state)
1949*61046927SAndroid Build Coastguard Worker {
1950*61046927SAndroid Build Coastguard Worker    return state->array_state->active_texture_unit;
1951*61046927SAndroid Build Coastguard Worker }
1952*61046927SAndroid Build Coastguard Worker 
1953*61046927SAndroid Build Coastguard Worker 
1954*61046927SAndroid Build Coastguard Worker void
__glXPushArrayState(__GLXattribute * state)1955*61046927SAndroid Build Coastguard Worker __glXPushArrayState(__GLXattribute * state)
1956*61046927SAndroid Build Coastguard Worker {
1957*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1958*61046927SAndroid Build Coastguard Worker    struct array_stack_state *stack =
1959*61046927SAndroid Build Coastguard Worker       &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1960*61046927SAndroid Build Coastguard Worker    unsigned i;
1961*61046927SAndroid Build Coastguard Worker 
1962*61046927SAndroid Build Coastguard Worker    /* XXX are we pushing _all_ the necessary fields? */
1963*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
1964*61046927SAndroid Build Coastguard Worker       stack[i].data = arrays->arrays[i].data;
1965*61046927SAndroid Build Coastguard Worker       stack[i].data_type = arrays->arrays[i].data_type;
1966*61046927SAndroid Build Coastguard Worker       stack[i].user_stride = arrays->arrays[i].user_stride;
1967*61046927SAndroid Build Coastguard Worker       stack[i].count = arrays->arrays[i].count;
1968*61046927SAndroid Build Coastguard Worker       stack[i].key = arrays->arrays[i].key;
1969*61046927SAndroid Build Coastguard Worker       stack[i].index = arrays->arrays[i].index;
1970*61046927SAndroid Build Coastguard Worker       stack[i].enabled = arrays->arrays[i].enabled;
1971*61046927SAndroid Build Coastguard Worker    }
1972*61046927SAndroid Build Coastguard Worker 
1973*61046927SAndroid Build Coastguard Worker    arrays->active_texture_unit_stack[arrays->stack_index] =
1974*61046927SAndroid Build Coastguard Worker       arrays->active_texture_unit;
1975*61046927SAndroid Build Coastguard Worker 
1976*61046927SAndroid Build Coastguard Worker    arrays->stack_index++;
1977*61046927SAndroid Build Coastguard Worker }
1978*61046927SAndroid Build Coastguard Worker 
1979*61046927SAndroid Build Coastguard Worker 
1980*61046927SAndroid Build Coastguard Worker void
__glXPopArrayState(__GLXattribute * state)1981*61046927SAndroid Build Coastguard Worker __glXPopArrayState(__GLXattribute * state)
1982*61046927SAndroid Build Coastguard Worker {
1983*61046927SAndroid Build Coastguard Worker    struct array_state_vector *arrays = state->array_state;
1984*61046927SAndroid Build Coastguard Worker    struct array_stack_state *stack;
1985*61046927SAndroid Build Coastguard Worker    unsigned i;
1986*61046927SAndroid Build Coastguard Worker 
1987*61046927SAndroid Build Coastguard Worker 
1988*61046927SAndroid Build Coastguard Worker    arrays->stack_index--;
1989*61046927SAndroid Build Coastguard Worker    stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1990*61046927SAndroid Build Coastguard Worker 
1991*61046927SAndroid Build Coastguard Worker    for (i = 0; i < arrays->num_arrays; i++) {
1992*61046927SAndroid Build Coastguard Worker       switch (stack[i].key) {
1993*61046927SAndroid Build Coastguard Worker       case GL_NORMAL_ARRAY:
1994*61046927SAndroid Build Coastguard Worker          __indirect_glNormalPointer(stack[i].data_type,
1995*61046927SAndroid Build Coastguard Worker                                     stack[i].user_stride, stack[i].data);
1996*61046927SAndroid Build Coastguard Worker          break;
1997*61046927SAndroid Build Coastguard Worker       case GL_COLOR_ARRAY:
1998*61046927SAndroid Build Coastguard Worker          __indirect_glColorPointer(stack[i].count,
1999*61046927SAndroid Build Coastguard Worker                                    stack[i].data_type,
2000*61046927SAndroid Build Coastguard Worker                                    stack[i].user_stride, stack[i].data);
2001*61046927SAndroid Build Coastguard Worker          break;
2002*61046927SAndroid Build Coastguard Worker       case GL_INDEX_ARRAY:
2003*61046927SAndroid Build Coastguard Worker          __indirect_glIndexPointer(stack[i].data_type,
2004*61046927SAndroid Build Coastguard Worker                                    stack[i].user_stride, stack[i].data);
2005*61046927SAndroid Build Coastguard Worker          break;
2006*61046927SAndroid Build Coastguard Worker       case GL_EDGE_FLAG_ARRAY:
2007*61046927SAndroid Build Coastguard Worker          __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
2008*61046927SAndroid Build Coastguard Worker          break;
2009*61046927SAndroid Build Coastguard Worker       case GL_TEXTURE_COORD_ARRAY:
2010*61046927SAndroid Build Coastguard Worker          arrays->active_texture_unit = stack[i].index;
2011*61046927SAndroid Build Coastguard Worker          __indirect_glTexCoordPointer(stack[i].count,
2012*61046927SAndroid Build Coastguard Worker                                       stack[i].data_type,
2013*61046927SAndroid Build Coastguard Worker                                       stack[i].user_stride, stack[i].data);
2014*61046927SAndroid Build Coastguard Worker          break;
2015*61046927SAndroid Build Coastguard Worker       case GL_SECONDARY_COLOR_ARRAY:
2016*61046927SAndroid Build Coastguard Worker          __indirect_glSecondaryColorPointer(stack[i].count,
2017*61046927SAndroid Build Coastguard Worker                                                stack[i].data_type,
2018*61046927SAndroid Build Coastguard Worker                                                stack[i].user_stride,
2019*61046927SAndroid Build Coastguard Worker                                                stack[i].data);
2020*61046927SAndroid Build Coastguard Worker          break;
2021*61046927SAndroid Build Coastguard Worker       case GL_FOG_COORDINATE_ARRAY:
2022*61046927SAndroid Build Coastguard Worker          __indirect_glFogCoordPointer(stack[i].data_type,
2023*61046927SAndroid Build Coastguard Worker                                          stack[i].user_stride, stack[i].data);
2024*61046927SAndroid Build Coastguard Worker          break;
2025*61046927SAndroid Build Coastguard Worker 
2026*61046927SAndroid Build Coastguard Worker       }
2027*61046927SAndroid Build Coastguard Worker 
2028*61046927SAndroid Build Coastguard Worker       __glXSetArrayEnable(state, stack[i].key, stack[i].index,
2029*61046927SAndroid Build Coastguard Worker                           stack[i].enabled);
2030*61046927SAndroid Build Coastguard Worker    }
2031*61046927SAndroid Build Coastguard Worker 
2032*61046927SAndroid Build Coastguard Worker    arrays->active_texture_unit =
2033*61046927SAndroid Build Coastguard Worker       arrays->active_texture_unit_stack[arrays->stack_index];
2034*61046927SAndroid Build Coastguard Worker }
2035