blob: c81aae603866c8f3e7d7ba9e2a01c9a409f48787 [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));
Matt Turner2c866682016-06-22 23:11:27 -0700154 state->array_state = arrays;
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700155
156 if (arrays == NULL) {
157 __glXSetError(gc, GL_OUT_OF_MEMORY);
158 return;
159 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000160
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200161 arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
162 arrays->new_DrawArrays_possible = GL_FALSE;
163 arrays->DrawArrays = NULL;
Ian Romanickfdb07632005-02-22 22:36:31 +0000164
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200165 arrays->active_texture_unit = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000166
167
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200168 /* Determine how many arrays are actually needed. Only arrays that
169 * are supported by the server are create. For example, if the server
170 * supports only 2 texture units, then only 2 texture coordinate arrays
171 * are created.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200172 *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200173 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
174 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
175 * GL_EDGE_FLAG_ARRAY are supported.
176 */
Ian Romanick979f35f2005-03-17 20:36:20 +0000177
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200178 array_count = 5;
Ian Romanickfdb07632005-02-22 22:36:31 +0000179
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200180 if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
181 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
182 got_fog = GL_TRUE;
183 array_count++;
184 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000185
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200186 if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
187 || (gc->server_major > 1) || (gc->server_minor >= 4)) {
188 got_secondary_color = GL_TRUE;
189 array_count++;
190 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000191
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200192 if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit)
193 || (gc->server_major > 1) || (gc->server_minor >= 3)) {
194 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
195 }
Ian Romanick40af76b2005-02-25 22:46:30 +0000196
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200197 if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) {
198 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
199 GL_MAX_PROGRAM_ATTRIBS_ARB,
200 &vertex_program_attribs);
201 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000202
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200203 arrays->num_texture_units = texture_units;
204 arrays->num_vertex_program_attribs = vertex_program_attribs;
205 array_count += texture_units + vertex_program_attribs;
206 arrays->num_arrays = array_count;
207 arrays->arrays = calloc(array_count, sizeof(struct array_state));
Ian Romanickfdb07632005-02-22 22:36:31 +0000208
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700209 if (arrays->arrays == NULL) {
Matt Turner66241742016-06-22 23:11:27 -0700210 state->array_state = NULL;
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700211 free(arrays);
212 __glXSetError(gc, GL_OUT_OF_MEMORY);
213 return;
214 }
215
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200216 arrays->arrays[0].data_type = GL_FLOAT;
217 arrays->arrays[0].count = 3;
218 arrays->arrays[0].key = GL_NORMAL_ARRAY;
219 arrays->arrays[0].normalized = GL_TRUE;
220 arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000221
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200222 arrays->arrays[1].data_type = GL_FLOAT;
223 arrays->arrays[1].count = 4;
224 arrays->arrays[1].key = GL_COLOR_ARRAY;
225 arrays->arrays[1].normalized = GL_TRUE;
226 arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000227
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200228 arrays->arrays[2].data_type = GL_FLOAT;
229 arrays->arrays[2].count = 1;
230 arrays->arrays[2].key = GL_INDEX_ARRAY;
231 arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000232
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200233 arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
234 arrays->arrays[3].count = 1;
235 arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
236 arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
Ian Romanick40af76b2005-02-25 22:46:30 +0000237
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200238 for (i = 0; i < texture_units; i++) {
239 arrays->arrays[4 + i].data_type = GL_FLOAT;
240 arrays->arrays[4 + i].count = 4;
241 arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
Ian Romanickfdb07632005-02-22 22:36:31 +0000242
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200243 arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
244 arrays->arrays[4 + i].index = i;
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200245 }
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;
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200277 }
Ian Romanick40af76b2005-02-25 22:46:30 +0000278
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200279 i += vertex_program_attribs;
Ian Romanick40af76b2005-02-25 22:46:30 +0000280
281
Zoë Blade05e7f7f2015-04-22 11:33:17 +0100282 /* Vertex array *must* be last because of the way that
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200283 * emit_DrawArrays_none works.
284 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000285
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200286 arrays->arrays[i].data_type = GL_FLOAT;
287 arrays->arrays[i].count = 4;
288 arrays->arrays[i].key = GL_VERTEX_ARRAY;
289 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000290
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200291 assert((i + 1) == arrays->num_arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000292
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200293 arrays->stack_index = 0;
294 arrays->stack = malloc(sizeof(struct array_stack_state)
Markus Fleschutz83f11832010-02-26 10:34:19 -0700295 * arrays->num_arrays
296 * __GL_CLIENT_ATTRIB_STACK_DEPTH);
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700297
298 if (arrays->stack == NULL) {
Matt Turner66241742016-06-22 23:11:27 -0700299 state->array_state = NULL;
Juha-Pekka Heikkilad41f5392014-01-03 05:57:00 -0700300 free(arrays->arrays);
301 free(arrays);
302 __glXSetError(gc, GL_OUT_OF_MEMORY);
303 return;
304 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000305}
306
307
308/**
309 * Calculate the size of a single vertex for the "none" protocol. This is
310 * essentially the size of all the immediate-mode commands required to
311 * implement the enabled vertex arrays.
312 */
313static size_t
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200314calculate_single_vertex_size_none(const struct array_state_vector *arrays)
Ian Romanickfdb07632005-02-22 22:36:31 +0000315{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200316 size_t single_vertex_size = 0;
317 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000318
319
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200320 for (i = 0; i < arrays->num_arrays; i++) {
321 if (arrays->arrays[i].enabled) {
Colin McDonaldb36644b2016-06-22 19:19:30 -0700322 single_vertex_size += arrays->arrays[i].header[0];
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200323 }
324 }
325
326 return single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000327}
328
329
330/**
331 * Emit a single element using non-DrawArrays protocol.
332 */
333GLubyte *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200334emit_element_none(GLubyte * dst,
335 const struct array_state_vector * arrays, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000336{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200337 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000338
339
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200340 for (i = 0; i < arrays->num_arrays; i++) {
341 if (arrays->arrays[i].enabled) {
342 const size_t offset = index * arrays->arrays[i].true_stride;
Ian Romanickfdb07632005-02-22 22:36:31 +0000343
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200344 /* The generic attributes can have more data than is in the
345 * elements. This is because a vertex array can be a 2 element,
346 * normalized, unsigned short, but the "closest" immediate mode
347 * protocol is for a 4Nus. Since the sizes are small, the
348 * performance impact on modern processors should be negligible.
349 */
Colin McDonaldb36644b2016-06-22 19:19:30 -0700350 (void) memset(dst, 0, arrays->arrays[i].header[0]);
Ian Romanick40af76b2005-02-25 22:46:30 +0000351
Colin McDonaldb36644b2016-06-22 19:19:30 -0700352 (void) memcpy(dst, arrays->arrays[i].header, 4);
Ian Romanickfdb07632005-02-22 22:36:31 +0000353
Colin McDonaldb36644b2016-06-22 19:19:30 -0700354 dst += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000355
Colin McDonaldb36644b2016-06-22 19:19:30 -0700356 if (arrays->arrays[i].key == GL_TEXTURE_COORD_ARRAY &&
357 arrays->arrays[i].index > 0) {
358 /* Multi-texture coordinate arrays require the texture target
359 * to be sent. For doubles it is after the data, for everything
360 * else it is before.
361 */
362 GLenum texture = arrays->arrays[i].index + GL_TEXTURE0;
363 if (arrays->arrays[i].data_type == GL_DOUBLE) {
364 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
365 arrays->arrays[i].element_size);
366 dst += arrays->arrays[i].element_size;
367 (void) memcpy(dst, &texture, 4);
368 dst += 4;
369 } else {
370 (void) memcpy(dst, &texture, 4);
371 dst += 4;
372 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
373 arrays->arrays[i].element_size);
374 dst += __GLX_PAD(arrays->arrays[i].element_size);
375 }
376 } else if (arrays->arrays[i].key == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
377 /* Vertex attribute data requires the index sent first.
378 */
379 (void) memcpy(dst, &arrays->arrays[i].index, 4);
380 dst += 4;
381 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
382 arrays->arrays[i].element_size);
383 dst += __GLX_PAD(arrays->arrays[i].element_size);
384 } else {
385 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
386 arrays->arrays[i].element_size);
387 dst += __GLX_PAD(arrays->arrays[i].element_size);
388 }
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200389 }
390 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000391
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200392 return dst;
Ian Romanickfdb07632005-02-22 22:36:31 +0000393}
394
395
396/**
397 * Emit a single element using "old" DrawArrays protocol from
398 * EXT_vertex_arrays / OpenGL 1.1.
399 */
400GLubyte *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200401emit_element_old(GLubyte * dst,
402 const struct array_state_vector * arrays, 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
406
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200407 for (i = 0; i < arrays->num_arrays; i++) {
408 if (arrays->arrays[i].enabled) {
409 const size_t offset = index * arrays->arrays[i].true_stride;
Ian Romanickfdb07632005-02-22 22:36:31 +0000410
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200411 (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
412 arrays->arrays[i].element_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000413
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200414 dst += __GLX_PAD(arrays->arrays[i].element_size);
415 }
416 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000417
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200418 return dst;
Ian Romanickfdb07632005-02-22 22:36:31 +0000419}
420
421
422struct array_state *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200423get_array_entry(const struct array_state_vector *arrays,
424 GLenum key, unsigned index)
Ian Romanickfdb07632005-02-22 22:36:31 +0000425{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200426 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000427
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200428 for (i = 0; i < arrays->num_arrays; i++) {
429 if ((arrays->arrays[i].key == key)
430 && (arrays->arrays[i].index == index)) {
431 return &arrays->arrays[i];
432 }
433 }
434
435 return NULL;
Ian Romanickfdb07632005-02-22 22:36:31 +0000436}
437
438
439static GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200440allocate_array_info_cache(struct array_state_vector *arrays,
441 size_t required_size)
Ian Romanickfdb07632005-02-22 22:36:31 +0000442{
Ian Romanick979f35f2005-03-17 20:36:20 +0000443#define MAX_HEADER_SIZE 20
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200444 if (arrays->array_info_cache_buffer_size < required_size) {
445 GLubyte *temp = realloc(arrays->array_info_cache_base,
446 required_size + MAX_HEADER_SIZE);
Ian Romanickfdb07632005-02-22 22:36:31 +0000447
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200448 if (temp == NULL) {
449 return GL_FALSE;
450 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000451
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200452 arrays->array_info_cache_base = temp;
453 arrays->array_info_cache = temp + MAX_HEADER_SIZE;
454 arrays->array_info_cache_buffer_size = required_size;
455 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000456
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200457 arrays->array_info_cache_size = required_size;
458 return GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000459}
460
461
462/**
463 */
464void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200465fill_array_info_cache(struct array_state_vector *arrays)
Ian Romanickfdb07632005-02-22 22:36:31 +0000466{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200467 GLboolean old_DrawArrays_possible;
468 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000469
470
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200471 /* Determine how many arrays are enabled.
472 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000473
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200474 arrays->enabled_client_array_count = 0;
475 old_DrawArrays_possible = arrays->old_DrawArrays_possible;
476 for (i = 0; i < arrays->num_arrays; i++) {
477 if (arrays->arrays[i].enabled) {
478 arrays->enabled_client_array_count++;
479 old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
480 }
481 }
482
483 if (arrays->new_DrawArrays_possible) {
484 assert(!arrays->new_DrawArrays_possible);
485 }
486 else if (old_DrawArrays_possible) {
487 const size_t required_size = arrays->enabled_client_array_count * 12;
488 uint32_t *info;
Ian Romanickfdb07632005-02-22 22:36:31 +0000489
490
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200491 if (!allocate_array_info_cache(arrays, required_size)) {
492 return;
493 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000494
495
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200496 info = (uint32_t *) arrays->array_info_cache;
497 for (i = 0; i < arrays->num_arrays; i++) {
498 if (arrays->arrays[i].enabled) {
499 *(info++) = arrays->arrays[i].data_type;
500 *(info++) = arrays->arrays[i].count;
501 *(info++) = arrays->arrays[i].key;
502 }
503 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000504
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200505 arrays->DrawArrays = emit_DrawArrays_old;
506 arrays->DrawElements = emit_DrawElements_old;
507 }
508 else {
509 arrays->DrawArrays = emit_DrawArrays_none;
510 arrays->DrawElements = emit_DrawElements_none;
511 }
Ian Romanickb81efaa2005-03-17 20:13:09 +0000512
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200513 arrays->array_info_cache_valid = GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000514}
515
516
517/**
518 * Emit a \c glDrawArrays command using the "none" protocol. That is,
519 * emit immediate-mode commands that are equivalent to the requiested
520 * \c glDrawArrays command. This is used with servers that don't support
521 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
522 * vertex state is enabled that is not compatible with that protocol.
523 */
524void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200525emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000526{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400527 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200528 const __GLXattribute *state =
529 (const __GLXattribute *) (gc->client_state_private);
530 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000531
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200532 size_t single_vertex_size;
533 GLubyte *pc;
534 unsigned i;
535 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
536 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
Ian Romanickfdb07632005-02-22 22:36:31 +0000537
538
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200539 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000540
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200541 pc = gc->pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000542
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200543 (void) memcpy(pc, begin_cmd, 4);
544 *(int *) (pc + 4) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000545
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200546 pc += 8;
Ian Romanickfdb07632005-02-22 22:36:31 +0000547
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200548 for (i = 0; i < count; i++) {
549 if ((pc + single_vertex_size) >= gc->bufEnd) {
550 pc = __glXFlushRenderBuffer(gc, pc);
551 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000552
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200553 pc = emit_element_none(pc, arrays, first + i);
554 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000555
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200556 if ((pc + 4) >= gc->bufEnd) {
557 pc = __glXFlushRenderBuffer(gc, pc);
558 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000559
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200560 (void) memcpy(pc, end_cmd, 4);
561 pc += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000562
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200563 gc->pc = pc;
564 if (gc->pc > gc->limit) {
565 (void) __glXFlushRenderBuffer(gc, gc->pc);
566 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000567}
568
569
570/**
571 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
572 * protocol.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200573 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000574 * \param gc GLX context.
575 * \param arrays Array state.
576 * \param elements_per_request Location to store the number of elements that
577 * can fit in a single Render / RenderLarge
578 * command.
579 * \param total_request Total number of requests for a RenderLarge
580 * command. If a Render command is used, this
581 * will be zero.
582 * \param mode Drawing mode.
583 * \param count Number of vertices.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200584 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000585 * \returns
586 * A pointer to the buffer for array data.
587 */
588static GLubyte *
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400589emit_DrawArrays_header_old(struct glx_context * gc,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200590 struct array_state_vector *arrays,
591 size_t * elements_per_request,
592 unsigned int *total_requests,
593 GLenum mode, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000594{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200595 size_t command_size;
596 size_t single_vertex_size;
597 const unsigned header_size = 16;
598 unsigned i;
599 GLubyte *pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000600
601
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200602 /* Determine the size of the whole command. This includes the header,
603 * the ARRAY_INFO data and the array data. Once this size is calculated,
604 * it will be known whether a Render or RenderLarge command is needed.
605 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000606
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200607 single_vertex_size = 0;
608 for (i = 0; i < arrays->num_arrays; i++) {
609 if (arrays->arrays[i].enabled) {
610 single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
611 }
612 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000613
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200614 command_size = arrays->array_info_cache_size + header_size
Ian Romanickfdb07632005-02-22 22:36:31 +0000615 + (single_vertex_size * count);
616
617
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200618 /* Write the header for either a Render command or a RenderLarge
619 * command. After the header is written, write the ARRAY_INFO data.
620 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000621
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200622 if (command_size > gc->maxSmallRenderCommandSize) {
623 /* maxSize is the maximum amount of data can be stuffed into a single
624 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
625 * packet size minus sz_xGLXRenderReq.
626 */
627 const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
628 - sz_xGLXRenderLargeReq;
629 unsigned vertex_requests;
Ian Romanickfdb07632005-02-22 22:36:31 +0000630
631
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200632 /* Calculate the number of data packets that will be required to send
633 * the whole command. To do this, the number of verticies that
634 * will fit in a single buffer must be calculated.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200635 *
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200636 * The important value here is elements_per_request. This is the
637 * number of complete array elements that will fit in a single
638 * buffer. There may be some wasted space at the end of the buffer,
639 * but splitting elements across buffer boundries would be painful.
640 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000641
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200642 elements_per_request[0] = maxSize / single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000643
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200644 vertex_requests = (count + elements_per_request[0] - 1)
645 / elements_per_request[0];
646
647 *total_requests = vertex_requests + 1;
Ian Romanickfdb07632005-02-22 22:36:31 +0000648
649
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200650 __glXFlushRenderBuffer(gc, gc->pc);
Ian Romanickfdb07632005-02-22 22:36:31 +0000651
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200652 command_size += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000653
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200654 pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
655 *(uint32_t *) (pc + 0) = command_size;
656 *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
657 *(uint32_t *) (pc + 8) = count;
658 *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
659 *(uint32_t *) (pc + 16) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000660
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200661 __glXSendLargeChunk(gc, 1, *total_requests, pc,
662 header_size + 4 + arrays->array_info_cache_size);
Ian Romanickfdb07632005-02-22 22:36:31 +0000663
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200664 pc = gc->pc;
665 }
666 else {
667 if ((gc->pc + command_size) >= gc->bufEnd) {
668 (void) __glXFlushRenderBuffer(gc, gc->pc);
669 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000670
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200671 pc = gc->pc;
672 *(uint16_t *) (pc + 0) = command_size;
673 *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
674 *(uint32_t *) (pc + 4) = count;
675 *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
676 *(uint32_t *) (pc + 12) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000677
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200678 pc += header_size;
Ian Romanickfdb07632005-02-22 22:36:31 +0000679
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200680 (void) memcpy(pc, arrays->array_info_cache,
681 arrays->array_info_cache_size);
682 pc += arrays->array_info_cache_size;
Ian Romanickb81efaa2005-03-17 20:13:09 +0000683
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200684 *elements_per_request = count;
685 *total_requests = 0;
686 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000687
688
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200689 return pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000690}
691
692
693/**
694 */
695void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200696emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000697{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400698 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200699 const __GLXattribute *state =
700 (const __GLXattribute *) (gc->client_state_private);
701 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000702
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200703 GLubyte *pc;
704 size_t elements_per_request;
705 unsigned total_requests = 0;
706 unsigned i;
707 size_t total_sent = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000708
709
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200710 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
711 &total_requests, mode, count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000712
713
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200714 /* Write the arrays.
715 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000716
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200717 if (total_requests == 0) {
718 assert(elements_per_request >= count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000719
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200720 for (i = 0; i < count; i++) {
721 pc = emit_element_old(pc, arrays, i + first);
722 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000723
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200724 assert(pc <= gc->bufEnd);
Ian Romanickfdb07632005-02-22 22:36:31 +0000725
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200726 gc->pc = pc;
727 if (gc->pc > gc->limit) {
728 (void) __glXFlushRenderBuffer(gc, gc->pc);
729 }
730 }
731 else {
732 unsigned req;
733
734
735 for (req = 2; req <= total_requests; req++) {
736 if (count < elements_per_request) {
737 elements_per_request = count;
738 }
739
740 pc = gc->pc;
741 for (i = 0; i < elements_per_request; i++) {
742 pc = emit_element_old(pc, arrays, i + first);
743 }
744
745 first += elements_per_request;
746
747 total_sent += (size_t) (pc - gc->pc);
748 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
749
750 count -= elements_per_request;
751 }
752 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000753}
754
755
756void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200757emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
758 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000759{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400760 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200761 const __GLXattribute *state =
762 (const __GLXattribute *) (gc->client_state_private);
763 struct array_state_vector *arrays = state->array_state;
764 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
765 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
Ian Romanickfdb07632005-02-22 22:36:31 +0000766
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200767 GLubyte *pc;
768 size_t single_vertex_size;
769 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +0000770
771
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200772 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +0000773
774
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200775 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
776 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
777 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000778
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200779 pc = gc->pc;
Ian Romanickfdb07632005-02-22 22:36:31 +0000780
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200781 (void) memcpy(pc, begin_cmd, 4);
782 *(int *) (pc + 4) = mode;
Ian Romanickfdb07632005-02-22 22:36:31 +0000783
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200784 pc += 8;
Ian Romanickfdb07632005-02-22 22:36:31 +0000785
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200786 for (i = 0; i < count; i++) {
787 unsigned index = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000788
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200789 if ((pc + single_vertex_size) >= gc->bufEnd) {
790 pc = __glXFlushRenderBuffer(gc, pc);
791 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000792
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200793 switch (type) {
794 case GL_UNSIGNED_INT:
795 index = (unsigned) (((GLuint *) indices)[i]);
796 break;
797 case GL_UNSIGNED_SHORT:
798 index = (unsigned) (((GLushort *) indices)[i]);
799 break;
800 case GL_UNSIGNED_BYTE:
801 index = (unsigned) (((GLubyte *) indices)[i]);
802 break;
803 }
804 pc = emit_element_none(pc, arrays, index);
805 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000806
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200807 if ((pc + 4) >= gc->bufEnd) {
808 pc = __glXFlushRenderBuffer(gc, pc);
809 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000810
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200811 (void) memcpy(pc, end_cmd, 4);
812 pc += 4;
Ian Romanickfdb07632005-02-22 22:36:31 +0000813
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200814 gc->pc = pc;
815 if (gc->pc > gc->limit) {
816 (void) __glXFlushRenderBuffer(gc, gc->pc);
817 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000818}
819
820
821/**
822 */
823void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200824emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
825 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +0000826{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400827 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200828 const __GLXattribute *state =
829 (const __GLXattribute *) (gc->client_state_private);
830 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000831
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200832 GLubyte *pc;
833 size_t elements_per_request;
834 unsigned total_requests = 0;
835 unsigned i;
836 unsigned req;
837 unsigned req_element = 0;
Ian Romanickfdb07632005-02-22 22:36:31 +0000838
839
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200840 pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
841 &total_requests, mode, count);
Ian Romanickfdb07632005-02-22 22:36:31 +0000842
843
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200844 /* Write the arrays.
845 */
Ian Romanickfdb07632005-02-22 22:36:31 +0000846
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200847 req = 2;
848 while (count > 0) {
849 if (count < elements_per_request) {
850 elements_per_request = count;
851 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000852
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200853 switch (type) {
854 case GL_UNSIGNED_INT:{
855 const GLuint *ui_ptr = (const GLuint *) indices + req_element;
856
857 for (i = 0; i < elements_per_request; i++) {
858 const GLint index = (GLint) * (ui_ptr++);
859 pc = emit_element_old(pc, arrays, index);
860 }
861 break;
862 }
863 case GL_UNSIGNED_SHORT:{
864 const GLushort *us_ptr = (const GLushort *) indices + req_element;
865
866 for (i = 0; i < elements_per_request; i++) {
867 const GLint index = (GLint) * (us_ptr++);
868 pc = emit_element_old(pc, arrays, index);
869 }
870 break;
871 }
872 case GL_UNSIGNED_BYTE:{
873 const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;
874
875 for (i = 0; i < elements_per_request; i++) {
876 const GLint index = (GLint) * (ub_ptr++);
877 pc = emit_element_old(pc, arrays, index);
878 }
879 break;
880 }
881 }
882
883 if (total_requests != 0) {
884 __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
885 pc = gc->pc;
886 req++;
887 }
888
889 count -= elements_per_request;
890 req_element += elements_per_request;
891 }
892
893
894 assert((total_requests == 0) || ((req - 1) == total_requests));
895
896 if (total_requests == 0) {
897 assert(pc <= gc->bufEnd);
898
899 gc->pc = pc;
900 if (gc->pc > gc->limit) {
901 (void) __glXFlushRenderBuffer(gc, gc->pc);
902 }
903 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000904}
905
906
907/**
908 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
909 * If it is not valid, then an error code is set in the GLX context.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200910 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000911 * \returns
912 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
913 */
914static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400915validate_mode(struct glx_context * gc, GLenum mode)
Ian Romanickfdb07632005-02-22 22:36:31 +0000916{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200917 switch (mode) {
918 case GL_POINTS:
919 case GL_LINE_STRIP:
920 case GL_LINE_LOOP:
921 case GL_LINES:
922 case GL_TRIANGLE_STRIP:
923 case GL_TRIANGLE_FAN:
924 case GL_TRIANGLES:
925 case GL_QUAD_STRIP:
926 case GL_QUADS:
927 case GL_POLYGON:
928 break;
929 default:
930 __glXSetError(gc, GL_INVALID_ENUM);
931 return GL_FALSE;
932 }
933
934 return GL_TRUE;
Ian Romanickfdb07632005-02-22 22:36:31 +0000935}
936
937
938/**
939 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
940 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
941 * being set. A value of zero will not result in an error being set, but
942 * will result in \c GL_FALSE being returned.
RALOVICH, Kristóf08962682009-08-12 12:41:22 +0200943 *
Ian Romanickfdb07632005-02-22 22:36:31 +0000944 * \returns
945 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
946 */
947static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400948validate_count(struct glx_context * gc, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000949{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200950 if (count < 0) {
951 __glXSetError(gc, GL_INVALID_VALUE);
952 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000953
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200954 return (count > 0);
Ian Romanickfdb07632005-02-22 22:36:31 +0000955}
956
957
Ian Romanick03dc4372005-02-28 19:37:10 +0000958/**
959 * Validate that the \c type parameter to \c glDrawElements, et. al. is
960 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
961 * \c GL_UNSIGNED_INT are valid.
962 *
963 * \returns
964 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
965 */
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200966static GLboolean
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400967validate_type(struct glx_context * gc, GLenum type)
Ian Romanick03dc4372005-02-28 19:37:10 +0000968{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200969 switch (type) {
970 case GL_UNSIGNED_INT:
971 case GL_UNSIGNED_SHORT:
972 case GL_UNSIGNED_BYTE:
973 return GL_TRUE;
974 default:
975 __glXSetError(gc, GL_INVALID_ENUM);
976 return GL_FALSE;
977 }
Ian Romanick03dc4372005-02-28 19:37:10 +0000978}
979
980
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200981void
982__indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
Ian Romanickfdb07632005-02-22 22:36:31 +0000983{
Kristian Høgsbergc356f582010-07-28 11:16:00 -0400984 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200985 const __GLXattribute *state =
986 (const __GLXattribute *) (gc->client_state_private);
987 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +0000988
Ian Romanickfdb07632005-02-22 22:36:31 +0000989
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +0200990 if (validate_mode(gc, mode) && validate_count(gc, count)) {
991 if (!arrays->array_info_cache_valid) {
992 fill_array_info_cache(arrays);
993 }
994
995 arrays->DrawArrays(mode, first, count);
996 }
Ian Romanickfdb07632005-02-22 22:36:31 +0000997}
998
999
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001000void
1001__indirect_glArrayElement(GLint index)
Ian Romanickfdb07632005-02-22 22:36:31 +00001002{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001003 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001004 const __GLXattribute *state =
1005 (const __GLXattribute *) (gc->client_state_private);
1006 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +00001007
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001008 size_t single_vertex_size;
Ian Romanickfdb07632005-02-22 22:36:31 +00001009
1010
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001011 single_vertex_size = calculate_single_vertex_size_none(arrays);
Ian Romanickfdb07632005-02-22 22:36:31 +00001012
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001013 if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
1014 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
1015 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001016
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001017 gc->pc = emit_element_none(gc->pc, arrays, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001018
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001019 if (gc->pc > gc->limit) {
1020 (void) __glXFlushRenderBuffer(gc, gc->pc);
1021 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001022}
1023
1024
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001025void
1026__indirect_glDrawElements(GLenum mode, 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 (!arrays->array_info_cache_valid) {
1038 fill_array_info_cache(arrays);
1039 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001040
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001041 arrays->DrawElements(mode, count, type, indices);
1042 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001043}
1044
1045
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001046void
1047__indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1048 GLsizei count, GLenum type,
1049 const GLvoid * indices)
Ian Romanickfdb07632005-02-22 22:36:31 +00001050{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001051 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001052 const __GLXattribute *state =
1053 (const __GLXattribute *) (gc->client_state_private);
1054 struct array_state_vector *arrays = state->array_state;
Ian Romanickfdb07632005-02-22 22:36:31 +00001055
1056
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001057 if (validate_mode(gc, mode) && validate_count(gc, count)
1058 && validate_type(gc, type)) {
1059 if (end < start) {
1060 __glXSetError(gc, GL_INVALID_VALUE);
1061 return;
1062 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001063
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001064 if (!arrays->array_info_cache_valid) {
1065 fill_array_info_cache(arrays);
1066 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001067
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001068 arrays->DrawElements(mode, count, type, indices);
1069 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001070}
1071
1072
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001073void
Paul Berry1a1db172012-11-06 08:57:59 -08001074__indirect_glMultiDrawArrays(GLenum mode, const GLint *first,
Brian Paul4cd751b2010-09-14 11:01:03 -06001075 const GLsizei *count, GLsizei primcount)
Ian Romanickfdb07632005-02-22 22:36:31 +00001076{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001077 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001078 const __GLXattribute *state =
1079 (const __GLXattribute *) (gc->client_state_private);
1080 struct array_state_vector *arrays = state->array_state;
1081 GLsizei i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001082
1083
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001084 if (validate_mode(gc, mode)) {
1085 if (!arrays->array_info_cache_valid) {
1086 fill_array_info_cache(arrays);
1087 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001088
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001089 for (i = 0; i < primcount; i++) {
1090 if (validate_count(gc, count[i])) {
1091 arrays->DrawArrays(mode, first[i], count[i]);
1092 }
1093 }
1094 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001095}
1096
1097
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001098void
1099__indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
Eric Anholtfc32d402013-06-26 12:24:08 -07001100 GLenum type, const GLvoid * const * indices,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001101 GLsizei primcount)
Ian Romanickfdb07632005-02-22 22:36:31 +00001102{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001103 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001104 const __GLXattribute *state =
1105 (const __GLXattribute *) (gc->client_state_private);
1106 struct array_state_vector *arrays = state->array_state;
1107 GLsizei i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001108
1109
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001110 if (validate_mode(gc, mode) && validate_type(gc, type)) {
1111 if (!arrays->array_info_cache_valid) {
1112 fill_array_info_cache(arrays);
1113 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001114
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001115 for (i = 0; i < primcount; i++) {
1116 if (validate_count(gc, count[i])) {
1117 arrays->DrawElements(mode, count[i], type, indices[i]);
1118 }
1119 }
1120 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001121}
1122
1123
Colin McDonaldb36644b2016-06-22 19:19:30 -07001124/* The HDR_SIZE macro argument is the command header size (4 bytes)
1125 * plus any additional index word e.g. for texture units or vertex
1126 * attributes.
1127 */
Ian Romanickb81efaa2005-03-17 20:13:09 +00001128#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001129 do { \
1130 (a)->data = PTR; \
1131 (a)->data_type = TYPE; \
1132 (a)->user_stride = STRIDE; \
1133 (a)->count = COUNT; \
1134 (a)->normalized = NORMALIZED; \
1135 \
1136 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1137 (a)->true_stride = (STRIDE == 0) \
1138 ? (a)->element_size : STRIDE; \
1139 \
Colin McDonaldb36644b2016-06-22 19:19:30 -07001140 (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size); \
1141 (a)->header[1] = OPCODE; \
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001142 } while(0)
Ian Romanickfdb07632005-02-22 22:36:31 +00001143
1144
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001145void
1146__indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
1147 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001148{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001149 static const uint16_t short_ops[5] = {
1150 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1151 };
1152 static const uint16_t int_ops[5] = {
1153 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1154 };
1155 static const uint16_t float_ops[5] = {
1156 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1157 };
1158 static const uint16_t double_ops[5] = {
1159 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1160 };
1161 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001162 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001163 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1164 struct array_state_vector *arrays = state->array_state;
1165 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001166
1167
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001168 if (size < 2 || size > 4 || stride < 0) {
1169 __glXSetError(gc, GL_INVALID_VALUE);
1170 return;
1171 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001172
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001173 switch (type) {
1174 case GL_SHORT:
1175 opcode = short_ops[size];
1176 break;
1177 case GL_INT:
1178 opcode = int_ops[size];
1179 break;
1180 case GL_FLOAT:
1181 opcode = float_ops[size];
1182 break;
1183 case GL_DOUBLE:
1184 opcode = double_ops[size];
1185 break;
1186 default:
1187 __glXSetError(gc, GL_INVALID_ENUM);
1188 return;
1189 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001190
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001191 a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
1192 assert(a != NULL);
1193 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
1194 opcode);
1195
1196 if (a->enabled) {
1197 arrays->array_info_cache_valid = GL_FALSE;
1198 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001199}
1200
1201
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001202void
1203__indirect_glNormalPointer(GLenum type, GLsizei stride,
1204 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001205{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001206 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001207 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001208 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1209 struct array_state_vector *arrays = state->array_state;
1210 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001211
1212
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001213 if (stride < 0) {
1214 __glXSetError(gc, GL_INVALID_VALUE);
1215 return;
1216 }
Ian Romanickb81efaa2005-03-17 20:13:09 +00001217
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001218 switch (type) {
1219 case GL_BYTE:
1220 opcode = X_GLrop_Normal3bv;
1221 break;
1222 case GL_SHORT:
1223 opcode = X_GLrop_Normal3sv;
1224 break;
1225 case GL_INT:
1226 opcode = X_GLrop_Normal3iv;
1227 break;
1228 case GL_FLOAT:
1229 opcode = X_GLrop_Normal3fv;
1230 break;
1231 case GL_DOUBLE:
1232 opcode = X_GLrop_Normal3dv;
1233 break;
1234 default:
1235 __glXSetError(gc, GL_INVALID_ENUM);
1236 return;
1237 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001238
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001239 a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
1240 assert(a != NULL);
1241 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);
Ian Romanickfdb07632005-02-22 22:36:31 +00001242
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001243 if (a->enabled) {
1244 arrays->array_info_cache_valid = GL_FALSE;
1245 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001246}
1247
1248
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001249void
1250__indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
1251 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001252{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001253 static const uint16_t byte_ops[5] = {
1254 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1255 };
1256 static const uint16_t ubyte_ops[5] = {
1257 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1258 };
1259 static const uint16_t short_ops[5] = {
1260 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1261 };
1262 static const uint16_t ushort_ops[5] = {
1263 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1264 };
1265 static const uint16_t int_ops[5] = {
1266 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1267 };
1268 static const uint16_t uint_ops[5] = {
1269 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1270 };
1271 static const uint16_t float_ops[5] = {
1272 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1273 };
1274 static const uint16_t double_ops[5] = {
1275 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1276 };
1277 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001278 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001279 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1280 struct array_state_vector *arrays = state->array_state;
1281 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001282
1283
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001284 if (size < 3 || size > 4 || stride < 0) {
1285 __glXSetError(gc, GL_INVALID_VALUE);
1286 return;
1287 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001288
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001289 switch (type) {
1290 case GL_BYTE:
1291 opcode = byte_ops[size];
1292 break;
1293 case GL_UNSIGNED_BYTE:
1294 opcode = ubyte_ops[size];
1295 break;
1296 case GL_SHORT:
1297 opcode = short_ops[size];
1298 break;
1299 case GL_UNSIGNED_SHORT:
1300 opcode = ushort_ops[size];
1301 break;
1302 case GL_INT:
1303 opcode = int_ops[size];
1304 break;
1305 case GL_UNSIGNED_INT:
1306 opcode = uint_ops[size];
1307 break;
1308 case GL_FLOAT:
1309 opcode = float_ops[size];
1310 break;
1311 case GL_DOUBLE:
1312 opcode = double_ops[size];
1313 break;
1314 default:
1315 __glXSetError(gc, GL_INVALID_ENUM);
1316 return;
1317 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001318
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001319 a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
1320 assert(a != NULL);
1321 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1322
1323 if (a->enabled) {
1324 arrays->array_info_cache_valid = GL_FALSE;
1325 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001326}
1327
1328
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001329void
1330__indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001331{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001332 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001333 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001334 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1335 struct array_state_vector *arrays = state->array_state;
1336 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001337
1338
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001339 if (stride < 0) {
1340 __glXSetError(gc, GL_INVALID_VALUE);
1341 return;
1342 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001343
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001344 switch (type) {
1345 case GL_UNSIGNED_BYTE:
1346 opcode = X_GLrop_Indexubv;
1347 break;
1348 case GL_SHORT:
1349 opcode = X_GLrop_Indexsv;
1350 break;
1351 case GL_INT:
1352 opcode = X_GLrop_Indexiv;
1353 break;
1354 case GL_FLOAT:
1355 opcode = X_GLrop_Indexfv;
1356 break;
1357 case GL_DOUBLE:
1358 opcode = X_GLrop_Indexdv;
1359 break;
1360 default:
1361 __glXSetError(gc, GL_INVALID_ENUM);
1362 return;
1363 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001364
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001365 a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
1366 assert(a != NULL);
1367 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1368
1369 if (a->enabled) {
1370 arrays->array_info_cache_valid = GL_FALSE;
1371 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001372}
1373
1374
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001375void
1376__indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001377{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001378 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001379 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1380 struct array_state_vector *arrays = state->array_state;
1381 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001382
1383
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001384 if (stride < 0) {
1385 __glXSetError(gc, GL_INVALID_VALUE);
1386 return;
1387 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001388
Ian Romanickfdb07632005-02-22 22:36:31 +00001389
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001390 a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
1391 assert(a != NULL);
1392 COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1393 4, X_GLrop_EdgeFlagv);
1394
1395 if (a->enabled) {
1396 arrays->array_info_cache_valid = GL_FALSE;
1397 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001398}
1399
1400
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001401void
1402__indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
1403 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001404{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001405 static const uint16_t short_ops[5] = {
1406 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001407 X_GLrop_TexCoord4sv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001408 };
1409 static const uint16_t int_ops[5] = {
1410 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001411 X_GLrop_TexCoord4iv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001412 };
1413 static const uint16_t float_ops[5] = {
Colin McDonald5ced1002016-06-22 19:11:55 -07001414 0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001415 X_GLrop_TexCoord4fv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001416 };
1417 static const uint16_t double_ops[5] = {
1418 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001419 X_GLrop_TexCoord4dv
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001420 };
Ian Romanickfdb07632005-02-22 22:36:31 +00001421
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001422 static const uint16_t mshort_ops[5] = {
1423 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001424 X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001425 };
1426 static const uint16_t mint_ops[5] = {
1427 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001428 X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001429 };
1430 static const uint16_t mfloat_ops[5] = {
Colin McDonald5ced1002016-06-22 19:11:55 -07001431 0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001432 X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001433 };
1434 static const uint16_t mdouble_ops[5] = {
1435 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
RALOVICH, Kristóf08962682009-08-12 12:41:22 +02001436 X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001437 };
Ian Romanickfdb07632005-02-22 22:36:31 +00001438
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001439 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001440 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001441 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1442 struct array_state_vector *arrays = state->array_state;
1443 struct array_state *a;
1444 unsigned header_size;
1445 unsigned index;
Ian Romanickfdb07632005-02-22 22:36:31 +00001446
1447
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001448 if (size < 1 || size > 4 || stride < 0) {
1449 __glXSetError(gc, GL_INVALID_VALUE);
1450 return;
1451 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001452
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001453 index = arrays->active_texture_unit;
1454 if (index == 0) {
1455 switch (type) {
1456 case GL_SHORT:
1457 opcode = short_ops[size];
1458 break;
1459 case GL_INT:
1460 opcode = int_ops[size];
1461 break;
1462 case GL_FLOAT:
1463 opcode = float_ops[size];
1464 break;
1465 case GL_DOUBLE:
1466 opcode = double_ops[size];
1467 break;
1468 default:
1469 __glXSetError(gc, GL_INVALID_ENUM);
1470 return;
1471 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001472
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001473 header_size = 4;
1474 }
1475 else {
1476 switch (type) {
1477 case GL_SHORT:
1478 opcode = mshort_ops[size];
1479 break;
1480 case GL_INT:
1481 opcode = mint_ops[size];
1482 break;
1483 case GL_FLOAT:
1484 opcode = mfloat_ops[size];
1485 break;
1486 case GL_DOUBLE:
1487 opcode = mdouble_ops[size];
1488 break;
1489 default:
1490 __glXSetError(gc, GL_INVALID_ENUM);
1491 return;
1492 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001493
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001494 header_size = 8;
1495 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001496
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001497 a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
1498 assert(a != NULL);
1499 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
1500 header_size, opcode);
1501
1502 if (a->enabled) {
1503 arrays->array_info_cache_valid = GL_FALSE;
1504 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001505}
1506
1507
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001508void
Paul Berry1a1db172012-11-06 08:57:59 -08001509__indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001510 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001511{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001512 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001513 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001514 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1515 struct array_state_vector *arrays = state->array_state;
1516 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001517
1518
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001519 if (size != 3 || stride < 0) {
1520 __glXSetError(gc, GL_INVALID_VALUE);
1521 return;
1522 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001523
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001524 switch (type) {
1525 case GL_BYTE:
1526 opcode = 4126;
1527 break;
1528 case GL_UNSIGNED_BYTE:
1529 opcode = 4131;
1530 break;
1531 case GL_SHORT:
1532 opcode = 4127;
1533 break;
1534 case GL_UNSIGNED_SHORT:
1535 opcode = 4132;
1536 break;
1537 case GL_INT:
1538 opcode = 4128;
1539 break;
1540 case GL_UNSIGNED_INT:
1541 opcode = 4133;
1542 break;
1543 case GL_FLOAT:
1544 opcode = 4129;
1545 break;
1546 case GL_DOUBLE:
1547 opcode = 4130;
1548 break;
1549 default:
1550 __glXSetError(gc, GL_INVALID_ENUM);
1551 return;
1552 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001553
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001554 a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
1555 if (a == NULL) {
1556 __glXSetError(gc, GL_INVALID_OPERATION);
1557 return;
1558 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001559
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001560 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1561
1562 if (a->enabled) {
1563 arrays->array_info_cache_valid = GL_FALSE;
1564 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001565}
1566
1567
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001568void
Paul Berry1a1db172012-11-06 08:57:59 -08001569__indirect_glFogCoordPointer(GLenum type, GLsizei stride,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001570 const GLvoid * pointer)
Ian Romanickfdb07632005-02-22 22:36:31 +00001571{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001572 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001573 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001574 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1575 struct array_state_vector *arrays = state->array_state;
1576 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001577
1578
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001579 if (stride < 0) {
1580 __glXSetError(gc, GL_INVALID_VALUE);
1581 return;
1582 }
Ian Romanickb81efaa2005-03-17 20:13:09 +00001583
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001584 switch (type) {
1585 case GL_FLOAT:
1586 opcode = 4124;
1587 break;
1588 case GL_DOUBLE:
1589 opcode = 4125;
1590 break;
1591 default:
1592 __glXSetError(gc, GL_INVALID_ENUM);
1593 return;
1594 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001595
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001596 a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
1597 if (a == NULL) {
1598 __glXSetError(gc, GL_INVALID_OPERATION);
1599 return;
1600 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001601
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001602 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
Ian Romanickfdb07632005-02-22 22:36:31 +00001603
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001604 if (a->enabled) {
1605 arrays->array_info_cache_valid = GL_FALSE;
1606 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001607}
1608
1609
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001610void
Paul Berry1a1db172012-11-06 08:57:59 -08001611__indirect_glVertexAttribPointer(GLuint index, GLint size,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001612 GLenum type, GLboolean normalized,
1613 GLsizei stride, const GLvoid * pointer)
Ian Romanick40af76b2005-02-25 22:46:30 +00001614{
Colin McDonald5ced1002016-06-22 19:11:55 -07001615 static const uint16_t short_ops[5] = {
1616 0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB,
1617 X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB
1618 };
1619 static const uint16_t float_ops[5] = {
1620 0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB,
1621 X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB
1622 };
1623 static const uint16_t double_ops[5] = {
1624 0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB,
1625 X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB
1626 };
Ian Romanick40af76b2005-02-25 22:46:30 +00001627
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001628 uint16_t opcode;
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001629 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001630 __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1631 struct array_state_vector *arrays = state->array_state;
1632 struct array_state *a;
1633 unsigned true_immediate_count;
1634 unsigned true_immediate_size;
Ian Romanick40af76b2005-02-25 22:46:30 +00001635
1636
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001637 if ((size < 1) || (size > 4) || (stride < 0)
1638 || (index > arrays->num_vertex_program_attribs)) {
1639 __glXSetError(gc, GL_INVALID_VALUE);
1640 return;
1641 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001642
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001643 if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
1644 switch (type) {
1645 case GL_BYTE:
1646 opcode = X_GLrop_VertexAttrib4NbvARB;
1647 break;
1648 case GL_UNSIGNED_BYTE:
1649 opcode = X_GLrop_VertexAttrib4NubvARB;
1650 break;
1651 case GL_SHORT:
1652 opcode = X_GLrop_VertexAttrib4NsvARB;
1653 break;
1654 case GL_UNSIGNED_SHORT:
1655 opcode = X_GLrop_VertexAttrib4NusvARB;
1656 break;
1657 case GL_INT:
1658 opcode = X_GLrop_VertexAttrib4NivARB;
1659 break;
1660 case GL_UNSIGNED_INT:
1661 opcode = X_GLrop_VertexAttrib4NuivARB;
1662 break;
1663 default:
1664 __glXSetError(gc, GL_INVALID_ENUM);
1665 return;
1666 }
Ian Romanick03dc4372005-02-28 19:37:10 +00001667
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001668 true_immediate_count = 4;
1669 }
1670 else {
1671 true_immediate_count = size;
Ian Romanick40af76b2005-02-25 22:46:30 +00001672
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001673 switch (type) {
1674 case GL_BYTE:
1675 opcode = X_GLrop_VertexAttrib4bvARB;
1676 true_immediate_count = 4;
1677 break;
1678 case GL_UNSIGNED_BYTE:
1679 opcode = X_GLrop_VertexAttrib4ubvARB;
1680 true_immediate_count = 4;
1681 break;
1682 case GL_SHORT:
1683 opcode = short_ops[size];
1684 break;
1685 case GL_UNSIGNED_SHORT:
1686 opcode = X_GLrop_VertexAttrib4usvARB;
1687 true_immediate_count = 4;
1688 break;
1689 case GL_INT:
1690 opcode = X_GLrop_VertexAttrib4ivARB;
1691 true_immediate_count = 4;
1692 break;
1693 case GL_UNSIGNED_INT:
1694 opcode = X_GLrop_VertexAttrib4uivARB;
1695 true_immediate_count = 4;
1696 break;
1697 case GL_FLOAT:
1698 opcode = float_ops[size];
1699 break;
1700 case GL_DOUBLE:
1701 opcode = double_ops[size];
1702 break;
1703 default:
1704 __glXSetError(gc, GL_INVALID_ENUM);
1705 return;
1706 }
1707 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001708
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001709 a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
1710 if (a == NULL) {
1711 __glXSetError(gc, GL_INVALID_OPERATION);
1712 return;
1713 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001714
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001715 COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
1716 opcode);
Ian Romanick40af76b2005-02-25 22:46:30 +00001717
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001718 true_immediate_size = __glXTypeSize(type) * true_immediate_count;
Colin McDonaldb36644b2016-06-22 19:19:30 -07001719 a->header[0] = __GLX_PAD(8 + true_immediate_size);
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001720
1721 if (a->enabled) {
1722 arrays->array_info_cache_valid = GL_FALSE;
1723 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001724}
1725
1726
1727/**
1728 * I don't have 100% confidence that this is correct. The different rules
1729 * about whether or not generic vertex attributes alias "classic" vertex
1730 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1731 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1732 * feeling is that the client-side doesn't have to worry about it. The
1733 * client just sends all the data to the server and lets the server deal
1734 * with it.
1735 */
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001736void
1737__indirect_glVertexAttribPointerNV(GLuint index, GLint size,
1738 GLenum type, GLsizei stride,
1739 const GLvoid * pointer)
Ian Romanick40af76b2005-02-25 22:46:30 +00001740{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001741 struct glx_context *gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001742 GLboolean normalized = GL_FALSE;
Ian Romanick40af76b2005-02-25 22:46:30 +00001743
1744
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001745 switch (type) {
1746 case GL_UNSIGNED_BYTE:
1747 if (size != 4) {
1748 __glXSetError(gc, GL_INVALID_VALUE);
1749 return;
1750 }
1751 normalized = GL_TRUE;
Ian Romanick40af76b2005-02-25 22:46:30 +00001752
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001753 case GL_SHORT:
1754 case GL_FLOAT:
1755 case GL_DOUBLE:
Paul Berry1a1db172012-11-06 08:57:59 -08001756 __indirect_glVertexAttribPointer(index, size, type,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001757 normalized, stride, pointer);
1758 return;
1759 default:
1760 __glXSetError(gc, GL_INVALID_ENUM);
1761 return;
1762 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001763}
1764
1765
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001766void
Paul Berry1a1db172012-11-06 08:57:59 -08001767__indirect_glClientActiveTexture(GLenum texture)
Ian Romanickfdb07632005-02-22 22:36:31 +00001768{
Kristian Høgsbergc356f582010-07-28 11:16:00 -04001769 struct glx_context *const gc = __glXGetCurrentContext();
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001770 __GLXattribute *const state =
1771 (__GLXattribute *) (gc->client_state_private);
1772 struct array_state_vector *const arrays = state->array_state;
1773 const GLint unit = (GLint) texture - GL_TEXTURE0;
Ian Romanickfdb07632005-02-22 22:36:31 +00001774
1775
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001776 if ((unit < 0) || (unit >= arrays->num_texture_units)) {
1777 __glXSetError(gc, GL_INVALID_ENUM);
1778 return;
1779 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001780
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001781 arrays->active_texture_unit = unit;
Ian Romanickfdb07632005-02-22 22:36:31 +00001782}
1783
1784
1785/**
Ian Romanick67108ad2008-07-15 11:06:04 -07001786 * Modify the enable state for the selected array
Ian Romanickfdb07632005-02-22 22:36:31 +00001787 */
1788GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001789__glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
Ian Romanick67108ad2008-07-15 11:06:04 -07001790 GLboolean enable)
Ian Romanickfdb07632005-02-22 22:36:31 +00001791{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001792 struct array_state_vector *arrays = state->array_state;
1793 struct array_state *a;
Ian Romanickfdb07632005-02-22 22:36:31 +00001794
Ian Romanickfdb07632005-02-22 22:36:31 +00001795
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001796 /* Texture coordinate arrays have an implict index set when the
1797 * application calls glClientActiveTexture.
1798 */
1799 if (key == GL_TEXTURE_COORD_ARRAY) {
1800 index = arrays->active_texture_unit;
1801 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001802
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001803 a = get_array_entry(arrays, key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001804
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001805 if ((a != NULL) && (a->enabled != enable)) {
1806 a->enabled = enable;
1807 arrays->array_info_cache_valid = GL_FALSE;
1808 }
1809
1810 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001811}
1812
1813
1814void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001815__glXArrayDisableAll(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001816{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001817 struct array_state_vector *arrays = state->array_state;
1818 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001819
1820
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001821 for (i = 0; i < arrays->num_arrays; i++) {
1822 arrays->arrays[i].enabled = GL_FALSE;
1823 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001824
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001825 arrays->array_info_cache_valid = GL_FALSE;
Ian Romanickfdb07632005-02-22 22:36:31 +00001826}
1827
1828
1829/**
1830 */
1831GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001832__glXGetArrayEnable(const __GLXattribute * const state,
1833 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001834{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001835 const struct array_state_vector *arrays = state->array_state;
1836 const struct array_state *a =
1837 get_array_entry((struct array_state_vector *) arrays,
1838 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001839
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001840 if (a != NULL) {
1841 *dest = (GLintptr) a->enabled;
1842 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001843
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001844 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001845}
1846
1847
1848/**
1849 */
1850GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001851__glXGetArrayType(const __GLXattribute * const state,
1852 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001853{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001854 const struct array_state_vector *arrays = state->array_state;
1855 const struct array_state *a =
1856 get_array_entry((struct array_state_vector *) arrays,
1857 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001858
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001859 if (a != NULL) {
1860 *dest = (GLintptr) a->data_type;
1861 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001862
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001863 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001864}
1865
1866
1867/**
1868 */
1869GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001870__glXGetArraySize(const __GLXattribute * const state,
1871 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001872{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001873 const struct array_state_vector *arrays = state->array_state;
1874 const struct array_state *a =
1875 get_array_entry((struct array_state_vector *) arrays,
1876 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001877
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001878 if (a != NULL) {
1879 *dest = (GLintptr) a->count;
1880 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001881
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001882 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001883}
1884
1885
1886/**
1887 */
1888GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001889__glXGetArrayStride(const __GLXattribute * const state,
1890 GLenum key, unsigned index, GLintptr * dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001891{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001892 const struct array_state_vector *arrays = state->array_state;
1893 const struct array_state *a =
1894 get_array_entry((struct array_state_vector *) arrays,
1895 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001896
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001897 if (a != NULL) {
1898 *dest = (GLintptr) a->user_stride;
1899 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001900
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001901 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001902}
1903
1904
1905/**
1906 */
1907GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001908__glXGetArrayPointer(const __GLXattribute * const state,
1909 GLenum key, unsigned index, void **dest)
Ian Romanickfdb07632005-02-22 22:36:31 +00001910{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001911 const struct array_state_vector *arrays = state->array_state;
1912 const struct array_state *a =
1913 get_array_entry((struct array_state_vector *) arrays,
1914 key, index);
Ian Romanickfdb07632005-02-22 22:36:31 +00001915
1916
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001917 if (a != NULL) {
1918 *dest = (void *) (a->data);
1919 }
Ian Romanick40af76b2005-02-25 22:46:30 +00001920
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001921 return (a != NULL);
Ian Romanick40af76b2005-02-25 22:46:30 +00001922}
1923
1924
1925/**
1926 */
1927GLboolean
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001928__glXGetArrayNormalized(const __GLXattribute * const state,
1929 GLenum key, unsigned index, GLintptr * dest)
Ian Romanick40af76b2005-02-25 22:46:30 +00001930{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001931 const struct array_state_vector *arrays = state->array_state;
1932 const struct array_state *a =
1933 get_array_entry((struct array_state_vector *) arrays,
1934 key, index);
Ian Romanick40af76b2005-02-25 22:46:30 +00001935
1936
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001937 if (a != NULL) {
1938 *dest = (GLintptr) a->normalized;
1939 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001940
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001941 return (a != NULL);
Ian Romanickfdb07632005-02-22 22:36:31 +00001942}
1943
1944
1945/**
1946 */
1947GLuint
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001948__glXGetActiveTextureUnit(const __GLXattribute * const state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001949{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001950 return state->array_state->active_texture_unit;
Ian Romanickfdb07632005-02-22 22:36:31 +00001951}
1952
1953
1954void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001955__glXPushArrayState(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001956{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001957 struct array_state_vector *arrays = state->array_state;
1958 struct array_stack_state *stack =
1959 &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1960 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001961
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001962 /* XXX are we pushing _all_ the necessary fields? */
1963 for (i = 0; i < arrays->num_arrays; i++) {
1964 stack[i].data = arrays->arrays[i].data;
1965 stack[i].data_type = arrays->arrays[i].data_type;
1966 stack[i].user_stride = arrays->arrays[i].user_stride;
1967 stack[i].count = arrays->arrays[i].count;
1968 stack[i].key = arrays->arrays[i].key;
1969 stack[i].index = arrays->arrays[i].index;
1970 stack[i].enabled = arrays->arrays[i].enabled;
1971 }
Ian Romanickfdb07632005-02-22 22:36:31 +00001972
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001973 arrays->active_texture_unit_stack[arrays->stack_index] =
Ian Romanickfdb07632005-02-22 22:36:31 +00001974 arrays->active_texture_unit;
1975
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001976 arrays->stack_index++;
Ian Romanickfdb07632005-02-22 22:36:31 +00001977}
1978
1979
1980void
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001981__glXPopArrayState(__GLXattribute * state)
Ian Romanickfdb07632005-02-22 22:36:31 +00001982{
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001983 struct array_state_vector *arrays = state->array_state;
1984 struct array_stack_state *stack;
1985 unsigned i;
Ian Romanickfdb07632005-02-22 22:36:31 +00001986
1987
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001988 arrays->stack_index--;
1989 stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
Ian Romanickfdb07632005-02-22 22:36:31 +00001990
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02001991 for (i = 0; i < arrays->num_arrays; i++) {
1992 switch (stack[i].key) {
1993 case GL_NORMAL_ARRAY:
1994 __indirect_glNormalPointer(stack[i].data_type,
1995 stack[i].user_stride, stack[i].data);
1996 break;
1997 case GL_COLOR_ARRAY:
1998 __indirect_glColorPointer(stack[i].count,
1999 stack[i].data_type,
2000 stack[i].user_stride, stack[i].data);
2001 break;
2002 case GL_INDEX_ARRAY:
2003 __indirect_glIndexPointer(stack[i].data_type,
2004 stack[i].user_stride, stack[i].data);
2005 break;
2006 case GL_EDGE_FLAG_ARRAY:
2007 __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
2008 break;
2009 case GL_TEXTURE_COORD_ARRAY:
2010 arrays->active_texture_unit = stack[i].index;
2011 __indirect_glTexCoordPointer(stack[i].count,
2012 stack[i].data_type,
2013 stack[i].user_stride, stack[i].data);
2014 break;
2015 case GL_SECONDARY_COLOR_ARRAY:
Paul Berry1a1db172012-11-06 08:57:59 -08002016 __indirect_glSecondaryColorPointer(stack[i].count,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02002017 stack[i].data_type,
2018 stack[i].user_stride,
2019 stack[i].data);
2020 break;
2021 case GL_FOG_COORDINATE_ARRAY:
Paul Berry1a1db172012-11-06 08:57:59 -08002022 __indirect_glFogCoordPointer(stack[i].data_type,
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02002023 stack[i].user_stride, stack[i].data);
2024 break;
Ian Romanickfdb07632005-02-22 22:36:31 +00002025
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02002026 }
Ian Romanickfdb07632005-02-22 22:36:31 +00002027
RALOVICH, Kristófc868ab32008-10-13 14:20:15 +02002028 __glXSetArrayEnable(state, stack[i].key, stack[i].index,
2029 stack[i].enabled);
2030 }
2031
2032 arrays->active_texture_unit =
2033 arrays->active_texture_unit_stack[arrays->stack_index];
Ian Romanickfdb07632005-02-22 22:36:31 +00002034}