blob: 115f755bb7d31d88f5d27773db700b97b76286c1 [file] [log] [blame]
Ian Romanickfdb07632005-02-22 22:36:31 +00001/*
2 * (C) Copyright IBM Corporation 2004, 2005
3 * All Rights Reserved.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02004 *
Ian Romanickfdb07632005-02-22 22:36:31 +00005 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020011 *
Ian Romanickfdb07632005-02-22 22:36:31 +000012 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020015 *
Ian Romanickfdb07632005-02-22 22:36:31 +000016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * IBM,
20 * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 */
25
26#include <inttypes.h>
27#include <assert.h>
Ian Romanickfdb07632005-02-22 22:36:31 +000028#include <string.h>
29
Ian Romanick03dc4372005-02-28 19:37:10 +000030#include "glxclient.h"
31#include "indirect.h"
Ian Romanickfdb07632005-02-22 22:36:31 +000032#include <GL/glxproto.h>
33#include "glxextensions.h"
34#include "indirect_vertex_array.h"
George Sapountzisf027f8d2008-04-18 17:28:53 +030035#include "indirect_vertex_array_priv.h"
Ian Romanickfdb07632005-02-22 22:36:31 +000036
Ian Romanick03dc4372005-02-28 19:37:10 +000037#define __GLX_PAD(n) (((n)+3) & ~3)
38
Ian Romanickfdb07632005-02-22 22:36:31 +000039/**
40 * \file indirect_vertex_array.c
41 * Implement GLX protocol for vertex arrays and vertex buffer objects.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020042 *
Ian Romanickfdb07632005-02-22 22:36:31 +000043 * The most important function in this fill is \c fill_array_info_cache.
44 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
45 * in the DrawArrays protocol. Certain operations, such as enabling or
46 * disabling an array, can invalidate this cache. \c fill_array_info_cache
47 * fills-in this data. Additionally, it examines the enabled state and
48 * other factors to determine what "version" of DrawArrays protocoal can be
49 * used.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020050 *
Ian Romanickfdb07632005-02-22 22:36:31 +000051 * Current, only two versions of DrawArrays protocol are implemented. The
52 * first version is the "none" protocol. This is the fallback when the
53 * server does not support GL 1.1 / EXT_vertex_arrays. It is implemented
54 * by sending batches of immediate mode commands that are equivalent to the
55 * DrawArrays protocol.
56 *
57 * The other protocol that is currently implemented is the "old" protocol.
58 * This is the GL 1.1 DrawArrays protocol. The only difference between GL
59 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
60 * This protocol is called "old" because the ARB is in the process of
61 * defining a new protocol, which will probably be called wither "new" or
62 * "vbo", to support multiple texture coordinate arrays, generic attributes,
63 * and vertex buffer objects.
64 *
Ian Romanick27e3f7f2008-07-15 11:06:31 -070065 * \author Ian Romanick <ian.d.romanick@intel.com>
Ian Romanickfdb07632005-02-22 22:36:31 +000066 */
67
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +020068static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count);
69static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count);
Ian Romanickfdb07632005-02-22 22:36:31 +000070
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +020071static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
72 const GLvoid * indices);
73static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
74 const GLvoid * indices);
Ian Romanickfdb07632005-02-22 22:36:31 +000075
76
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +020077static GLubyte *emit_element_none(GLubyte * dst,
78 const struct array_state_vector *arrays,
79 unsigned index);
80static GLubyte *emit_element_old(GLubyte * dst,
81 const struct array_state_vector *arrays,
82 unsigned index);
83static struct array_state *get_array_entry(const struct array_state_vector
84 *arrays, GLenum key,
85 unsigned index);
86static void fill_array_info_cache(struct array_state_vector *arrays);
Kristian Høgsbergc356f582010-07-28 11:16:00 -040087static GLboolean validate_mode(struct glx_context * gc, GLenum mode);
88static GLboolean validate_count(struct glx_context * gc, GLsizei count);
89static GLboolean validate_type(struct glx_context * gc, GLenum type);
Ian Romanickfdb07632005-02-22 22:36:31 +000090
91
92/**
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020093 * Table of sizes, in bytes, of a GL types. All of the type enums are be in
Ian Romanickfdb07632005-02-22 22:36:31 +000094 * the range 0x1400 - 0x140F. That includes types added by extensions (i.e.,
95 * \c GL_HALF_FLOAT_NV). This elements of this table correspond to the
96 * type enums masked with 0x0f.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +020097 *
Ian Romanickfdb07632005-02-22 22:36:31 +000098 * \notes
99 * \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES,
100 * \c GL_3_BYTES, or \c GL_4_BYTES.
101 */
102const GLuint __glXTypeSize_table[16] = {
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200103 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
Ian Romanickfdb07632005-02-22 22:36:31 +0000104};
105
106
Kristof Raloviche2060342008-08-20 15:18:38 -0600107/**
108 * Free the per-context array state that was allocated with
109 * __glXInitVertexArrayState().
110 */
111void
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400112__glXFreeVertexArrayState(struct glx_context * gc)
Kristof Raloviche2060342008-08-20 15:18:38 -0600113{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200114 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
115 struct array_state_vector *arrays = state->array_state;
Kristof Raloviche2060342008-08-20 15:18:38 -0600116
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200117 if (arrays) {
118 if (arrays->stack) {
119 free(arrays->stack);
120 arrays->stack = NULL;
121 }
122 if (arrays->arrays) {
123 free(arrays->arrays);
124 arrays->arrays = NULL;
125 }
126 free(arrays);
127 state->array_state = NULL;
128 }
Kristof Raloviche2060342008-08-20 15:18:38 -0600129}
130
Ian Romanickfdb07632005-02-22 22:36:31 +0000131
132/**
133 * Initialize vertex array state of a GLX context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200134 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000135 * \param gc GLX context whose vertex array state is to be initialized.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200136 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000137 * \warning
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400138 * This function may only be called after struct glx_context::gl_extension_bits,
139 * struct glx_context::server_minor, and __GLXcontext::server_major have been
Ian Romanickfdb07632005-02-22 22:36:31 +0000140 * initialized. These values are used to determine what vertex arrays are
141 * supported.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200142 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000143 * \bug
144 * Return values from malloc are not properly tested.
145 */
146void
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400147__glXInitVertexArrayState(struct glx_context * gc)
Ian Romanickfdb07632005-02-22 22:36:31 +0000148{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200149 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
150 struct array_state_vector *arrays;
Ian Romanickfdb07632005-02-22 22:36:31 +0000151
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200152 unsigned array_count;
153 int texture_units = 1, vertex_program_attribs = 0;
154 unsigned i, j;
Ian Romanickfdb07632005-02-22 22:36:31 +0000155
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200156 GLboolean got_fog = GL_FALSE;
157 GLboolean got_secondary_color = GL_FALSE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000158
159
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200160 arrays = calloc(1, sizeof(struct array_state_vector));
161 state->array_state = arrays;
Ian Romanickfdb07632005-02-22 22:36:31 +0000162
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200163 arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
164 arrays->new_DrawArrays_possible = GL_FALSE;
165 arrays->DrawArrays = NULL;
Ian Romanickfdb07632005-02-22 22:36:31 +0000166
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200167 arrays->active_texture_unit = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000168
169
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200170 /* Determine how many arrays are actually needed. Only arrays that
171 * are supported by the server are create. For example, if the server
172 * supports only 2 texture units, then only 2 texture coordinate arrays
173 * are created.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200174 *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200175 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
176 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
177 * GL_EDGE_FLAG_ARRAY are supported.
178 */
Ian Romanick979f35f2005-03-17 20:36:20 +0000179
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200180 array_count = 5;
Ian Romanickfdb07632005-02-22 22:36:31 +0000181
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200182 if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
183 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
184 got_fog = GL_TRUE;
185 array_count++;
186 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000187
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200188 if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
189 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
190 got_secondary_color = GL_TRUE;
191 array_count++;
192 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000193
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200194 if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit)
195 || (gc->server_major > 1) || (gc->server_minor >= 3)) {
196 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
197 }
Ian Romanick40af76b2005-02-25 22:46:30 +0000198
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200199 if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) {
200 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
201 GL_MAX_PROGRAM_ATTRIBS_ARB,
202 &vertex_program_attribs);
203 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000204
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200205 arrays->num_texture_units = texture_units;
206 arrays->num_vertex_program_attribs = vertex_program_attribs;
207 array_count += texture_units + vertex_program_attribs;
208 arrays->num_arrays = array_count;
209 arrays->arrays = calloc(array_count, sizeof(struct array_state));
Ian Romanickfdb07632005-02-22 22:36:31 +0000210
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200211 arrays->arrays[0].data_type = GL_FLOAT;
212 arrays->arrays[0].count = 3;
213 arrays->arrays[0].key = GL_NORMAL_ARRAY;
214 arrays->arrays[0].normalized = GL_TRUE;
215 arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000216
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200217 arrays->arrays[1].data_type = GL_FLOAT;
218 arrays->arrays[1].count = 4;
219 arrays->arrays[1].key = GL_COLOR_ARRAY;
220 arrays->arrays[1].normalized = GL_TRUE;
221 arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000222
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200223 arrays->arrays[2].data_type = GL_FLOAT;
224 arrays->arrays[2].count = 1;
225 arrays->arrays[2].key = GL_INDEX_ARRAY;
226 arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000227
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200228 arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
229 arrays->arrays[3].count = 1;
230 arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
231 arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
Ian Romanick40af76b2005-02-25 22:46:30 +0000232
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200233 for (i = 0; i < texture_units; i++) {
234 arrays->arrays[4 + i].data_type = GL_FLOAT;
235 arrays->arrays[4 + i].count = 4;
236 arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
Ian Romanickfdb07632005-02-22 22:36:31 +0000237
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200238 arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
239 arrays->arrays[4 + i].index = i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000240
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200241 arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0;
242 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000243
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200244 i = 4 + texture_units;
245
246 if (got_fog) {
247 arrays->arrays[i].data_type = GL_FLOAT;
248 arrays->arrays[i].count = 1;
249 arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
250 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
251 i++;
252 }
253
254 if (got_secondary_color) {
255 arrays->arrays[i].data_type = GL_FLOAT;
256 arrays->arrays[i].count = 3;
257 arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
258 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
259 arrays->arrays[i].normalized = GL_TRUE;
260 i++;
261 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000262
263
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200264 for (j = 0; j < vertex_program_attribs; j++) {
265 const unsigned idx = (vertex_program_attribs - (j + 1));
Ian Romanick40af76b2005-02-25 22:46:30 +0000266
267
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200268 arrays->arrays[idx + i].data_type = GL_FLOAT;
269 arrays->arrays[idx + i].count = 4;
270 arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
Ian Romanick40af76b2005-02-25 22:46:30 +0000271
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200272 arrays->arrays[idx + i].old_DrawArrays_possible = 0;
273 arrays->arrays[idx + i].index = idx;
Ian Romanick40af76b2005-02-25 22:46:30 +0000274
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200275 arrays->arrays[idx + i].header[1] = idx;
276 }
Ian Romanick40af76b2005-02-25 22:46:30 +0000277
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200278 i += vertex_program_attribs;
Ian Romanick40af76b2005-02-25 22:46:30 +0000279
280
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200281 /* Vertex array *must* be last becuase of the way that
282 * emit_DrawArrays_none works.
283 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000284
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200285 arrays->arrays[i].data_type = GL_FLOAT;
286 arrays->arrays[i].count = 4;
287 arrays->arrays[i].key = GL_VERTEX_ARRAY;
288 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000289
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200290 assert((i + 1) == arrays->num_arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000291
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200292 arrays->stack_index = 0;
293 arrays->stack = malloc(sizeof(struct array_stack_state)
Markus Fleschutz83f11832010-02-26 10:34:19 -0700294 * arrays->num_arrays
295 * __GL_CLIENT_ATTRIB_STACK_DEPTH);
Ian Romanickfdb07632005-02-22 22:36:31 +0000296}
297
298
299/**
300 * Calculate the size of a single vertex for the "none" protocol. This is
301 * essentially the size of all the immediate-mode commands required to
302 * implement the enabled vertex arrays.
303 */
304static size_t
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200305calculate_single_vertex_size_none(const struct array_state_vector *arrays)
Ian Romanickfdb07632005-02-22 22:36:31 +0000306{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200307 size_t single_vertex_size = 0;
308 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000309
310
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200311 for (i = 0; i < arrays->num_arrays; i++) {
312 if (arrays->arrays[i].enabled) {
313 single_vertex_size += ((uint16_t *) arrays->arrays[i].header)[0];
314 }
315 }
316
317 return single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000318}
319
320
321/**
322 * Emit a single element using non-DrawArrays protocol.
323 */
324GLubyte *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200325emit_element_none(GLubyte * dst,
326 const struct array_state_vector * arrays, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000327{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200328 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000329
330
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200331 for (i = 0; i < arrays->num_arrays; i++) {
332 if (arrays->arrays[i].enabled) {
333 const size_t offset = index * arrays->arrays[i].true_stride;
Ian Romanickfdb07632005-02-22 22:36:31 +0000334
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200335 /* The generic attributes can have more data than is in the
336 * elements. This is because a vertex array can be a 2 element,
337 * normalized, unsigned short, but the "closest" immediate mode
338 * protocol is for a 4Nus. Since the sizes are small, the
339 * performance impact on modern processors should be negligible.
340 */
341 (void) memset(dst, 0, ((uint16_t *) arrays->arrays[i].header)[0]);
Ian Romanick40af76b2005-02-25 22:46:30 +0000342
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200343 (void) memcpy(dst, arrays->arrays[i].header,
344 arrays->arrays[i].header_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000345
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200346 dst += arrays->arrays[i].header_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000347
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200348 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
349 arrays->arrays[i].element_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000350
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200351 dst += __GLX_PAD(arrays->arrays[i].element_size);
352 }
353 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000354
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200355 return dst;
Ian Romanickfdb07632005-02-22 22:36:31 +0000356}
357
358
359/**
360 * Emit a single element using "old" DrawArrays protocol from
361 * EXT_vertex_arrays / OpenGL 1.1.
362 */
363GLubyte *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200364emit_element_old(GLubyte * dst,
365 const struct array_state_vector * arrays, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000366{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200367 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000368
369
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200370 for (i = 0; i < arrays->num_arrays; i++) {
371 if (arrays->arrays[i].enabled) {
372 const size_t offset = index * arrays->arrays[i].true_stride;
Ian Romanickfdb07632005-02-22 22:36:31 +0000373
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200374 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
375 arrays->arrays[i].element_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000376
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200377 dst += __GLX_PAD(arrays->arrays[i].element_size);
378 }
379 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000380
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200381 return dst;
Ian Romanickfdb07632005-02-22 22:36:31 +0000382}
383
384
385struct array_state *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200386get_array_entry(const struct array_state_vector *arrays,
387 GLenum key, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000388{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200389 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000390
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200391 for (i = 0; i < arrays->num_arrays; i++) {
392 if ((arrays->arrays[i].key == key)
393 && (arrays->arrays[i].index == index)) {
394 return &arrays->arrays[i];
395 }
396 }
397
398 return NULL;
Ian Romanickfdb07632005-02-22 22:36:31 +0000399}
400
401
402static GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200403allocate_array_info_cache(struct array_state_vector *arrays,
404 size_t required_size)
Ian Romanickfdb07632005-02-22 22:36:31 +0000405{
Ian Romanick979f35f2005-03-17 20:36:20 +0000406#define MAX_HEADER_SIZE 20
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200407 if (arrays->array_info_cache_buffer_size < required_size) {
408 GLubyte *temp = realloc(arrays->array_info_cache_base,
409 required_size + MAX_HEADER_SIZE);
Ian Romanickfdb07632005-02-22 22:36:31 +0000410
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200411 if (temp == NULL) {
412 return GL_FALSE;
413 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000414
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200415 arrays->array_info_cache_base = temp;
416 arrays->array_info_cache = temp + MAX_HEADER_SIZE;
417 arrays->array_info_cache_buffer_size = required_size;
418 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000419
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200420 arrays->array_info_cache_size = required_size;
421 return GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000422}
423
424
425/**
426 */
427void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200428fill_array_info_cache(struct array_state_vector *arrays)
Ian Romanickfdb07632005-02-22 22:36:31 +0000429{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200430 GLboolean old_DrawArrays_possible;
431 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000432
433
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200434 /* Determine how many arrays are enabled.
435 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000436
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200437 arrays->enabled_client_array_count = 0;
438 old_DrawArrays_possible = arrays->old_DrawArrays_possible;
439 for (i = 0; i < arrays->num_arrays; i++) {
440 if (arrays->arrays[i].enabled) {
441 arrays->enabled_client_array_count++;
442 old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
443 }
444 }
445
446 if (arrays->new_DrawArrays_possible) {
447 assert(!arrays->new_DrawArrays_possible);
448 }
449 else if (old_DrawArrays_possible) {
450 const size_t required_size = arrays->enabled_client_array_count * 12;
451 uint32_t *info;
Ian Romanickfdb07632005-02-22 22:36:31 +0000452
453
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200454 if (!allocate_array_info_cache(arrays, required_size)) {
455 return;
456 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000457
458
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200459 info = (uint32_t *) arrays->array_info_cache;
460 for (i = 0; i < arrays->num_arrays; i++) {
461 if (arrays->arrays[i].enabled) {
462 *(info++) = arrays->arrays[i].data_type;
463 *(info++) = arrays->arrays[i].count;
464 *(info++) = arrays->arrays[i].key;
465 }
466 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000467
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200468 arrays->DrawArrays = emit_DrawArrays_old;
469 arrays->DrawElements = emit_DrawElements_old;
470 }
471 else {
472 arrays->DrawArrays = emit_DrawArrays_none;
473 arrays->DrawElements = emit_DrawElements_none;
474 }
Ian Romanickb81efaa2005-03-17 20:13:09 +0000475
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200476 arrays->array_info_cache_valid = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000477}
478
479
480/**
481 * Emit a \c glDrawArrays command using the "none" protocol. That is,
482 * emit immediate-mode commands that are equivalent to the requiested
483 * \c glDrawArrays command. This is used with servers that don't support
484 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
485 * vertex state is enabled that is not compatible with that protocol.
486 */
487void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200488emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000489{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400490 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200491 const __GLXattribute *state =
492 (const __GLXattribute *) (gc->client_state_private);
493 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000494
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200495 size_t single_vertex_size;
496 GLubyte *pc;
497 unsigned i;
498 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
499 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
Ian Romanickfdb07632005-02-22 22:36:31 +0000500
501
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200502 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000503
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200504 pc = gc->pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000505
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200506 (void) memcpy(pc, begin_cmd, 4);
507 *(int *) (pc + 4) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000508
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200509 pc += 8;
Ian Romanickfdb07632005-02-22 22:36:31 +0000510
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200511 for (i = 0; i < count; i++) {
512 if ((pc + single_vertex_size) >= gc->bufEnd) {
513 pc = __glXFlushRenderBuffer(gc, pc);
514 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000515
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200516 pc = emit_element_none(pc, arrays, first + i);
517 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000518
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200519 if ((pc + 4) >= gc->bufEnd) {
520 pc = __glXFlushRenderBuffer(gc, pc);
521 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000522
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200523 (void) memcpy(pc, end_cmd, 4);
524 pc += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000525
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200526 gc->pc = pc;
527 if (gc->pc > gc->limit) {
528 (void) __glXFlushRenderBuffer(gc, gc->pc);
529 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000530}
531
532
533/**
534 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
535 * protocol.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200536 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000537 * \param gc GLX context.
538 * \param arrays Array state.
539 * \param elements_per_request Location to store the number of elements that
540 * can fit in a single Render / RenderLarge
541 * command.
542 * \param total_request Total number of requests for a RenderLarge
543 * command. If a Render command is used, this
544 * will be zero.
545 * \param mode Drawing mode.
546 * \param count Number of vertices.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200547 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000548 * \returns
549 * A pointer to the buffer for array data.
550 */
551static GLubyte *
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400552emit_DrawArrays_header_old(struct glx_context * gc,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200553 struct array_state_vector *arrays,
554 size_t * elements_per_request,
555 unsigned int *total_requests,
556 GLenum mode, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000557{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200558 size_t command_size;
559 size_t single_vertex_size;
560 const unsigned header_size = 16;
561 unsigned i;
562 GLubyte *pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000563
564
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200565 /* Determine the size of the whole command. This includes the header,
566 * the ARRAY_INFO data and the array data. Once this size is calculated,
567 * it will be known whether a Render or RenderLarge command is needed.
568 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000569
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200570 single_vertex_size = 0;
571 for (i = 0; i < arrays->num_arrays; i++) {
572 if (arrays->arrays[i].enabled) {
573 single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
574 }
575 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000576
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200577 command_size = arrays->array_info_cache_size + header_size
Ian Romanickfdb07632005-02-22 22:36:31 +0000578 + (single_vertex_size * count);
579
580
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200581 /* Write the header for either a Render command or a RenderLarge
582 * command. After the header is written, write the ARRAY_INFO data.
583 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000584
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200585 if (command_size > gc->maxSmallRenderCommandSize) {
586 /* maxSize is the maximum amount of data can be stuffed into a single
587 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
588 * packet size minus sz_xGLXRenderReq.
589 */
590 const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
591 - sz_xGLXRenderLargeReq;
592 unsigned vertex_requests;
Ian Romanickfdb07632005-02-22 22:36:31 +0000593
594
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200595 /* Calculate the number of data packets that will be required to send
596 * the whole command. To do this, the number of verticies that
597 * will fit in a single buffer must be calculated.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200598 *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200599 * The important value here is elements_per_request. This is the
600 * number of complete array elements that will fit in a single
601 * buffer. There may be some wasted space at the end of the buffer,
602 * but splitting elements across buffer boundries would be painful.
603 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000604
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200605 elements_per_request[0] = maxSize / single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000606
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200607 vertex_requests = (count + elements_per_request[0] - 1)
608 / elements_per_request[0];
609
610 *total_requests = vertex_requests + 1;
Ian Romanickfdb07632005-02-22 22:36:31 +0000611
612
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200613 __glXFlushRenderBuffer(gc, gc->pc);
Ian Romanickfdb07632005-02-22 22:36:31 +0000614
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200615 command_size += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000616
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200617 pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
618 *(uint32_t *) (pc + 0) = command_size;
619 *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
620 *(uint32_t *) (pc + 8) = count;
621 *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
622 *(uint32_t *) (pc + 16) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000623
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200624 __glXSendLargeChunk(gc, 1, *total_requests, pc,
625 header_size + 4 + arrays->array_info_cache_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000626
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200627 pc = gc->pc;
628 }
629 else {
630 if ((gc->pc + command_size) >= gc->bufEnd) {
631 (void) __glXFlushRenderBuffer(gc, gc->pc);
632 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000633
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200634 pc = gc->pc;
635 *(uint16_t *) (pc + 0) = command_size;
636 *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
637 *(uint32_t *) (pc + 4) = count;
638 *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
639 *(uint32_t *) (pc + 12) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000640
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200641 pc += header_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000642
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200643 (void) memcpy(pc, arrays->array_info_cache,
644 arrays->array_info_cache_size);
645 pc += arrays->array_info_cache_size;
Ian Romanickb81efaa2005-03-17 20:13:09 +0000646
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200647 *elements_per_request = count;
648 *total_requests = 0;
649 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000650
651
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200652 return pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000653}
654
655
656/**
657 */
658void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200659emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000660{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400661 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200662 const __GLXattribute *state =
663 (const __GLXattribute *) (gc->client_state_private);
664 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000665
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200666 GLubyte *pc;
667 size_t elements_per_request;
668 unsigned total_requests = 0;
669 unsigned i;
670 size_t total_sent = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000671
672
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200673 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
674 &total_requests, mode, count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000675
676
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200677 /* Write the arrays.
678 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000679
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200680 if (total_requests == 0) {
681 assert(elements_per_request >= count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000682
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200683 for (i = 0; i < count; i++) {
684 pc = emit_element_old(pc, arrays, i + first);
685 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000686
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200687 assert(pc <= gc->bufEnd);
Ian Romanickfdb07632005-02-22 22:36:31 +0000688
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200689 gc->pc = pc;
690 if (gc->pc > gc->limit) {
691 (void) __glXFlushRenderBuffer(gc, gc->pc);
692 }
693 }
694 else {
695 unsigned req;
696
697
698 for (req = 2; req <= total_requests; req++) {
699 if (count < elements_per_request) {
700 elements_per_request = count;
701 }
702
703 pc = gc->pc;
704 for (i = 0; i < elements_per_request; i++) {
705 pc = emit_element_old(pc, arrays, i + first);
706 }
707
708 first += elements_per_request;
709
710 total_sent += (size_t) (pc - gc->pc);
711 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
712
713 count -= elements_per_request;
714 }
715 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000716}
717
718
719void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200720emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
721 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000722{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400723 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200724 const __GLXattribute *state =
725 (const __GLXattribute *) (gc->client_state_private);
726 struct array_state_vector *arrays = state->array_state;
727 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
728 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
Ian Romanickfdb07632005-02-22 22:36:31 +0000729
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200730 GLubyte *pc;
731 size_t single_vertex_size;
732 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000733
734
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200735 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000736
737
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200738 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
739 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
740 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000741
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200742 pc = gc->pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000743
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200744 (void) memcpy(pc, begin_cmd, 4);
745 *(int *) (pc + 4) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000746
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200747 pc += 8;
Ian Romanickfdb07632005-02-22 22:36:31 +0000748
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200749 for (i = 0; i < count; i++) {
750 unsigned index = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000751
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200752 if ((pc + single_vertex_size) >= gc->bufEnd) {
753 pc = __glXFlushRenderBuffer(gc, pc);
754 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000755
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200756 switch (type) {
757 case GL_UNSIGNED_INT:
758 index = (unsigned) (((GLuint *) indices)[i]);
759 break;
760 case GL_UNSIGNED_SHORT:
761 index = (unsigned) (((GLushort *) indices)[i]);
762 break;
763 case GL_UNSIGNED_BYTE:
764 index = (unsigned) (((GLubyte *) indices)[i]);
765 break;
766 }
767 pc = emit_element_none(pc, arrays, index);
768 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000769
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200770 if ((pc + 4) >= gc->bufEnd) {
771 pc = __glXFlushRenderBuffer(gc, pc);
772 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000773
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200774 (void) memcpy(pc, end_cmd, 4);
775 pc += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000776
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200777 gc->pc = pc;
778 if (gc->pc > gc->limit) {
779 (void) __glXFlushRenderBuffer(gc, gc->pc);
780 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000781}
782
783
784/**
785 */
786void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200787emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
788 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000789{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400790 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200791 const __GLXattribute *state =
792 (const __GLXattribute *) (gc->client_state_private);
793 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000794
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200795 GLubyte *pc;
796 size_t elements_per_request;
797 unsigned total_requests = 0;
798 unsigned i;
799 unsigned req;
800 unsigned req_element = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000801
802
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200803 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
804 &total_requests, mode, count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000805
806
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200807 /* Write the arrays.
808 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000809
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200810 req = 2;
811 while (count > 0) {
812 if (count < elements_per_request) {
813 elements_per_request = count;
814 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000815
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200816 switch (type) {
817 case GL_UNSIGNED_INT:{
818 const GLuint *ui_ptr = (const GLuint *) indices + req_element;
819
820 for (i = 0; i < elements_per_request; i++) {
821 const GLint index = (GLint) * (ui_ptr++);
822 pc = emit_element_old(pc, arrays, index);
823 }
824 break;
825 }
826 case GL_UNSIGNED_SHORT:{
827 const GLushort *us_ptr = (const GLushort *) indices + req_element;
828
829 for (i = 0; i < elements_per_request; i++) {
830 const GLint index = (GLint) * (us_ptr++);
831 pc = emit_element_old(pc, arrays, index);
832 }
833 break;
834 }
835 case GL_UNSIGNED_BYTE:{
836 const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;
837
838 for (i = 0; i < elements_per_request; i++) {
839 const GLint index = (GLint) * (ub_ptr++);
840 pc = emit_element_old(pc, arrays, index);
841 }
842 break;
843 }
844 }
845
846 if (total_requests != 0) {
847 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
848 pc = gc->pc;
849 req++;
850 }
851
852 count -= elements_per_request;
853 req_element += elements_per_request;
854 }
855
856
857 assert((total_requests == 0) || ((req - 1) == total_requests));
858
859 if (total_requests == 0) {
860 assert(pc <= gc->bufEnd);
861
862 gc->pc = pc;
863 if (gc->pc > gc->limit) {
864 (void) __glXFlushRenderBuffer(gc, gc->pc);
865 }
866 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000867}
868
869
870/**
871 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
872 * If it is not valid, then an error code is set in the GLX context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200873 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000874 * \returns
875 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
876 */
877static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400878validate_mode(struct glx_context * gc, GLenum mode)
Ian Romanickfdb07632005-02-22 22:36:31 +0000879{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200880 switch (mode) {
881 case GL_POINTS:
882 case GL_LINE_STRIP:
883 case GL_LINE_LOOP:
884 case GL_LINES:
885 case GL_TRIANGLE_STRIP:
886 case GL_TRIANGLE_FAN:
887 case GL_TRIANGLES:
888 case GL_QUAD_STRIP:
889 case GL_QUADS:
890 case GL_POLYGON:
891 break;
892 default:
893 __glXSetError(gc, GL_INVALID_ENUM);
894 return GL_FALSE;
895 }
896
897 return GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000898}
899
900
901/**
902 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
903 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
904 * being set. A value of zero will not result in an error being set, but
905 * will result in \c GL_FALSE being returned.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200906 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000907 * \returns
908 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
909 */
910static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400911validate_count(struct glx_context * gc, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000912{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200913 if (count < 0) {
914 __glXSetError(gc, GL_INVALID_VALUE);
915 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000916
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200917 return (count > 0);
Ian Romanickfdb07632005-02-22 22:36:31 +0000918}
919
920
Ian Romanick03dc4372005-02-28 19:37:10 +0000921/**
922 * Validate that the \c type parameter to \c glDrawElements, et. al. is
923 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
924 * \c GL_UNSIGNED_INT are valid.
925 *
926 * \returns
927 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
928 */
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200929static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400930validate_type(struct glx_context * gc, GLenum type)
Ian Romanick03dc4372005-02-28 19:37:10 +0000931{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200932 switch (type) {
933 case GL_UNSIGNED_INT:
934 case GL_UNSIGNED_SHORT:
935 case GL_UNSIGNED_BYTE:
936 return GL_TRUE;
937 default:
938 __glXSetError(gc, GL_INVALID_ENUM);
939 return GL_FALSE;
940 }
Ian Romanick03dc4372005-02-28 19:37:10 +0000941}
942
943
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200944void
945__indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000946{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400947 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200948 const __GLXattribute *state =
949 (const __GLXattribute *) (gc->client_state_private);
950 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000951
Ian Romanickfdb07632005-02-22 22:36:31 +0000952
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200953 if (validate_mode(gc, mode) && validate_count(gc, count)) {
954 if (!arrays->array_info_cache_valid) {
955 fill_array_info_cache(arrays);
956 }
957
958 arrays->DrawArrays(mode, first, count);
959 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000960}
961
962
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200963void
964__indirect_glArrayElement(GLint index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000965{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400966 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200967 const __GLXattribute *state =
968 (const __GLXattribute *) (gc->client_state_private);
969 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000970
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200971 size_t single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000972
973
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200974 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000975
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200976 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
977 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
978 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000979
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200980 gc->pc = emit_element_none(gc->pc, arrays, index);
Ian Romanickfdb07632005-02-22 22:36:31 +0000981
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200982 if (gc->pc > gc->limit) {
983 (void) __glXFlushRenderBuffer(gc, gc->pc);
984 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000985}
986
987
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200988void
989__indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
990 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000991{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400992 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200993 const __GLXattribute *state =
994 (const __GLXattribute *) (gc->client_state_private);
995 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000996
997
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200998 if (validate_mode(gc, mode) && validate_count(gc, count)
999 && validate_type(gc, type)) {
1000 if (!arrays->array_info_cache_valid) {
1001 fill_array_info_cache(arrays);
1002 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001003
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001004 arrays->DrawElements(mode, count, type, indices);
1005 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001006}
1007
1008
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001009void
1010__indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1011 GLsizei count, GLenum type,
1012 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +00001013{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001014 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001015 const __GLXattribute *state =
1016 (const __GLXattribute *) (gc->client_state_private);
1017 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +00001018
1019
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001020 if (validate_mode(gc, mode) && validate_count(gc, count)
1021 && validate_type(gc, type)) {
1022 if (end < start) {
1023 __glXSetError(gc, GL_INVALID_VALUE);
1024 return;
1025 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001026
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001027 if (!arrays->array_info_cache_valid) {
1028 fill_array_info_cache(arrays);
1029 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001030
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001031 arrays->DrawElements(mode, count, type, indices);
1032 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001033}
1034
1035
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001036void
Brian Paul4cd751b2010-09-14 11:01:03 -06001037__indirect_glMultiDrawArraysEXT(GLenum mode, const GLint *first,
1038 const GLsizei *count, GLsizei primcount)
Ian Romanickfdb07632005-02-22 22:36:31 +00001039{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001040 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001041 const __GLXattribute *state =
1042 (const __GLXattribute *) (gc->client_state_private);
1043 struct array_state_vector *arrays = state->array_state;
1044 GLsizei i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001045
1046
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001047 if (validate_mode(gc, mode)) {
1048 if (!arrays->array_info_cache_valid) {
1049 fill_array_info_cache(arrays);
1050 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001051
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001052 for (i = 0; i < primcount; i++) {
1053 if (validate_count(gc, count[i])) {
1054 arrays->DrawArrays(mode, first[i], count[i]);
1055 }
1056 }
1057 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001058}
1059
1060
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001061void
1062__indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
1063 GLenum type, const GLvoid ** indices,
1064 GLsizei primcount)
Ian Romanickfdb07632005-02-22 22:36:31 +00001065{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001066 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001067 const __GLXattribute *state =
1068 (const __GLXattribute *) (gc->client_state_private);
1069 struct array_state_vector *arrays = state->array_state;
1070 GLsizei i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001071
1072
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001073 if (validate_mode(gc, mode) && validate_type(gc, type)) {
1074 if (!arrays->array_info_cache_valid) {
1075 fill_array_info_cache(arrays);
1076 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001077
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001078 for (i = 0; i < primcount; i++) {
1079 if (validate_count(gc, count[i])) {
1080 arrays->DrawElements(mode, count[i], type, indices[i]);
1081 }
1082 }
1083 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001084}
1085
1086
Ian Romanickb81efaa2005-03-17 20:13:09 +00001087#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001088 do { \
1089 (a)->data = PTR; \
1090 (a)->data_type = TYPE; \
1091 (a)->user_stride = STRIDE; \
1092 (a)->count = COUNT; \
1093 (a)->normalized = NORMALIZED; \
1094 \
1095 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1096 (a)->true_stride = (STRIDE == 0) \
1097 ? (a)->element_size : STRIDE; \
1098 \
1099 (a)->header_size = HDR_SIZE; \
1100 ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1101 ((uint16_t *) (a)->header)[1] = OPCODE; \
1102 } while(0)
Ian Romanickfdb07632005-02-22 22:36:31 +00001103
1104
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001105void
1106__indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
1107 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001108{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001109 static const uint16_t short_ops[5] = {
1110 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1111 };
1112 static const uint16_t int_ops[5] = {
1113 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1114 };
1115 static const uint16_t float_ops[5] = {
1116 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1117 };
1118 static const uint16_t double_ops[5] = {
1119 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1120 };
1121 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001122 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001123 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1124 struct array_state_vector *arrays = state->array_state;
1125 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001126
1127
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001128 if (size < 2 || size > 4 || stride < 0) {
1129 __glXSetError(gc, GL_INVALID_VALUE);
1130 return;
1131 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001132
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001133 switch (type) {
1134 case GL_SHORT:
1135 opcode = short_ops[size];
1136 break;
1137 case GL_INT:
1138 opcode = int_ops[size];
1139 break;
1140 case GL_FLOAT:
1141 opcode = float_ops[size];
1142 break;
1143 case GL_DOUBLE:
1144 opcode = double_ops[size];
1145 break;
1146 default:
1147 __glXSetError(gc, GL_INVALID_ENUM);
1148 return;
1149 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001150
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001151 a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
1152 assert(a != NULL);
1153 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
1154 opcode);
1155
1156 if (a->enabled) {
1157 arrays->array_info_cache_valid = GL_FALSE;
1158 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001159}
1160
1161
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001162void
1163__indirect_glNormalPointer(GLenum type, GLsizei stride,
1164 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001165{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001166 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001167 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001168 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1169 struct array_state_vector *arrays = state->array_state;
1170 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001171
1172
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001173 if (stride < 0) {
1174 __glXSetError(gc, GL_INVALID_VALUE);
1175 return;
1176 }
Ian Romanickb81efaa2005-03-17 20:13:09 +00001177
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001178 switch (type) {
1179 case GL_BYTE:
1180 opcode = X_GLrop_Normal3bv;
1181 break;
1182 case GL_SHORT:
1183 opcode = X_GLrop_Normal3sv;
1184 break;
1185 case GL_INT:
1186 opcode = X_GLrop_Normal3iv;
1187 break;
1188 case GL_FLOAT:
1189 opcode = X_GLrop_Normal3fv;
1190 break;
1191 case GL_DOUBLE:
1192 opcode = X_GLrop_Normal3dv;
1193 break;
1194 default:
1195 __glXSetError(gc, GL_INVALID_ENUM);
1196 return;
1197 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001198
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001199 a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
1200 assert(a != NULL);
1201 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);
Ian Romanickfdb07632005-02-22 22:36:31 +00001202
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001203 if (a->enabled) {
1204 arrays->array_info_cache_valid = GL_FALSE;
1205 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001206}
1207
1208
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001209void
1210__indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
1211 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001212{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001213 static const uint16_t byte_ops[5] = {
1214 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1215 };
1216 static const uint16_t ubyte_ops[5] = {
1217 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1218 };
1219 static const uint16_t short_ops[5] = {
1220 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1221 };
1222 static const uint16_t ushort_ops[5] = {
1223 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1224 };
1225 static const uint16_t int_ops[5] = {
1226 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1227 };
1228 static const uint16_t uint_ops[5] = {
1229 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1230 };
1231 static const uint16_t float_ops[5] = {
1232 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1233 };
1234 static const uint16_t double_ops[5] = {
1235 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1236 };
1237 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001238 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001239 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1240 struct array_state_vector *arrays = state->array_state;
1241 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001242
1243
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001244 if (size < 3 || size > 4 || stride < 0) {
1245 __glXSetError(gc, GL_INVALID_VALUE);
1246 return;
1247 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001248
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001249 switch (type) {
1250 case GL_BYTE:
1251 opcode = byte_ops[size];
1252 break;
1253 case GL_UNSIGNED_BYTE:
1254 opcode = ubyte_ops[size];
1255 break;
1256 case GL_SHORT:
1257 opcode = short_ops[size];
1258 break;
1259 case GL_UNSIGNED_SHORT:
1260 opcode = ushort_ops[size];
1261 break;
1262 case GL_INT:
1263 opcode = int_ops[size];
1264 break;
1265 case GL_UNSIGNED_INT:
1266 opcode = uint_ops[size];
1267 break;
1268 case GL_FLOAT:
1269 opcode = float_ops[size];
1270 break;
1271 case GL_DOUBLE:
1272 opcode = double_ops[size];
1273 break;
1274 default:
1275 __glXSetError(gc, GL_INVALID_ENUM);
1276 return;
1277 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001278
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001279 a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
1280 assert(a != NULL);
1281 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1282
1283 if (a->enabled) {
1284 arrays->array_info_cache_valid = GL_FALSE;
1285 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001286}
1287
1288
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001289void
1290__indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001291{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001292 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001293 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001294 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1295 struct array_state_vector *arrays = state->array_state;
1296 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001297
1298
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001299 if (stride < 0) {
1300 __glXSetError(gc, GL_INVALID_VALUE);
1301 return;
1302 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001303
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001304 switch (type) {
1305 case GL_UNSIGNED_BYTE:
1306 opcode = X_GLrop_Indexubv;
1307 break;
1308 case GL_SHORT:
1309 opcode = X_GLrop_Indexsv;
1310 break;
1311 case GL_INT:
1312 opcode = X_GLrop_Indexiv;
1313 break;
1314 case GL_FLOAT:
1315 opcode = X_GLrop_Indexfv;
1316 break;
1317 case GL_DOUBLE:
1318 opcode = X_GLrop_Indexdv;
1319 break;
1320 default:
1321 __glXSetError(gc, GL_INVALID_ENUM);
1322 return;
1323 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001324
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001325 a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
1326 assert(a != NULL);
1327 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1328
1329 if (a->enabled) {
1330 arrays->array_info_cache_valid = GL_FALSE;
1331 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001332}
1333
1334
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001335void
1336__indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001337{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001338 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001339 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1340 struct array_state_vector *arrays = state->array_state;
1341 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001342
1343
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001344 if (stride < 0) {
1345 __glXSetError(gc, GL_INVALID_VALUE);
1346 return;
1347 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001348
Ian Romanickfdb07632005-02-22 22:36:31 +00001349
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001350 a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
1351 assert(a != NULL);
1352 COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1353 4, X_GLrop_EdgeFlagv);
1354
1355 if (a->enabled) {
1356 arrays->array_info_cache_valid = GL_FALSE;
1357 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001358}
1359
1360
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001361void
1362__indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
1363 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001364{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001365 static const uint16_t short_ops[5] = {
1366 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001367 X_GLrop_TexCoord4sv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001368 };
1369 static const uint16_t int_ops[5] = {
1370 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001371 X_GLrop_TexCoord4iv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001372 };
1373 static const uint16_t float_ops[5] = {
1374 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001375 X_GLrop_TexCoord4fv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001376 };
1377 static const uint16_t double_ops[5] = {
1378 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001379 X_GLrop_TexCoord4dv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001380 };
Ian Romanickfdb07632005-02-22 22:36:31 +00001381
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001382 static const uint16_t mshort_ops[5] = {
1383 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001384 X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001385 };
1386 static const uint16_t mint_ops[5] = {
1387 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001388 X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001389 };
1390 static const uint16_t mfloat_ops[5] = {
1391 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001392 X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001393 };
1394 static const uint16_t mdouble_ops[5] = {
1395 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001396 X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001397 };
Ian Romanickfdb07632005-02-22 22:36:31 +00001398
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001399 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001400 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001401 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1402 struct array_state_vector *arrays = state->array_state;
1403 struct array_state *a;
1404 unsigned header_size;
1405 unsigned index;
Ian Romanickfdb07632005-02-22 22:36:31 +00001406
1407
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001408 if (size < 1 || size > 4 || stride < 0) {
1409 __glXSetError(gc, GL_INVALID_VALUE);
1410 return;
1411 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001412
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001413 index = arrays->active_texture_unit;
1414 if (index == 0) {
1415 switch (type) {
1416 case GL_SHORT:
1417 opcode = short_ops[size];
1418 break;
1419 case GL_INT:
1420 opcode = int_ops[size];
1421 break;
1422 case GL_FLOAT:
1423 opcode = float_ops[size];
1424 break;
1425 case GL_DOUBLE:
1426 opcode = double_ops[size];
1427 break;
1428 default:
1429 __glXSetError(gc, GL_INVALID_ENUM);
1430 return;
1431 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001432
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001433 header_size = 4;
1434 }
1435 else {
1436 switch (type) {
1437 case GL_SHORT:
1438 opcode = mshort_ops[size];
1439 break;
1440 case GL_INT:
1441 opcode = mint_ops[size];
1442 break;
1443 case GL_FLOAT:
1444 opcode = mfloat_ops[size];
1445 break;
1446 case GL_DOUBLE:
1447 opcode = mdouble_ops[size];
1448 break;
1449 default:
1450 __glXSetError(gc, GL_INVALID_ENUM);
1451 return;
1452 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001453
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001454 header_size = 8;
1455 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001456
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001457 a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
1458 assert(a != NULL);
1459 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
1460 header_size, opcode);
1461
1462 if (a->enabled) {
1463 arrays->array_info_cache_valid = GL_FALSE;
1464 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001465}
1466
1467
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001468void
1469__indirect_glSecondaryColorPointerEXT(GLint size, GLenum type, GLsizei stride,
1470 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001471{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001472 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001473 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001474 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1475 struct array_state_vector *arrays = state->array_state;
1476 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001477
1478
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001479 if (size != 3 || stride < 0) {
1480 __glXSetError(gc, GL_INVALID_VALUE);
1481 return;
1482 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001483
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001484 switch (type) {
1485 case GL_BYTE:
1486 opcode = 4126;
1487 break;
1488 case GL_UNSIGNED_BYTE:
1489 opcode = 4131;
1490 break;
1491 case GL_SHORT:
1492 opcode = 4127;
1493 break;
1494 case GL_UNSIGNED_SHORT:
1495 opcode = 4132;
1496 break;
1497 case GL_INT:
1498 opcode = 4128;
1499 break;
1500 case GL_UNSIGNED_INT:
1501 opcode = 4133;
1502 break;
1503 case GL_FLOAT:
1504 opcode = 4129;
1505 break;
1506 case GL_DOUBLE:
1507 opcode = 4130;
1508 break;
1509 default:
1510 __glXSetError(gc, GL_INVALID_ENUM);
1511 return;
1512 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001513
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001514 a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
1515 if (a == NULL) {
1516 __glXSetError(gc, GL_INVALID_OPERATION);
1517 return;
1518 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001519
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001520 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1521
1522 if (a->enabled) {
1523 arrays->array_info_cache_valid = GL_FALSE;
1524 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001525}
1526
1527
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001528void
1529__indirect_glFogCoordPointerEXT(GLenum type, GLsizei stride,
1530 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001531{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001532 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001533 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001534 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1535 struct array_state_vector *arrays = state->array_state;
1536 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001537
1538
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001539 if (stride < 0) {
1540 __glXSetError(gc, GL_INVALID_VALUE);
1541 return;
1542 }
Ian Romanickb81efaa2005-03-17 20:13:09 +00001543
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001544 switch (type) {
1545 case GL_FLOAT:
1546 opcode = 4124;
1547 break;
1548 case GL_DOUBLE:
1549 opcode = 4125;
1550 break;
1551 default:
1552 __glXSetError(gc, GL_INVALID_ENUM);
1553 return;
1554 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001555
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001556 a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
1557 if (a == NULL) {
1558 __glXSetError(gc, GL_INVALID_OPERATION);
1559 return;
1560 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001561
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001562 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
Ian Romanickfdb07632005-02-22 22:36:31 +00001563
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001564 if (a->enabled) {
1565 arrays->array_info_cache_valid = GL_FALSE;
1566 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001567}
1568
1569
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001570void
1571__indirect_glVertexAttribPointerARB(GLuint index, GLint size,
1572 GLenum type, GLboolean normalized,
1573 GLsizei stride, const GLvoid * pointer)
Ian Romanick40af76b2005-02-25 22:46:30 +00001574{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001575 static const uint16_t short_ops[5] = { 0, 4189, 4190, 4191, 4192 };
1576 static const uint16_t float_ops[5] = { 0, 4193, 4194, 4195, 4196 };
1577 static const uint16_t double_ops[5] = { 0, 4197, 4198, 4199, 4200 };
Ian Romanick40af76b2005-02-25 22:46:30 +00001578
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001579 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001580 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001581 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1582 struct array_state_vector *arrays = state->array_state;
1583 struct array_state *a;
1584 unsigned true_immediate_count;
1585 unsigned true_immediate_size;
Ian Romanick40af76b2005-02-25 22:46:30 +00001586
1587
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001588 if ((size < 1) || (size > 4) || (stride < 0)
1589 || (index > arrays->num_vertex_program_attribs)) {
1590 __glXSetError(gc, GL_INVALID_VALUE);
1591 return;
1592 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001593
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001594 if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
1595 switch (type) {
1596 case GL_BYTE:
1597 opcode = X_GLrop_VertexAttrib4NbvARB;
1598 break;
1599 case GL_UNSIGNED_BYTE:
1600 opcode = X_GLrop_VertexAttrib4NubvARB;
1601 break;
1602 case GL_SHORT:
1603 opcode = X_GLrop_VertexAttrib4NsvARB;
1604 break;
1605 case GL_UNSIGNED_SHORT:
1606 opcode = X_GLrop_VertexAttrib4NusvARB;
1607 break;
1608 case GL_INT:
1609 opcode = X_GLrop_VertexAttrib4NivARB;
1610 break;
1611 case GL_UNSIGNED_INT:
1612 opcode = X_GLrop_VertexAttrib4NuivARB;
1613 break;
1614 default:
1615 __glXSetError(gc, GL_INVALID_ENUM);
1616 return;
1617 }
Ian Romanick03dc4372005-02-28 19:37:10 +00001618
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001619 true_immediate_count = 4;
1620 }
1621 else {
1622 true_immediate_count = size;
Ian Romanick40af76b2005-02-25 22:46:30 +00001623
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001624 switch (type) {
1625 case GL_BYTE:
1626 opcode = X_GLrop_VertexAttrib4bvARB;
1627 true_immediate_count = 4;
1628 break;
1629 case GL_UNSIGNED_BYTE:
1630 opcode = X_GLrop_VertexAttrib4ubvARB;
1631 true_immediate_count = 4;
1632 break;
1633 case GL_SHORT:
1634 opcode = short_ops[size];
1635 break;
1636 case GL_UNSIGNED_SHORT:
1637 opcode = X_GLrop_VertexAttrib4usvARB;
1638 true_immediate_count = 4;
1639 break;
1640 case GL_INT:
1641 opcode = X_GLrop_VertexAttrib4ivARB;
1642 true_immediate_count = 4;
1643 break;
1644 case GL_UNSIGNED_INT:
1645 opcode = X_GLrop_VertexAttrib4uivARB;
1646 true_immediate_count = 4;
1647 break;
1648 case GL_FLOAT:
1649 opcode = float_ops[size];
1650 break;
1651 case GL_DOUBLE:
1652 opcode = double_ops[size];
1653 break;
1654 default:
1655 __glXSetError(gc, GL_INVALID_ENUM);
1656 return;
1657 }
1658 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001659
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001660 a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
1661 if (a == NULL) {
1662 __glXSetError(gc, GL_INVALID_OPERATION);
1663 return;
1664 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001665
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001666 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
1667 opcode);
Ian Romanick40af76b2005-02-25 22:46:30 +00001668
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001669 true_immediate_size = __glXTypeSize(type) * true_immediate_count;
1670 ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size
1671 + true_immediate_size);
1672
1673 if (a->enabled) {
1674 arrays->array_info_cache_valid = GL_FALSE;
1675 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001676}
1677
1678
1679/**
1680 * I don't have 100% confidence that this is correct. The different rules
1681 * about whether or not generic vertex attributes alias "classic" vertex
1682 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1683 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1684 * feeling is that the client-side doesn't have to worry about it. The
1685 * client just sends all the data to the server and lets the server deal
1686 * with it.
1687 */
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001688void
1689__indirect_glVertexAttribPointerNV(GLuint index, GLint size,
1690 GLenum type, GLsizei stride,
1691 const GLvoid * pointer)
Ian Romanick40af76b2005-02-25 22:46:30 +00001692{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001693 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001694 GLboolean normalized = GL_FALSE;
Ian Romanick40af76b2005-02-25 22:46:30 +00001695
1696
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001697 switch (type) {
1698 case GL_UNSIGNED_BYTE:
1699 if (size != 4) {
1700 __glXSetError(gc, GL_INVALID_VALUE);
1701 return;
1702 }
1703 normalized = GL_TRUE;
Ian Romanick40af76b2005-02-25 22:46:30 +00001704
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001705 case GL_SHORT:
1706 case GL_FLOAT:
1707 case GL_DOUBLE:
1708 __indirect_glVertexAttribPointerARB(index, size, type,
1709 normalized, stride, pointer);
1710 return;
1711 default:
1712 __glXSetError(gc, GL_INVALID_ENUM);
1713 return;
1714 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001715}
1716
1717
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001718void
1719__indirect_glClientActiveTextureARB(GLenum texture)
Ian Romanickfdb07632005-02-22 22:36:31 +00001720{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001721 struct glx_context *const gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001722 __GLXattribute *const state =
1723 (__GLXattribute *) (gc->client_state_private);
1724 struct array_state_vector *const arrays = state->array_state;
1725 const GLint unit = (GLint) texture - GL_TEXTURE0;
Ian Romanickfdb07632005-02-22 22:36:31 +00001726
1727
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001728 if ((unit < 0) || (unit >= arrays->num_texture_units)) {
1729 __glXSetError(gc, GL_INVALID_ENUM);
1730 return;
1731 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001732
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001733 arrays->active_texture_unit = unit;
Ian Romanickfdb07632005-02-22 22:36:31 +00001734}
1735
1736
1737/**
Ian Romanick67108ad2008-07-15 11:06:04 -07001738 * Modify the enable state for the selected array
Ian Romanickfdb07632005-02-22 22:36:31 +00001739 */
1740GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001741__glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
Ian Romanick67108ad2008-07-15 11:06:04 -07001742 GLboolean enable)
Ian Romanickfdb07632005-02-22 22:36:31 +00001743{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001744 struct array_state_vector *arrays = state->array_state;
1745 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001746
Ian Romanickfdb07632005-02-22 22:36:31 +00001747
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001748 /* Texture coordinate arrays have an implict index set when the
1749 * application calls glClientActiveTexture.
1750 */
1751 if (key == GL_TEXTURE_COORD_ARRAY) {
1752 index = arrays->active_texture_unit;
1753 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001754
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001755 a = get_array_entry(arrays, key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001756
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001757 if ((a != NULL) && (a->enabled != enable)) {
1758 a->enabled = enable;
1759 arrays->array_info_cache_valid = GL_FALSE;
1760 }
1761
1762 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001763}
1764
1765
1766void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001767__glXArrayDisableAll(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001768{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001769 struct array_state_vector *arrays = state->array_state;
1770 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001771
1772
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001773 for (i = 0; i < arrays->num_arrays; i++) {
1774 arrays->arrays[i].enabled = GL_FALSE;
1775 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001776
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001777 arrays->array_info_cache_valid = GL_FALSE;
Ian Romanickfdb07632005-02-22 22:36:31 +00001778}
1779
1780
1781/**
1782 */
1783GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001784__glXGetArrayEnable(const __GLXattribute * const state,
1785 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001786{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001787 const struct array_state_vector *arrays = state->array_state;
1788 const struct array_state *a =
1789 get_array_entry((struct array_state_vector *) arrays,
1790 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001791
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001792 if (a != NULL) {
1793 *dest = (GLintptr) a->enabled;
1794 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001795
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001796 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001797}
1798
1799
1800/**
1801 */
1802GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001803__glXGetArrayType(const __GLXattribute * const state,
1804 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001805{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001806 const struct array_state_vector *arrays = state->array_state;
1807 const struct array_state *a =
1808 get_array_entry((struct array_state_vector *) arrays,
1809 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001810
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001811 if (a != NULL) {
1812 *dest = (GLintptr) a->data_type;
1813 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001814
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001815 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001816}
1817
1818
1819/**
1820 */
1821GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001822__glXGetArraySize(const __GLXattribute * const state,
1823 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001824{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001825 const struct array_state_vector *arrays = state->array_state;
1826 const struct array_state *a =
1827 get_array_entry((struct array_state_vector *) arrays,
1828 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001829
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001830 if (a != NULL) {
1831 *dest = (GLintptr) a->count;
1832 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001833
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001834 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001835}
1836
1837
1838/**
1839 */
1840GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001841__glXGetArrayStride(const __GLXattribute * const state,
1842 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001843{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001844 const struct array_state_vector *arrays = state->array_state;
1845 const struct array_state *a =
1846 get_array_entry((struct array_state_vector *) arrays,
1847 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001848
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001849 if (a != NULL) {
1850 *dest = (GLintptr) a->user_stride;
1851 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001852
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001853 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001854}
1855
1856
1857/**
1858 */
1859GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001860__glXGetArrayPointer(const __GLXattribute * const state,
1861 GLenum key, unsigned index, void **dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001862{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001863 const struct array_state_vector *arrays = state->array_state;
1864 const struct array_state *a =
1865 get_array_entry((struct array_state_vector *) arrays,
1866 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001867
1868
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001869 if (a != NULL) {
1870 *dest = (void *) (a->data);
1871 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001872
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001873 return (a != NULL);
Ian Romanick40af76b2005-02-25 22:46:30 +00001874}
1875
1876
1877/**
1878 */
1879GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001880__glXGetArrayNormalized(const __GLXattribute * const state,
1881 GLenum key, unsigned index, GLintptr * dest)
Ian Romanick40af76b2005-02-25 22:46:30 +00001882{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001883 const struct array_state_vector *arrays = state->array_state;
1884 const struct array_state *a =
1885 get_array_entry((struct array_state_vector *) arrays,
1886 key, index);
Ian Romanick40af76b2005-02-25 22:46:30 +00001887
1888
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001889 if (a != NULL) {
1890 *dest = (GLintptr) a->normalized;
1891 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001892
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001893 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001894}
1895
1896
1897/**
1898 */
1899GLuint
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001900__glXGetActiveTextureUnit(const __GLXattribute * const state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001901{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001902 return state->array_state->active_texture_unit;
Ian Romanickfdb07632005-02-22 22:36:31 +00001903}
1904
1905
1906void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001907__glXPushArrayState(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001908{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001909 struct array_state_vector *arrays = state->array_state;
1910 struct array_stack_state *stack =
1911 &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1912 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001913
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001914 /* XXX are we pushing _all_ the necessary fields? */
1915 for (i = 0; i < arrays->num_arrays; i++) {
1916 stack[i].data = arrays->arrays[i].data;
1917 stack[i].data_type = arrays->arrays[i].data_type;
1918 stack[i].user_stride = arrays->arrays[i].user_stride;
1919 stack[i].count = arrays->arrays[i].count;
1920 stack[i].key = arrays->arrays[i].key;
1921 stack[i].index = arrays->arrays[i].index;
1922 stack[i].enabled = arrays->arrays[i].enabled;
1923 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001924
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001925 arrays->active_texture_unit_stack[arrays->stack_index] =
Ian Romanickfdb07632005-02-22 22:36:31 +00001926 arrays->active_texture_unit;
1927
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001928 arrays->stack_index++;
Ian Romanickfdb07632005-02-22 22:36:31 +00001929}
1930
1931
1932void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001933__glXPopArrayState(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001934{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001935 struct array_state_vector *arrays = state->array_state;
1936 struct array_stack_state *stack;
1937 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001938
1939
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001940 arrays->stack_index--;
1941 stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
Ian Romanickfdb07632005-02-22 22:36:31 +00001942
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001943 for (i = 0; i < arrays->num_arrays; i++) {
1944 switch (stack[i].key) {
1945 case GL_NORMAL_ARRAY:
1946 __indirect_glNormalPointer(stack[i].data_type,
1947 stack[i].user_stride, stack[i].data);
1948 break;
1949 case GL_COLOR_ARRAY:
1950 __indirect_glColorPointer(stack[i].count,
1951 stack[i].data_type,
1952 stack[i].user_stride, stack[i].data);
1953 break;
1954 case GL_INDEX_ARRAY:
1955 __indirect_glIndexPointer(stack[i].data_type,
1956 stack[i].user_stride, stack[i].data);
1957 break;
1958 case GL_EDGE_FLAG_ARRAY:
1959 __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
1960 break;
1961 case GL_TEXTURE_COORD_ARRAY:
1962 arrays->active_texture_unit = stack[i].index;
1963 __indirect_glTexCoordPointer(stack[i].count,
1964 stack[i].data_type,
1965 stack[i].user_stride, stack[i].data);
1966 break;
1967 case GL_SECONDARY_COLOR_ARRAY:
1968 __indirect_glSecondaryColorPointerEXT(stack[i].count,
1969 stack[i].data_type,
1970 stack[i].user_stride,
1971 stack[i].data);
1972 break;
1973 case GL_FOG_COORDINATE_ARRAY:
1974 __indirect_glFogCoordPointerEXT(stack[i].data_type,
1975 stack[i].user_stride, stack[i].data);
1976 break;
Ian Romanickfdb07632005-02-22 22:36:31 +00001977
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001978 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001979
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001980 __glXSetArrayEnable(state, stack[i].key, stack[i].index,
1981 stack[i].enabled);
1982 }
1983
1984 arrays->active_texture_unit =
1985 arrays->active_texture_unit_stack[arrays->stack_index];
Ian Romanickfdb07632005-02-22 22:36:31 +00001986}