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