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