blob: 01fab3345a93afed6dfeea47b7b68b693dafea1e [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) {
Matt Turner50675062012-09-03 20:24:35 -0700118 free(arrays->stack);
119 arrays->stack = NULL;
120 free(arrays->arrays);
121 arrays->arrays = NULL;
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200122 free(arrays);
123 state->array_state = NULL;
124 }
Kristof Raloviche2060342008-08-20 15:18:38 -0600125}
126
Ian Romanickfdb07632005-02-22 22:36:31 +0000127
128/**
129 * Initialize vertex array state of a GLX context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200130 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000131 * \param gc GLX context whose vertex array state is to be initialized.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200132 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000133 * \warning
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400134 * This function may only be called after struct glx_context::gl_extension_bits,
135 * struct glx_context::server_minor, and __GLXcontext::server_major have been
Ian Romanickfdb07632005-02-22 22:36:31 +0000136 * initialized. These values are used to determine what vertex arrays are
137 * supported.
Ian Romanickfdb07632005-02-22 22:36:31 +0000138 */
139void
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400140__glXInitVertexArrayState(struct glx_context * gc)
Ian Romanickfdb07632005-02-22 22:36:31 +0000141{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200142 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
143 struct array_state_vector *arrays;
Ian Romanickfdb07632005-02-22 22:36:31 +0000144
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200145 unsigned array_count;
146 int texture_units = 1, vertex_program_attribs = 0;
147 unsigned i, j;
Ian Romanickfdb07632005-02-22 22:36:31 +0000148
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200149 GLboolean got_fog = GL_FALSE;
150 GLboolean got_secondary_color = GL_FALSE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000151
152
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200153 arrays = calloc(1, sizeof(struct array_state_vector));
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700154
155 if (arrays == NULL) {
156 __glXSetError(gc, GL_OUT_OF_MEMORY);
157 return;
158 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000159
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200160 arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
161 arrays->new_DrawArrays_possible = GL_FALSE;
162 arrays->DrawArrays = NULL;
Ian Romanickfdb07632005-02-22 22:36:31 +0000163
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200164 arrays->active_texture_unit = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000165
166
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200167 /* Determine how many arrays are actually needed. Only arrays that
168 * are supported by the server are create. For example, if the server
169 * supports only 2 texture units, then only 2 texture coordinate arrays
170 * are created.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200171 *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200172 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
173 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
174 * GL_EDGE_FLAG_ARRAY are supported.
175 */
Ian Romanick979f35f2005-03-17 20:36:20 +0000176
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200177 array_count = 5;
Ian Romanickfdb07632005-02-22 22:36:31 +0000178
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200179 if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
180 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
181 got_fog = GL_TRUE;
182 array_count++;
183 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000184
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200185 if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
186 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
187 got_secondary_color = GL_TRUE;
188 array_count++;
189 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000190
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200191 if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit)
192 || (gc->server_major > 1) || (gc->server_minor >= 3)) {
193 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
194 }
Ian Romanick40af76b2005-02-25 22:46:30 +0000195
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200196 if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) {
197 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
198 GL_MAX_PROGRAM_ATTRIBS_ARB,
199 &vertex_program_attribs);
200 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000201
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200202 arrays->num_texture_units = texture_units;
203 arrays->num_vertex_program_attribs = vertex_program_attribs;
204 array_count += texture_units + vertex_program_attribs;
205 arrays->num_arrays = array_count;
206 arrays->arrays = calloc(array_count, sizeof(struct array_state));
Ian Romanickfdb07632005-02-22 22:36:31 +0000207
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700208 if (arrays->arrays == NULL) {
209 free(arrays);
210 __glXSetError(gc, GL_OUT_OF_MEMORY);
211 return;
212 }
213
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200214 arrays->arrays[0].data_type = GL_FLOAT;
215 arrays->arrays[0].count = 3;
216 arrays->arrays[0].key = GL_NORMAL_ARRAY;
217 arrays->arrays[0].normalized = GL_TRUE;
218 arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000219
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200220 arrays->arrays[1].data_type = GL_FLOAT;
221 arrays->arrays[1].count = 4;
222 arrays->arrays[1].key = GL_COLOR_ARRAY;
223 arrays->arrays[1].normalized = GL_TRUE;
224 arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000225
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200226 arrays->arrays[2].data_type = GL_FLOAT;
227 arrays->arrays[2].count = 1;
228 arrays->arrays[2].key = GL_INDEX_ARRAY;
229 arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000230
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200231 arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
232 arrays->arrays[3].count = 1;
233 arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
234 arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
Ian Romanick40af76b2005-02-25 22:46:30 +0000235
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200236 for (i = 0; i < texture_units; i++) {
237 arrays->arrays[4 + i].data_type = GL_FLOAT;
238 arrays->arrays[4 + i].count = 4;
239 arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
Ian Romanickfdb07632005-02-22 22:36:31 +0000240
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200241 arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
242 arrays->arrays[4 + i].index = i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000243
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200244 arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0;
245 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000246
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200247 i = 4 + texture_units;
248
249 if (got_fog) {
250 arrays->arrays[i].data_type = GL_FLOAT;
251 arrays->arrays[i].count = 1;
252 arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
253 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
254 i++;
255 }
256
257 if (got_secondary_color) {
258 arrays->arrays[i].data_type = GL_FLOAT;
259 arrays->arrays[i].count = 3;
260 arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
261 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
262 arrays->arrays[i].normalized = GL_TRUE;
263 i++;
264 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000265
266
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200267 for (j = 0; j < vertex_program_attribs; j++) {
268 const unsigned idx = (vertex_program_attribs - (j + 1));
Ian Romanick40af76b2005-02-25 22:46:30 +0000269
270
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200271 arrays->arrays[idx + i].data_type = GL_FLOAT;
272 arrays->arrays[idx + i].count = 4;
273 arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
Ian Romanick40af76b2005-02-25 22:46:30 +0000274
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200275 arrays->arrays[idx + i].old_DrawArrays_possible = 0;
276 arrays->arrays[idx + i].index = idx;
Ian Romanick40af76b2005-02-25 22:46:30 +0000277
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200278 arrays->arrays[idx + i].header[1] = idx;
279 }
Ian Romanick40af76b2005-02-25 22:46:30 +0000280
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200281 i += vertex_program_attribs;
Ian Romanick40af76b2005-02-25 22:46:30 +0000282
283
Zoë Blade05e7f7f2015-04-22 11:33:17 +0100284 /* Vertex array *must* be last because of the way that
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200285 * emit_DrawArrays_none works.
286 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000287
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200288 arrays->arrays[i].data_type = GL_FLOAT;
289 arrays->arrays[i].count = 4;
290 arrays->arrays[i].key = GL_VERTEX_ARRAY;
291 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000292
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200293 assert((i + 1) == arrays->num_arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000294
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200295 arrays->stack_index = 0;
296 arrays->stack = malloc(sizeof(struct array_stack_state)
Markus Fleschutz83f11832010-02-26 10:34:19 -0700297 * arrays->num_arrays
298 * __GL_CLIENT_ATTRIB_STACK_DEPTH);
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700299
300 if (arrays->stack == NULL) {
301 free(arrays->arrays);
302 free(arrays);
303 __glXSetError(gc, GL_OUT_OF_MEMORY);
304 return;
305 }
306
307 /* Everything went ok so we put vertex array state in place
308 * in context.
309 */
310 state->array_state = arrays;
Ian Romanickfdb07632005-02-22 22:36:31 +0000311}
312
313
314/**
315 * Calculate the size of a single vertex for the "none" protocol. This is
316 * essentially the size of all the immediate-mode commands required to
317 * implement the enabled vertex arrays.
318 */
319static size_t
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200320calculate_single_vertex_size_none(const struct array_state_vector *arrays)
Ian Romanickfdb07632005-02-22 22:36:31 +0000321{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200322 size_t single_vertex_size = 0;
323 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000324
325
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200326 for (i = 0; i < arrays->num_arrays; i++) {
327 if (arrays->arrays[i].enabled) {
328 single_vertex_size += ((uint16_t *) arrays->arrays[i].header)[0];
329 }
330 }
331
332 return single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000333}
334
335
336/**
337 * Emit a single element using non-DrawArrays protocol.
338 */
339GLubyte *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200340emit_element_none(GLubyte * dst,
341 const struct array_state_vector * arrays, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000342{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200343 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000344
345
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200346 for (i = 0; i < arrays->num_arrays; i++) {
347 if (arrays->arrays[i].enabled) {
348 const size_t offset = index * arrays->arrays[i].true_stride;
Ian Romanickfdb07632005-02-22 22:36:31 +0000349
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200350 /* The generic attributes can have more data than is in the
351 * elements. This is because a vertex array can be a 2 element,
352 * normalized, unsigned short, but the "closest" immediate mode
353 * protocol is for a 4Nus. Since the sizes are small, the
354 * performance impact on modern processors should be negligible.
355 */
356 (void) memset(dst, 0, ((uint16_t *) arrays->arrays[i].header)[0]);
Ian Romanick40af76b2005-02-25 22:46:30 +0000357
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200358 (void) memcpy(dst, arrays->arrays[i].header,
359 arrays->arrays[i].header_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000360
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200361 dst += arrays->arrays[i].header_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000362
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200363 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
364 arrays->arrays[i].element_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000365
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200366 dst += __GLX_PAD(arrays->arrays[i].element_size);
367 }
368 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000369
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200370 return dst;
Ian Romanickfdb07632005-02-22 22:36:31 +0000371}
372
373
374/**
375 * Emit a single element using "old" DrawArrays protocol from
376 * EXT_vertex_arrays / OpenGL 1.1.
377 */
378GLubyte *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200379emit_element_old(GLubyte * dst,
380 const struct array_state_vector * arrays, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000381{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200382 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000383
384
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200385 for (i = 0; i < arrays->num_arrays; i++) {
386 if (arrays->arrays[i].enabled) {
387 const size_t offset = index * arrays->arrays[i].true_stride;
Ian Romanickfdb07632005-02-22 22:36:31 +0000388
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200389 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
390 arrays->arrays[i].element_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000391
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200392 dst += __GLX_PAD(arrays->arrays[i].element_size);
393 }
394 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000395
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200396 return dst;
Ian Romanickfdb07632005-02-22 22:36:31 +0000397}
398
399
400struct array_state *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200401get_array_entry(const struct array_state_vector *arrays,
402 GLenum key, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000403{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200404 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000405
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200406 for (i = 0; i < arrays->num_arrays; i++) {
407 if ((arrays->arrays[i].key == key)
408 && (arrays->arrays[i].index == index)) {
409 return &arrays->arrays[i];
410 }
411 }
412
413 return NULL;
Ian Romanickfdb07632005-02-22 22:36:31 +0000414}
415
416
417static GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200418allocate_array_info_cache(struct array_state_vector *arrays,
419 size_t required_size)
Ian Romanickfdb07632005-02-22 22:36:31 +0000420{
Ian Romanick979f35f2005-03-17 20:36:20 +0000421#define MAX_HEADER_SIZE 20
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200422 if (arrays->array_info_cache_buffer_size < required_size) {
423 GLubyte *temp = realloc(arrays->array_info_cache_base,
424 required_size + MAX_HEADER_SIZE);
Ian Romanickfdb07632005-02-22 22:36:31 +0000425
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200426 if (temp == NULL) {
427 return GL_FALSE;
428 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000429
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200430 arrays->array_info_cache_base = temp;
431 arrays->array_info_cache = temp + MAX_HEADER_SIZE;
432 arrays->array_info_cache_buffer_size = required_size;
433 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000434
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200435 arrays->array_info_cache_size = required_size;
436 return GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000437}
438
439
440/**
441 */
442void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200443fill_array_info_cache(struct array_state_vector *arrays)
Ian Romanickfdb07632005-02-22 22:36:31 +0000444{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200445 GLboolean old_DrawArrays_possible;
446 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000447
448
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200449 /* Determine how many arrays are enabled.
450 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000451
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200452 arrays->enabled_client_array_count = 0;
453 old_DrawArrays_possible = arrays->old_DrawArrays_possible;
454 for (i = 0; i < arrays->num_arrays; i++) {
455 if (arrays->arrays[i].enabled) {
456 arrays->enabled_client_array_count++;
457 old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
458 }
459 }
460
461 if (arrays->new_DrawArrays_possible) {
462 assert(!arrays->new_DrawArrays_possible);
463 }
464 else if (old_DrawArrays_possible) {
465 const size_t required_size = arrays->enabled_client_array_count * 12;
466 uint32_t *info;
Ian Romanickfdb07632005-02-22 22:36:31 +0000467
468
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200469 if (!allocate_array_info_cache(arrays, required_size)) {
470 return;
471 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000472
473
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200474 info = (uint32_t *) arrays->array_info_cache;
475 for (i = 0; i < arrays->num_arrays; i++) {
476 if (arrays->arrays[i].enabled) {
477 *(info++) = arrays->arrays[i].data_type;
478 *(info++) = arrays->arrays[i].count;
479 *(info++) = arrays->arrays[i].key;
480 }
481 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000482
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200483 arrays->DrawArrays = emit_DrawArrays_old;
484 arrays->DrawElements = emit_DrawElements_old;
485 }
486 else {
487 arrays->DrawArrays = emit_DrawArrays_none;
488 arrays->DrawElements = emit_DrawElements_none;
489 }
Ian Romanickb81efaa2005-03-17 20:13:09 +0000490
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200491 arrays->array_info_cache_valid = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000492}
493
494
495/**
496 * Emit a \c glDrawArrays command using the "none" protocol. That is,
497 * emit immediate-mode commands that are equivalent to the requiested
498 * \c glDrawArrays command. This is used with servers that don't support
499 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
500 * vertex state is enabled that is not compatible with that protocol.
501 */
502void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200503emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000504{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400505 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200506 const __GLXattribute *state =
507 (const __GLXattribute *) (gc->client_state_private);
508 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000509
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200510 size_t single_vertex_size;
511 GLubyte *pc;
512 unsigned i;
513 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
514 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
Ian Romanickfdb07632005-02-22 22:36:31 +0000515
516
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200517 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000518
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200519 pc = gc->pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000520
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200521 (void) memcpy(pc, begin_cmd, 4);
522 *(int *) (pc + 4) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000523
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200524 pc += 8;
Ian Romanickfdb07632005-02-22 22:36:31 +0000525
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200526 for (i = 0; i < count; i++) {
527 if ((pc + single_vertex_size) >= gc->bufEnd) {
528 pc = __glXFlushRenderBuffer(gc, pc);
529 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000530
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200531 pc = emit_element_none(pc, arrays, first + i);
532 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000533
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200534 if ((pc + 4) >= gc->bufEnd) {
535 pc = __glXFlushRenderBuffer(gc, pc);
536 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000537
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200538 (void) memcpy(pc, end_cmd, 4);
539 pc += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000540
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200541 gc->pc = pc;
542 if (gc->pc > gc->limit) {
543 (void) __glXFlushRenderBuffer(gc, gc->pc);
544 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000545}
546
547
548/**
549 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
550 * protocol.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200551 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000552 * \param gc GLX context.
553 * \param arrays Array state.
554 * \param elements_per_request Location to store the number of elements that
555 * can fit in a single Render / RenderLarge
556 * command.
557 * \param total_request Total number of requests for a RenderLarge
558 * command. If a Render command is used, this
559 * will be zero.
560 * \param mode Drawing mode.
561 * \param count Number of vertices.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200562 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000563 * \returns
564 * A pointer to the buffer for array data.
565 */
566static GLubyte *
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400567emit_DrawArrays_header_old(struct glx_context * gc,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200568 struct array_state_vector *arrays,
569 size_t * elements_per_request,
570 unsigned int *total_requests,
571 GLenum mode, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000572{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200573 size_t command_size;
574 size_t single_vertex_size;
575 const unsigned header_size = 16;
576 unsigned i;
577 GLubyte *pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000578
579
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200580 /* Determine the size of the whole command. This includes the header,
581 * the ARRAY_INFO data and the array data. Once this size is calculated,
582 * it will be known whether a Render or RenderLarge command is needed.
583 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000584
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200585 single_vertex_size = 0;
586 for (i = 0; i < arrays->num_arrays; i++) {
587 if (arrays->arrays[i].enabled) {
588 single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
589 }
590 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000591
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200592 command_size = arrays->array_info_cache_size + header_size
Ian Romanickfdb07632005-02-22 22:36:31 +0000593 + (single_vertex_size * count);
594
595
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200596 /* Write the header for either a Render command or a RenderLarge
597 * command. After the header is written, write the ARRAY_INFO data.
598 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000599
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200600 if (command_size > gc->maxSmallRenderCommandSize) {
601 /* maxSize is the maximum amount of data can be stuffed into a single
602 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
603 * packet size minus sz_xGLXRenderReq.
604 */
605 const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
606 - sz_xGLXRenderLargeReq;
607 unsigned vertex_requests;
Ian Romanickfdb07632005-02-22 22:36:31 +0000608
609
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200610 /* Calculate the number of data packets that will be required to send
611 * the whole command. To do this, the number of verticies that
612 * will fit in a single buffer must be calculated.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200613 *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200614 * The important value here is elements_per_request. This is the
615 * number of complete array elements that will fit in a single
616 * buffer. There may be some wasted space at the end of the buffer,
617 * but splitting elements across buffer boundries would be painful.
618 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000619
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200620 elements_per_request[0] = maxSize / single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000621
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200622 vertex_requests = (count + elements_per_request[0] - 1)
623 / elements_per_request[0];
624
625 *total_requests = vertex_requests + 1;
Ian Romanickfdb07632005-02-22 22:36:31 +0000626
627
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200628 __glXFlushRenderBuffer(gc, gc->pc);
Ian Romanickfdb07632005-02-22 22:36:31 +0000629
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200630 command_size += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000631
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200632 pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
633 *(uint32_t *) (pc + 0) = command_size;
634 *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
635 *(uint32_t *) (pc + 8) = count;
636 *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
637 *(uint32_t *) (pc + 16) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000638
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200639 __glXSendLargeChunk(gc, 1, *total_requests, pc,
640 header_size + 4 + arrays->array_info_cache_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000641
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200642 pc = gc->pc;
643 }
644 else {
645 if ((gc->pc + command_size) >= gc->bufEnd) {
646 (void) __glXFlushRenderBuffer(gc, gc->pc);
647 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000648
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200649 pc = gc->pc;
650 *(uint16_t *) (pc + 0) = command_size;
651 *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
652 *(uint32_t *) (pc + 4) = count;
653 *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
654 *(uint32_t *) (pc + 12) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000655
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200656 pc += header_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000657
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200658 (void) memcpy(pc, arrays->array_info_cache,
659 arrays->array_info_cache_size);
660 pc += arrays->array_info_cache_size;
Ian Romanickb81efaa2005-03-17 20:13:09 +0000661
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200662 *elements_per_request = count;
663 *total_requests = 0;
664 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000665
666
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200667 return pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000668}
669
670
671/**
672 */
673void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200674emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000675{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400676 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200677 const __GLXattribute *state =
678 (const __GLXattribute *) (gc->client_state_private);
679 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000680
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200681 GLubyte *pc;
682 size_t elements_per_request;
683 unsigned total_requests = 0;
684 unsigned i;
685 size_t total_sent = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000686
687
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200688 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
689 &total_requests, mode, count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000690
691
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200692 /* Write the arrays.
693 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000694
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200695 if (total_requests == 0) {
696 assert(elements_per_request >= count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000697
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200698 for (i = 0; i < count; i++) {
699 pc = emit_element_old(pc, arrays, i + first);
700 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000701
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200702 assert(pc <= gc->bufEnd);
Ian Romanickfdb07632005-02-22 22:36:31 +0000703
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200704 gc->pc = pc;
705 if (gc->pc > gc->limit) {
706 (void) __glXFlushRenderBuffer(gc, gc->pc);
707 }
708 }
709 else {
710 unsigned req;
711
712
713 for (req = 2; req <= total_requests; req++) {
714 if (count < elements_per_request) {
715 elements_per_request = count;
716 }
717
718 pc = gc->pc;
719 for (i = 0; i < elements_per_request; i++) {
720 pc = emit_element_old(pc, arrays, i + first);
721 }
722
723 first += elements_per_request;
724
725 total_sent += (size_t) (pc - gc->pc);
726 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
727
728 count -= elements_per_request;
729 }
730 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000731}
732
733
734void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200735emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
736 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000737{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400738 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200739 const __GLXattribute *state =
740 (const __GLXattribute *) (gc->client_state_private);
741 struct array_state_vector *arrays = state->array_state;
742 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
743 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
Ian Romanickfdb07632005-02-22 22:36:31 +0000744
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200745 GLubyte *pc;
746 size_t single_vertex_size;
747 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000748
749
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200750 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000751
752
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200753 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
754 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
755 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000756
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200757 pc = gc->pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000758
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200759 (void) memcpy(pc, begin_cmd, 4);
760 *(int *) (pc + 4) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000761
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200762 pc += 8;
Ian Romanickfdb07632005-02-22 22:36:31 +0000763
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200764 for (i = 0; i < count; i++) {
765 unsigned index = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000766
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200767 if ((pc + single_vertex_size) >= gc->bufEnd) {
768 pc = __glXFlushRenderBuffer(gc, pc);
769 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000770
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200771 switch (type) {
772 case GL_UNSIGNED_INT:
773 index = (unsigned) (((GLuint *) indices)[i]);
774 break;
775 case GL_UNSIGNED_SHORT:
776 index = (unsigned) (((GLushort *) indices)[i]);
777 break;
778 case GL_UNSIGNED_BYTE:
779 index = (unsigned) (((GLubyte *) indices)[i]);
780 break;
781 }
782 pc = emit_element_none(pc, arrays, index);
783 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000784
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200785 if ((pc + 4) >= gc->bufEnd) {
786 pc = __glXFlushRenderBuffer(gc, pc);
787 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000788
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200789 (void) memcpy(pc, end_cmd, 4);
790 pc += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000791
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200792 gc->pc = pc;
793 if (gc->pc > gc->limit) {
794 (void) __glXFlushRenderBuffer(gc, gc->pc);
795 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000796}
797
798
799/**
800 */
801void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200802emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
803 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000804{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400805 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200806 const __GLXattribute *state =
807 (const __GLXattribute *) (gc->client_state_private);
808 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000809
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200810 GLubyte *pc;
811 size_t elements_per_request;
812 unsigned total_requests = 0;
813 unsigned i;
814 unsigned req;
815 unsigned req_element = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000816
817
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200818 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
819 &total_requests, mode, count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000820
821
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200822 /* Write the arrays.
823 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000824
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200825 req = 2;
826 while (count > 0) {
827 if (count < elements_per_request) {
828 elements_per_request = count;
829 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000830
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200831 switch (type) {
832 case GL_UNSIGNED_INT:{
833 const GLuint *ui_ptr = (const GLuint *) indices + req_element;
834
835 for (i = 0; i < elements_per_request; i++) {
836 const GLint index = (GLint) * (ui_ptr++);
837 pc = emit_element_old(pc, arrays, index);
838 }
839 break;
840 }
841 case GL_UNSIGNED_SHORT:{
842 const GLushort *us_ptr = (const GLushort *) indices + req_element;
843
844 for (i = 0; i < elements_per_request; i++) {
845 const GLint index = (GLint) * (us_ptr++);
846 pc = emit_element_old(pc, arrays, index);
847 }
848 break;
849 }
850 case GL_UNSIGNED_BYTE:{
851 const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;
852
853 for (i = 0; i < elements_per_request; i++) {
854 const GLint index = (GLint) * (ub_ptr++);
855 pc = emit_element_old(pc, arrays, index);
856 }
857 break;
858 }
859 }
860
861 if (total_requests != 0) {
862 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
863 pc = gc->pc;
864 req++;
865 }
866
867 count -= elements_per_request;
868 req_element += elements_per_request;
869 }
870
871
872 assert((total_requests == 0) || ((req - 1) == total_requests));
873
874 if (total_requests == 0) {
875 assert(pc <= gc->bufEnd);
876
877 gc->pc = pc;
878 if (gc->pc > gc->limit) {
879 (void) __glXFlushRenderBuffer(gc, gc->pc);
880 }
881 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000882}
883
884
885/**
886 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
887 * If it is not valid, then an error code is set in the GLX context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200888 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000889 * \returns
890 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
891 */
892static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400893validate_mode(struct glx_context * gc, GLenum mode)
Ian Romanickfdb07632005-02-22 22:36:31 +0000894{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200895 switch (mode) {
896 case GL_POINTS:
897 case GL_LINE_STRIP:
898 case GL_LINE_LOOP:
899 case GL_LINES:
900 case GL_TRIANGLE_STRIP:
901 case GL_TRIANGLE_FAN:
902 case GL_TRIANGLES:
903 case GL_QUAD_STRIP:
904 case GL_QUADS:
905 case GL_POLYGON:
906 break;
907 default:
908 __glXSetError(gc, GL_INVALID_ENUM);
909 return GL_FALSE;
910 }
911
912 return GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000913}
914
915
916/**
917 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
918 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
919 * being set. A value of zero will not result in an error being set, but
920 * will result in \c GL_FALSE being returned.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200921 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000922 * \returns
923 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
924 */
925static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400926validate_count(struct glx_context * gc, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000927{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200928 if (count < 0) {
929 __glXSetError(gc, GL_INVALID_VALUE);
930 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000931
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200932 return (count > 0);
Ian Romanickfdb07632005-02-22 22:36:31 +0000933}
934
935
Ian Romanick03dc4372005-02-28 19:37:10 +0000936/**
937 * Validate that the \c type parameter to \c glDrawElements, et. al. is
938 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
939 * \c GL_UNSIGNED_INT are valid.
940 *
941 * \returns
942 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
943 */
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200944static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400945validate_type(struct glx_context * gc, GLenum type)
Ian Romanick03dc4372005-02-28 19:37:10 +0000946{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200947 switch (type) {
948 case GL_UNSIGNED_INT:
949 case GL_UNSIGNED_SHORT:
950 case GL_UNSIGNED_BYTE:
951 return GL_TRUE;
952 default:
953 __glXSetError(gc, GL_INVALID_ENUM);
954 return GL_FALSE;
955 }
Ian Romanick03dc4372005-02-28 19:37:10 +0000956}
957
958
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200959void
960__indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000961{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400962 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200963 const __GLXattribute *state =
964 (const __GLXattribute *) (gc->client_state_private);
965 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000966
Ian Romanickfdb07632005-02-22 22:36:31 +0000967
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200968 if (validate_mode(gc, mode) && validate_count(gc, count)) {
969 if (!arrays->array_info_cache_valid) {
970 fill_array_info_cache(arrays);
971 }
972
973 arrays->DrawArrays(mode, first, count);
974 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000975}
976
977
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200978void
979__indirect_glArrayElement(GLint index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000980{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400981 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200982 const __GLXattribute *state =
983 (const __GLXattribute *) (gc->client_state_private);
984 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000985
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200986 size_t single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000987
988
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200989 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000990
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200991 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
992 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
993 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000994
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200995 gc->pc = emit_element_none(gc->pc, arrays, index);
Ian Romanickfdb07632005-02-22 22:36:31 +0000996
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200997 if (gc->pc > gc->limit) {
998 (void) __glXFlushRenderBuffer(gc, gc->pc);
999 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001000}
1001
1002
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001003void
1004__indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
1005 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +00001006{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001007 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001008 const __GLXattribute *state =
1009 (const __GLXattribute *) (gc->client_state_private);
1010 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +00001011
1012
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001013 if (validate_mode(gc, mode) && validate_count(gc, count)
1014 && validate_type(gc, type)) {
1015 if (!arrays->array_info_cache_valid) {
1016 fill_array_info_cache(arrays);
1017 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001018
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001019 arrays->DrawElements(mode, count, type, indices);
1020 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001021}
1022
1023
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001024void
1025__indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1026 GLsizei count, GLenum type,
1027 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +00001028{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001029 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001030 const __GLXattribute *state =
1031 (const __GLXattribute *) (gc->client_state_private);
1032 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +00001033
1034
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001035 if (validate_mode(gc, mode) && validate_count(gc, count)
1036 && validate_type(gc, type)) {
1037 if (end < start) {
1038 __glXSetError(gc, GL_INVALID_VALUE);
1039 return;
1040 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001041
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001042 if (!arrays->array_info_cache_valid) {
1043 fill_array_info_cache(arrays);
1044 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001045
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001046 arrays->DrawElements(mode, count, type, indices);
1047 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001048}
1049
1050
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001051void
Paul Berry1a1db172012-11-06 08:57:59 -08001052__indirect_glMultiDrawArrays(GLenum mode, const GLint *first,
Brian Paul4cd751b2010-09-14 11:01:03 -06001053 const GLsizei *count, GLsizei primcount)
Ian Romanickfdb07632005-02-22 22:36:31 +00001054{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001055 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001056 const __GLXattribute *state =
1057 (const __GLXattribute *) (gc->client_state_private);
1058 struct array_state_vector *arrays = state->array_state;
1059 GLsizei i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001060
1061
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001062 if (validate_mode(gc, mode)) {
1063 if (!arrays->array_info_cache_valid) {
1064 fill_array_info_cache(arrays);
1065 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001066
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001067 for (i = 0; i < primcount; i++) {
1068 if (validate_count(gc, count[i])) {
1069 arrays->DrawArrays(mode, first[i], count[i]);
1070 }
1071 }
1072 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001073}
1074
1075
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001076void
1077__indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
Eric Anholtfc32d402013-06-26 12:24:08 -07001078 GLenum type, const GLvoid * const * indices,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001079 GLsizei primcount)
Ian Romanickfdb07632005-02-22 22:36:31 +00001080{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001081 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001082 const __GLXattribute *state =
1083 (const __GLXattribute *) (gc->client_state_private);
1084 struct array_state_vector *arrays = state->array_state;
1085 GLsizei i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001086
1087
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001088 if (validate_mode(gc, mode) && validate_type(gc, type)) {
1089 if (!arrays->array_info_cache_valid) {
1090 fill_array_info_cache(arrays);
1091 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001092
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001093 for (i = 0; i < primcount; i++) {
1094 if (validate_count(gc, count[i])) {
1095 arrays->DrawElements(mode, count[i], type, indices[i]);
1096 }
1097 }
1098 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001099}
1100
1101
Ian Romanickb81efaa2005-03-17 20:13:09 +00001102#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001103 do { \
1104 (a)->data = PTR; \
1105 (a)->data_type = TYPE; \
1106 (a)->user_stride = STRIDE; \
1107 (a)->count = COUNT; \
1108 (a)->normalized = NORMALIZED; \
1109 \
1110 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1111 (a)->true_stride = (STRIDE == 0) \
1112 ? (a)->element_size : STRIDE; \
1113 \
1114 (a)->header_size = HDR_SIZE; \
1115 ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1116 ((uint16_t *) (a)->header)[1] = OPCODE; \
1117 } while(0)
Ian Romanickfdb07632005-02-22 22:36:31 +00001118
1119
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001120void
1121__indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
1122 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001123{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001124 static const uint16_t short_ops[5] = {
1125 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1126 };
1127 static const uint16_t int_ops[5] = {
1128 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1129 };
1130 static const uint16_t float_ops[5] = {
1131 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1132 };
1133 static const uint16_t double_ops[5] = {
1134 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1135 };
1136 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001137 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001138 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1139 struct array_state_vector *arrays = state->array_state;
1140 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001141
1142
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001143 if (size < 2 || size > 4 || stride < 0) {
1144 __glXSetError(gc, GL_INVALID_VALUE);
1145 return;
1146 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001147
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001148 switch (type) {
1149 case GL_SHORT:
1150 opcode = short_ops[size];
1151 break;
1152 case GL_INT:
1153 opcode = int_ops[size];
1154 break;
1155 case GL_FLOAT:
1156 opcode = float_ops[size];
1157 break;
1158 case GL_DOUBLE:
1159 opcode = double_ops[size];
1160 break;
1161 default:
1162 __glXSetError(gc, GL_INVALID_ENUM);
1163 return;
1164 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001165
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001166 a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
1167 assert(a != NULL);
1168 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
1169 opcode);
1170
1171 if (a->enabled) {
1172 arrays->array_info_cache_valid = GL_FALSE;
1173 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001174}
1175
1176
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001177void
1178__indirect_glNormalPointer(GLenum type, GLsizei stride,
1179 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001180{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001181 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001182 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001183 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1184 struct array_state_vector *arrays = state->array_state;
1185 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001186
1187
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001188 if (stride < 0) {
1189 __glXSetError(gc, GL_INVALID_VALUE);
1190 return;
1191 }
Ian Romanickb81efaa2005-03-17 20:13:09 +00001192
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001193 switch (type) {
1194 case GL_BYTE:
1195 opcode = X_GLrop_Normal3bv;
1196 break;
1197 case GL_SHORT:
1198 opcode = X_GLrop_Normal3sv;
1199 break;
1200 case GL_INT:
1201 opcode = X_GLrop_Normal3iv;
1202 break;
1203 case GL_FLOAT:
1204 opcode = X_GLrop_Normal3fv;
1205 break;
1206 case GL_DOUBLE:
1207 opcode = X_GLrop_Normal3dv;
1208 break;
1209 default:
1210 __glXSetError(gc, GL_INVALID_ENUM);
1211 return;
1212 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001213
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001214 a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
1215 assert(a != NULL);
1216 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);
Ian Romanickfdb07632005-02-22 22:36:31 +00001217
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001218 if (a->enabled) {
1219 arrays->array_info_cache_valid = GL_FALSE;
1220 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001221}
1222
1223
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001224void
1225__indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
1226 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001227{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001228 static const uint16_t byte_ops[5] = {
1229 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1230 };
1231 static const uint16_t ubyte_ops[5] = {
1232 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1233 };
1234 static const uint16_t short_ops[5] = {
1235 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1236 };
1237 static const uint16_t ushort_ops[5] = {
1238 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1239 };
1240 static const uint16_t int_ops[5] = {
1241 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1242 };
1243 static const uint16_t uint_ops[5] = {
1244 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1245 };
1246 static const uint16_t float_ops[5] = {
1247 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1248 };
1249 static const uint16_t double_ops[5] = {
1250 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1251 };
1252 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001253 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001254 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1255 struct array_state_vector *arrays = state->array_state;
1256 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001257
1258
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001259 if (size < 3 || size > 4 || stride < 0) {
1260 __glXSetError(gc, GL_INVALID_VALUE);
1261 return;
1262 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001263
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001264 switch (type) {
1265 case GL_BYTE:
1266 opcode = byte_ops[size];
1267 break;
1268 case GL_UNSIGNED_BYTE:
1269 opcode = ubyte_ops[size];
1270 break;
1271 case GL_SHORT:
1272 opcode = short_ops[size];
1273 break;
1274 case GL_UNSIGNED_SHORT:
1275 opcode = ushort_ops[size];
1276 break;
1277 case GL_INT:
1278 opcode = int_ops[size];
1279 break;
1280 case GL_UNSIGNED_INT:
1281 opcode = uint_ops[size];
1282 break;
1283 case GL_FLOAT:
1284 opcode = float_ops[size];
1285 break;
1286 case GL_DOUBLE:
1287 opcode = double_ops[size];
1288 break;
1289 default:
1290 __glXSetError(gc, GL_INVALID_ENUM);
1291 return;
1292 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001293
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001294 a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
1295 assert(a != NULL);
1296 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1297
1298 if (a->enabled) {
1299 arrays->array_info_cache_valid = GL_FALSE;
1300 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001301}
1302
1303
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001304void
1305__indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001306{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001307 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001308 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001309 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1310 struct array_state_vector *arrays = state->array_state;
1311 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001312
1313
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001314 if (stride < 0) {
1315 __glXSetError(gc, GL_INVALID_VALUE);
1316 return;
1317 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001318
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001319 switch (type) {
1320 case GL_UNSIGNED_BYTE:
1321 opcode = X_GLrop_Indexubv;
1322 break;
1323 case GL_SHORT:
1324 opcode = X_GLrop_Indexsv;
1325 break;
1326 case GL_INT:
1327 opcode = X_GLrop_Indexiv;
1328 break;
1329 case GL_FLOAT:
1330 opcode = X_GLrop_Indexfv;
1331 break;
1332 case GL_DOUBLE:
1333 opcode = X_GLrop_Indexdv;
1334 break;
1335 default:
1336 __glXSetError(gc, GL_INVALID_ENUM);
1337 return;
1338 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001339
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001340 a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
1341 assert(a != NULL);
1342 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1343
1344 if (a->enabled) {
1345 arrays->array_info_cache_valid = GL_FALSE;
1346 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001347}
1348
1349
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001350void
1351__indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001352{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001353 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001354 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1355 struct array_state_vector *arrays = state->array_state;
1356 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001357
1358
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001359 if (stride < 0) {
1360 __glXSetError(gc, GL_INVALID_VALUE);
1361 return;
1362 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001363
Ian Romanickfdb07632005-02-22 22:36:31 +00001364
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001365 a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
1366 assert(a != NULL);
1367 COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1368 4, X_GLrop_EdgeFlagv);
1369
1370 if (a->enabled) {
1371 arrays->array_info_cache_valid = GL_FALSE;
1372 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001373}
1374
1375
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001376void
1377__indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
1378 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001379{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001380 static const uint16_t short_ops[5] = {
1381 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001382 X_GLrop_TexCoord4sv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001383 };
1384 static const uint16_t int_ops[5] = {
1385 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001386 X_GLrop_TexCoord4iv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001387 };
1388 static const uint16_t float_ops[5] = {
Colin McDonald5ced1002016-06-22 19:11:55 -07001389 0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001390 X_GLrop_TexCoord4fv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001391 };
1392 static const uint16_t double_ops[5] = {
1393 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001394 X_GLrop_TexCoord4dv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001395 };
Ian Romanickfdb07632005-02-22 22:36:31 +00001396
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001397 static const uint16_t mshort_ops[5] = {
1398 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001399 X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001400 };
1401 static const uint16_t mint_ops[5] = {
1402 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001403 X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001404 };
1405 static const uint16_t mfloat_ops[5] = {
Colin McDonald5ced1002016-06-22 19:11:55 -07001406 0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001407 X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001408 };
1409 static const uint16_t mdouble_ops[5] = {
1410 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001411 X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001412 };
Ian Romanickfdb07632005-02-22 22:36:31 +00001413
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001414 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001415 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001416 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1417 struct array_state_vector *arrays = state->array_state;
1418 struct array_state *a;
1419 unsigned header_size;
1420 unsigned index;
Ian Romanickfdb07632005-02-22 22:36:31 +00001421
1422
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001423 if (size < 1 || size > 4 || stride < 0) {
1424 __glXSetError(gc, GL_INVALID_VALUE);
1425 return;
1426 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001427
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001428 index = arrays->active_texture_unit;
1429 if (index == 0) {
1430 switch (type) {
1431 case GL_SHORT:
1432 opcode = short_ops[size];
1433 break;
1434 case GL_INT:
1435 opcode = int_ops[size];
1436 break;
1437 case GL_FLOAT:
1438 opcode = float_ops[size];
1439 break;
1440 case GL_DOUBLE:
1441 opcode = double_ops[size];
1442 break;
1443 default:
1444 __glXSetError(gc, GL_INVALID_ENUM);
1445 return;
1446 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001447
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001448 header_size = 4;
1449 }
1450 else {
1451 switch (type) {
1452 case GL_SHORT:
1453 opcode = mshort_ops[size];
1454 break;
1455 case GL_INT:
1456 opcode = mint_ops[size];
1457 break;
1458 case GL_FLOAT:
1459 opcode = mfloat_ops[size];
1460 break;
1461 case GL_DOUBLE:
1462 opcode = mdouble_ops[size];
1463 break;
1464 default:
1465 __glXSetError(gc, GL_INVALID_ENUM);
1466 return;
1467 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001468
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001469 header_size = 8;
1470 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001471
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001472 a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
1473 assert(a != NULL);
1474 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
1475 header_size, opcode);
1476
1477 if (a->enabled) {
1478 arrays->array_info_cache_valid = GL_FALSE;
1479 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001480}
1481
1482
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001483void
Paul Berry1a1db172012-11-06 08:57:59 -08001484__indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001485 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001486{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001487 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001488 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001489 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1490 struct array_state_vector *arrays = state->array_state;
1491 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001492
1493
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001494 if (size != 3 || stride < 0) {
1495 __glXSetError(gc, GL_INVALID_VALUE);
1496 return;
1497 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001498
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001499 switch (type) {
1500 case GL_BYTE:
1501 opcode = 4126;
1502 break;
1503 case GL_UNSIGNED_BYTE:
1504 opcode = 4131;
1505 break;
1506 case GL_SHORT:
1507 opcode = 4127;
1508 break;
1509 case GL_UNSIGNED_SHORT:
1510 opcode = 4132;
1511 break;
1512 case GL_INT:
1513 opcode = 4128;
1514 break;
1515 case GL_UNSIGNED_INT:
1516 opcode = 4133;
1517 break;
1518 case GL_FLOAT:
1519 opcode = 4129;
1520 break;
1521 case GL_DOUBLE:
1522 opcode = 4130;
1523 break;
1524 default:
1525 __glXSetError(gc, GL_INVALID_ENUM);
1526 return;
1527 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001528
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001529 a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
1530 if (a == NULL) {
1531 __glXSetError(gc, GL_INVALID_OPERATION);
1532 return;
1533 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001534
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001535 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1536
1537 if (a->enabled) {
1538 arrays->array_info_cache_valid = GL_FALSE;
1539 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001540}
1541
1542
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001543void
Paul Berry1a1db172012-11-06 08:57:59 -08001544__indirect_glFogCoordPointer(GLenum type, GLsizei stride,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001545 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001546{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001547 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001548 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001549 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1550 struct array_state_vector *arrays = state->array_state;
1551 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001552
1553
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001554 if (stride < 0) {
1555 __glXSetError(gc, GL_INVALID_VALUE);
1556 return;
1557 }
Ian Romanickb81efaa2005-03-17 20:13:09 +00001558
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001559 switch (type) {
1560 case GL_FLOAT:
1561 opcode = 4124;
1562 break;
1563 case GL_DOUBLE:
1564 opcode = 4125;
1565 break;
1566 default:
1567 __glXSetError(gc, GL_INVALID_ENUM);
1568 return;
1569 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001570
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001571 a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
1572 if (a == NULL) {
1573 __glXSetError(gc, GL_INVALID_OPERATION);
1574 return;
1575 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001576
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001577 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
Ian Romanickfdb07632005-02-22 22:36:31 +00001578
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001579 if (a->enabled) {
1580 arrays->array_info_cache_valid = GL_FALSE;
1581 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001582}
1583
1584
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001585void
Paul Berry1a1db172012-11-06 08:57:59 -08001586__indirect_glVertexAttribPointer(GLuint index, GLint size,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001587 GLenum type, GLboolean normalized,
1588 GLsizei stride, const GLvoid * pointer)
Ian Romanick40af76b2005-02-25 22:46:30 +00001589{
Colin McDonald5ced1002016-06-22 19:11:55 -07001590 static const uint16_t short_ops[5] = {
1591 0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB,
1592 X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB
1593 };
1594 static const uint16_t float_ops[5] = {
1595 0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB,
1596 X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB
1597 };
1598 static const uint16_t double_ops[5] = {
1599 0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB,
1600 X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB
1601 };
Ian Romanick40af76b2005-02-25 22:46:30 +00001602
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001603 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001604 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001605 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1606 struct array_state_vector *arrays = state->array_state;
1607 struct array_state *a;
1608 unsigned true_immediate_count;
1609 unsigned true_immediate_size;
Ian Romanick40af76b2005-02-25 22:46:30 +00001610
1611
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001612 if ((size < 1) || (size > 4) || (stride < 0)
1613 || (index > arrays->num_vertex_program_attribs)) {
1614 __glXSetError(gc, GL_INVALID_VALUE);
1615 return;
1616 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001617
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001618 if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
1619 switch (type) {
1620 case GL_BYTE:
1621 opcode = X_GLrop_VertexAttrib4NbvARB;
1622 break;
1623 case GL_UNSIGNED_BYTE:
1624 opcode = X_GLrop_VertexAttrib4NubvARB;
1625 break;
1626 case GL_SHORT:
1627 opcode = X_GLrop_VertexAttrib4NsvARB;
1628 break;
1629 case GL_UNSIGNED_SHORT:
1630 opcode = X_GLrop_VertexAttrib4NusvARB;
1631 break;
1632 case GL_INT:
1633 opcode = X_GLrop_VertexAttrib4NivARB;
1634 break;
1635 case GL_UNSIGNED_INT:
1636 opcode = X_GLrop_VertexAttrib4NuivARB;
1637 break;
1638 default:
1639 __glXSetError(gc, GL_INVALID_ENUM);
1640 return;
1641 }
Ian Romanick03dc4372005-02-28 19:37:10 +00001642
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001643 true_immediate_count = 4;
1644 }
1645 else {
1646 true_immediate_count = size;
Ian Romanick40af76b2005-02-25 22:46:30 +00001647
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001648 switch (type) {
1649 case GL_BYTE:
1650 opcode = X_GLrop_VertexAttrib4bvARB;
1651 true_immediate_count = 4;
1652 break;
1653 case GL_UNSIGNED_BYTE:
1654 opcode = X_GLrop_VertexAttrib4ubvARB;
1655 true_immediate_count = 4;
1656 break;
1657 case GL_SHORT:
1658 opcode = short_ops[size];
1659 break;
1660 case GL_UNSIGNED_SHORT:
1661 opcode = X_GLrop_VertexAttrib4usvARB;
1662 true_immediate_count = 4;
1663 break;
1664 case GL_INT:
1665 opcode = X_GLrop_VertexAttrib4ivARB;
1666 true_immediate_count = 4;
1667 break;
1668 case GL_UNSIGNED_INT:
1669 opcode = X_GLrop_VertexAttrib4uivARB;
1670 true_immediate_count = 4;
1671 break;
1672 case GL_FLOAT:
1673 opcode = float_ops[size];
1674 break;
1675 case GL_DOUBLE:
1676 opcode = double_ops[size];
1677 break;
1678 default:
1679 __glXSetError(gc, GL_INVALID_ENUM);
1680 return;
1681 }
1682 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001683
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001684 a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
1685 if (a == NULL) {
1686 __glXSetError(gc, GL_INVALID_OPERATION);
1687 return;
1688 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001689
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001690 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
1691 opcode);
Ian Romanick40af76b2005-02-25 22:46:30 +00001692
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001693 true_immediate_size = __glXTypeSize(type) * true_immediate_count;
1694 ((uint16_t *) (a)->header)[0] = __GLX_PAD(a->header_size
1695 + true_immediate_size);
1696
1697 if (a->enabled) {
1698 arrays->array_info_cache_valid = GL_FALSE;
1699 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001700}
1701
1702
1703/**
1704 * I don't have 100% confidence that this is correct. The different rules
1705 * about whether or not generic vertex attributes alias "classic" vertex
1706 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1707 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1708 * feeling is that the client-side doesn't have to worry about it. The
1709 * client just sends all the data to the server and lets the server deal
1710 * with it.
1711 */
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001712void
1713__indirect_glVertexAttribPointerNV(GLuint index, GLint size,
1714 GLenum type, GLsizei stride,
1715 const GLvoid * pointer)
Ian Romanick40af76b2005-02-25 22:46:30 +00001716{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001717 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001718 GLboolean normalized = GL_FALSE;
Ian Romanick40af76b2005-02-25 22:46:30 +00001719
1720
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001721 switch (type) {
1722 case GL_UNSIGNED_BYTE:
1723 if (size != 4) {
1724 __glXSetError(gc, GL_INVALID_VALUE);
1725 return;
1726 }
1727 normalized = GL_TRUE;
Ian Romanick40af76b2005-02-25 22:46:30 +00001728
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001729 case GL_SHORT:
1730 case GL_FLOAT:
1731 case GL_DOUBLE:
Paul Berry1a1db172012-11-06 08:57:59 -08001732 __indirect_glVertexAttribPointer(index, size, type,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001733 normalized, stride, pointer);
1734 return;
1735 default:
1736 __glXSetError(gc, GL_INVALID_ENUM);
1737 return;
1738 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001739}
1740
1741
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001742void
Paul Berry1a1db172012-11-06 08:57:59 -08001743__indirect_glClientActiveTexture(GLenum texture)
Ian Romanickfdb07632005-02-22 22:36:31 +00001744{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001745 struct glx_context *const gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001746 __GLXattribute *const state =
1747 (__GLXattribute *) (gc->client_state_private);
1748 struct array_state_vector *const arrays = state->array_state;
1749 const GLint unit = (GLint) texture - GL_TEXTURE0;
Ian Romanickfdb07632005-02-22 22:36:31 +00001750
1751
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001752 if ((unit < 0) || (unit >= arrays->num_texture_units)) {
1753 __glXSetError(gc, GL_INVALID_ENUM);
1754 return;
1755 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001756
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001757 arrays->active_texture_unit = unit;
Ian Romanickfdb07632005-02-22 22:36:31 +00001758}
1759
1760
1761/**
Ian Romanick67108ad2008-07-15 11:06:04 -07001762 * Modify the enable state for the selected array
Ian Romanickfdb07632005-02-22 22:36:31 +00001763 */
1764GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001765__glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
Ian Romanick67108ad2008-07-15 11:06:04 -07001766 GLboolean enable)
Ian Romanickfdb07632005-02-22 22:36:31 +00001767{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001768 struct array_state_vector *arrays = state->array_state;
1769 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001770
Ian Romanickfdb07632005-02-22 22:36:31 +00001771
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001772 /* Texture coordinate arrays have an implict index set when the
1773 * application calls glClientActiveTexture.
1774 */
1775 if (key == GL_TEXTURE_COORD_ARRAY) {
1776 index = arrays->active_texture_unit;
1777 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001778
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001779 a = get_array_entry(arrays, key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001780
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001781 if ((a != NULL) && (a->enabled != enable)) {
1782 a->enabled = enable;
1783 arrays->array_info_cache_valid = GL_FALSE;
1784 }
1785
1786 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001787}
1788
1789
1790void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001791__glXArrayDisableAll(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001792{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001793 struct array_state_vector *arrays = state->array_state;
1794 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001795
1796
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001797 for (i = 0; i < arrays->num_arrays; i++) {
1798 arrays->arrays[i].enabled = GL_FALSE;
1799 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001800
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001801 arrays->array_info_cache_valid = GL_FALSE;
Ian Romanickfdb07632005-02-22 22:36:31 +00001802}
1803
1804
1805/**
1806 */
1807GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001808__glXGetArrayEnable(const __GLXattribute * const state,
1809 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001810{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001811 const struct array_state_vector *arrays = state->array_state;
1812 const struct array_state *a =
1813 get_array_entry((struct array_state_vector *) arrays,
1814 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001815
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001816 if (a != NULL) {
1817 *dest = (GLintptr) a->enabled;
1818 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001819
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001820 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001821}
1822
1823
1824/**
1825 */
1826GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001827__glXGetArrayType(const __GLXattribute * const state,
1828 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001829{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001830 const struct array_state_vector *arrays = state->array_state;
1831 const struct array_state *a =
1832 get_array_entry((struct array_state_vector *) arrays,
1833 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001834
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001835 if (a != NULL) {
1836 *dest = (GLintptr) a->data_type;
1837 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001838
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001839 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001840}
1841
1842
1843/**
1844 */
1845GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001846__glXGetArraySize(const __GLXattribute * const state,
1847 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001848{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001849 const struct array_state_vector *arrays = state->array_state;
1850 const struct array_state *a =
1851 get_array_entry((struct array_state_vector *) arrays,
1852 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001853
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001854 if (a != NULL) {
1855 *dest = (GLintptr) a->count;
1856 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001857
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001858 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001859}
1860
1861
1862/**
1863 */
1864GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001865__glXGetArrayStride(const __GLXattribute * const state,
1866 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001867{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001868 const struct array_state_vector *arrays = state->array_state;
1869 const struct array_state *a =
1870 get_array_entry((struct array_state_vector *) arrays,
1871 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001872
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001873 if (a != NULL) {
1874 *dest = (GLintptr) a->user_stride;
1875 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001876
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001877 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001878}
1879
1880
1881/**
1882 */
1883GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001884__glXGetArrayPointer(const __GLXattribute * const state,
1885 GLenum key, unsigned index, void **dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001886{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001887 const struct array_state_vector *arrays = state->array_state;
1888 const struct array_state *a =
1889 get_array_entry((struct array_state_vector *) arrays,
1890 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001891
1892
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001893 if (a != NULL) {
1894 *dest = (void *) (a->data);
1895 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001896
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001897 return (a != NULL);
Ian Romanick40af76b2005-02-25 22:46:30 +00001898}
1899
1900
1901/**
1902 */
1903GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001904__glXGetArrayNormalized(const __GLXattribute * const state,
1905 GLenum key, unsigned index, GLintptr * dest)
Ian Romanick40af76b2005-02-25 22:46:30 +00001906{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001907 const struct array_state_vector *arrays = state->array_state;
1908 const struct array_state *a =
1909 get_array_entry((struct array_state_vector *) arrays,
1910 key, index);
Ian Romanick40af76b2005-02-25 22:46:30 +00001911
1912
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001913 if (a != NULL) {
1914 *dest = (GLintptr) a->normalized;
1915 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001916
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001917 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001918}
1919
1920
1921/**
1922 */
1923GLuint
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001924__glXGetActiveTextureUnit(const __GLXattribute * const state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001925{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001926 return state->array_state->active_texture_unit;
Ian Romanickfdb07632005-02-22 22:36:31 +00001927}
1928
1929
1930void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001931__glXPushArrayState(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001932{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001933 struct array_state_vector *arrays = state->array_state;
1934 struct array_stack_state *stack =
1935 &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1936 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001937
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001938 /* XXX are we pushing _all_ the necessary fields? */
1939 for (i = 0; i < arrays->num_arrays; i++) {
1940 stack[i].data = arrays->arrays[i].data;
1941 stack[i].data_type = arrays->arrays[i].data_type;
1942 stack[i].user_stride = arrays->arrays[i].user_stride;
1943 stack[i].count = arrays->arrays[i].count;
1944 stack[i].key = arrays->arrays[i].key;
1945 stack[i].index = arrays->arrays[i].index;
1946 stack[i].enabled = arrays->arrays[i].enabled;
1947 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001948
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001949 arrays->active_texture_unit_stack[arrays->stack_index] =
Ian Romanickfdb07632005-02-22 22:36:31 +00001950 arrays->active_texture_unit;
1951
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001952 arrays->stack_index++;
Ian Romanickfdb07632005-02-22 22:36:31 +00001953}
1954
1955
1956void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001957__glXPopArrayState(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001958{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001959 struct array_state_vector *arrays = state->array_state;
1960 struct array_stack_state *stack;
1961 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001962
1963
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001964 arrays->stack_index--;
1965 stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
Ian Romanickfdb07632005-02-22 22:36:31 +00001966
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001967 for (i = 0; i < arrays->num_arrays; i++) {
1968 switch (stack[i].key) {
1969 case GL_NORMAL_ARRAY:
1970 __indirect_glNormalPointer(stack[i].data_type,
1971 stack[i].user_stride, stack[i].data);
1972 break;
1973 case GL_COLOR_ARRAY:
1974 __indirect_glColorPointer(stack[i].count,
1975 stack[i].data_type,
1976 stack[i].user_stride, stack[i].data);
1977 break;
1978 case GL_INDEX_ARRAY:
1979 __indirect_glIndexPointer(stack[i].data_type,
1980 stack[i].user_stride, stack[i].data);
1981 break;
1982 case GL_EDGE_FLAG_ARRAY:
1983 __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
1984 break;
1985 case GL_TEXTURE_COORD_ARRAY:
1986 arrays->active_texture_unit = stack[i].index;
1987 __indirect_glTexCoordPointer(stack[i].count,
1988 stack[i].data_type,
1989 stack[i].user_stride, stack[i].data);
1990 break;
1991 case GL_SECONDARY_COLOR_ARRAY:
Paul Berry1a1db172012-11-06 08:57:59 -08001992 __indirect_glSecondaryColorPointer(stack[i].count,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001993 stack[i].data_type,
1994 stack[i].user_stride,
1995 stack[i].data);
1996 break;
1997 case GL_FOG_COORDINATE_ARRAY:
Paul Berry1a1db172012-11-06 08:57:59 -08001998 __indirect_glFogCoordPointer(stack[i].data_type,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001999 stack[i].user_stride, stack[i].data);
2000 break;
Ian Romanickfdb07632005-02-22 22:36:31 +00002001
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02002002 }
Ian Romanickfdb07632005-02-22 22:36:31 +00002003
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02002004 __glXSetArrayEnable(state, stack[i].key, stack[i].index,
2005 stack[i].enabled);
2006 }
2007
2008 arrays->active_texture_unit =
2009 arrays->active_texture_unit_stack[arrays->stack_index];
Ian Romanickfdb07632005-02-22 22:36:31 +00002010}