Added __glExtensionBiIsEnabled and __GLXcontext::gl_extension_bits. This
[mesa.git] / src / glx / x11 / 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 "glxclient.h"
29 #include "packrender.h"
30 #include "indirect.h"
31 #include <string.h>
32
33 #include <GL/glxproto.h>
34 #include "glxextensions.h"
35 #include "indirect_vertex_array.h"
36
37 /**
38 * \file indirect_vertex_array.c
39 * Implement GLX protocol for vertex arrays and vertex buffer objects.
40 *
41 * The most important function in this fill is \c fill_array_info_cache.
42 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
43 * in the DrawArrays protocol. Certain operations, such as enabling or
44 * disabling an array, can invalidate this cache. \c fill_array_info_cache
45 * fills-in this data. Additionally, it examines the enabled state and
46 * other factors to determine what "version" of DrawArrays protocoal can be
47 * used.
48 *
49 * Current, only two versions of DrawArrays protocol are implemented. The
50 * first version is the "none" protocol. This is the fallback when the
51 * server does not support GL 1.1 / EXT_vertex_arrays. It is implemented
52 * by sending batches of immediate mode commands that are equivalent to the
53 * DrawArrays protocol.
54 *
55 * The other protocol that is currently implemented is the "old" protocol.
56 * This is the GL 1.1 DrawArrays protocol. The only difference between GL
57 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
58 * This protocol is called "old" because the ARB is in the process of
59 * defining a new protocol, which will probably be called wither "new" or
60 * "vbo", to support multiple texture coordinate arrays, generic attributes,
61 * and vertex buffer objects.
62 *
63 * \author Ian Romanick <idr@us.ibm.com>
64 */
65
66
67 /**
68 * State descriptor for a single array of vertex data.
69 */
70 struct array_state {
71 /**
72 * Pointer to the application supplied data.
73 */
74 const void * data;
75
76 /**
77 * Enum representing the type of the application supplied data.
78 */
79 GLenum data_type;
80
81 /**
82 * Stride value supplied by the application. This value is not used
83 * internally. It is only kept so that it can be queried by the
84 * application using glGet*v.
85 */
86 GLsizei user_stride;
87
88 /**
89 * Calculated size, in bytes, of a single element in the array. This
90 * is calculated based on \c count and the size of the data type
91 * represented by \c data_type.
92 */
93 GLsizei element_size;
94
95 /**
96 * Actual byte-stride from one element to the next. This value will
97 * be equal to either \c user_stride or \c element_stride.
98 */
99 GLsizei true_stride;
100
101 /**
102 * Number of data values in each element.
103 */
104 GLint count;
105
106 /**
107 * Pre-calculated GLX protocol command header.
108 */
109 uint32_t header[2];
110
111 /**
112 * Size of the header data. For simple data, like glColorPointerfv,
113 * this is 4. For complex data that requires either a count (e.g.,
114 * glWeightfvARB), an index (e.g., glVertexAttrib1fvARB), or a
115 * selector enum (e.g., glMultiTexCoord2fv) this is 8.
116 */
117 unsigned header_size;
118
119 /**
120 * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
121 * to \c GL_FALSE.
122 */
123 GLboolean enabled;
124
125 /**
126 * For multi-arrayed data (e.g., texture coordinates, generic vertex
127 * program attributes, etc.), this specifies which array this is.
128 */
129 unsigned index;
130
131 /**
132 * Per-array-type key. For most arrays, this will be the GL enum for
133 * that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY
134 * for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data,
135 * etc.).
136 */
137 GLenum key;
138
139 /**
140 * If this array can be used with the "classic" \c glDrawArrays protocol,
141 * this is set to \c GL_TRUE. Otherwise, it is set to \c GL_FALSE.
142 */
143 GLboolean old_DrawArrays_possible;
144 };
145
146
147 /**
148 * Array state that is pushed / poped by \c glPushClientAttrib and
149 * \c glPopClientAttrib.
150 */
151 struct array_stack_state {
152 /**
153 * Pointer to the application supplied data.
154 */
155 const void * data;
156
157 /**
158 * Enum representing the type of the application supplied data.
159 */
160 GLenum data_type;
161
162 /**
163 * Stride value supplied by the application. This value is not used
164 * internally. It is only kept so that it can be queried by the
165 * application using glGet*v.
166 */
167 GLsizei user_stride;
168
169 /**
170 * Number of data values in each element.
171 */
172 GLint count;
173
174 /**
175 * Per-array-type key. For most arrays, this will be the GL enum for
176 * that array (e.g., GL_VERTEX_ARRAY for vertex data, GL_NORMAL_ARRAY
177 * for normal data, GL_TEXTURE_COORD_ARRAY for texture coordinate data,
178 * etc.).
179 */
180 GLenum key;
181
182 /**
183 * For multi-arrayed data (e.g., texture coordinates, generic vertex
184 * program attributes, etc.), this specifies which array this is.
185 */
186 unsigned index;
187
188 /**
189 * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
190 * to \c GL_FALSE.
191 */
192 GLboolean enabled;
193 };
194
195
196 /**
197 * Collection of all the vertex array state.
198 */
199 struct array_state_vector {
200 /**
201 * Number of arrays tracked by \c ::arrays.
202 */
203 size_t num_arrays;
204
205 /**
206 * Array of vertex array state. This array contains all of the valid
207 * vertex arrays. If a vertex array isn't in this array, then it isn't
208 * valid. For example, if an implementation does not support
209 * EXT_fog_coord, there won't be a GL_FOG_COORD_ARRAY entry in this
210 * array.
211 */
212 struct array_state * arrays;
213
214 /**
215 * Number of currently enabled arrays. The value of this field is
216 * only valid if \c array_info_cache_valid is true.
217 */
218 size_t enabled_array_count;
219
220 /**
221 * \name ARRAY_INFO cache.
222 *
223 * These fields track the state of the ARRAY_INFO cache. The
224 * \c array_info_cache_size is the size of the actual data stored in
225 * \c array_info_cache. \c array_info_cache_buffer_size is the size of
226 * the buffer. This will always be greater than or equal to
227 * \c array_info_cache_size.
228 *
229 * \c large_header doesn't completely belong in this group. This is a
230 * pointer to a buffer to hold the header information for DrawArrays in
231 * a RenderLarge command. This buffer is immediately before
232 * \c array_info_cache. The idea is that the header data will be written
233 * to \c large_header and a single call to \c __glXSendLargeChunk can be
234 * made to send the header and the ARRAY_INFO data.
235 *
236 * \note
237 * \c array_info_cache_size and \c array_info_cache_buffer_size do
238 * NOT include the size of \c large_header.
239 */
240 /*@{*/
241 size_t array_info_cache_size;
242 size_t array_info_cache_buffer_size;
243 void * array_info_cache;
244 GLubyte * large_header;
245 /*@}*/
246
247
248 /**
249 * Is the cache of ARRAY_INFO data valid? The cache can become invalid
250 * when one of several state changes occur. Among these chages are
251 * modifying the array settings for an enabled array and enabling /
252 * disabling an array.
253 */
254 GLboolean array_info_cache_valid;
255
256 /**
257 * Is it possible to use the GL 1.1 / EXT_vertex_arrays protocol? Use
258 * of this protocol is disabled with really old servers (i.e., servers
259 * that don't support GL 1.1 or EXT_vertex_arrays) or when an environment
260 * variable is set.
261 *
262 * \todo
263 * GL 1.1 and EXT_vertex_arrays use identical protocol, but have different
264 * opcodes for \c glDrawArrays. For servers that advertise one or the
265 * other, there should be a way to select which opcode to use.
266 */
267 GLboolean old_DrawArrays_possible;
268
269 /**
270 * Is it possible to use the new GL X.X / ARB_vertex_buffer_object
271 * protocol?
272 *
273 * \todo
274 * This protocol has not yet been defined by the ARB, but is currently a
275 * work in progress. This field is a place-holder.
276 */
277 GLboolean new_DrawArrays_possible;
278
279 /**
280 * Active texture unit set by \c glClientActiveTexture.
281 *
282 * \sa __glXGetActiveTextureUnit
283 */
284 unsigned active_texture_unit;
285
286 /**
287 * Number of supported texture units. Even if ARB_multitexture /
288 * GL 1.3 are not supported, this will be at least 1. When multitexture
289 * is supported, this will be the value queried by calling
290 * \c glGetIntegerv with \c GL_MAX_TEXTURE_UNITS.
291 *
292 * \todo
293 * Investigate if this should be the value of \c GL_MAX_TEXTURE_COORDS
294 * instead (if GL 2.0 / ARB_fragment_shader / ARB_fragment_program /
295 * NV_fragment_program are supported).
296 */
297 unsigned num_texture_units;
298
299 /**
300 * \n Methods for implementing various GL functions.
301 *
302 * These method pointers are only valid \c array_info_cache_valid is set.
303 * When each function starts, it much check \c array_info_cache_valid.
304 * If it is not set, it must call \c fill_array_info_cache and call
305 * the new method.
306 *
307 * \sa fill_array_info_cache
308 *
309 * \todo
310 * Write code to plug these functions directly into the dispatch table.
311 */
312 /*@{*/
313 void (*DrawArrays)( GLenum, GLint, GLsizei );
314 void (*DrawElements)( GLenum mode, GLsizei count, GLenum type,
315 const GLvoid *indices );
316 /*@}*/
317
318 struct array_stack_state * stack;
319 unsigned active_texture_unit_stack[ __GL_CLIENT_ATTRIB_STACK_DEPTH ];
320 unsigned stack_index;
321 };
322
323
324 static void emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count );
325 static void emit_DrawArrays_old ( GLenum mode, GLint first, GLsizei count );
326
327 static void emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
328 const GLvoid *indices );
329 static void emit_DrawElements_old ( GLenum mode, GLsizei count, GLenum type,
330 const GLvoid *indices );
331
332
333 static GLubyte * emit_element_none( GLubyte * dst,
334 const struct array_state_vector * arrays, unsigned index );
335 static GLubyte * emit_element_old( GLubyte * dst,
336 const struct array_state_vector * arrays, unsigned index );
337 static struct array_state * get_array_entry(
338 const struct array_state_vector * arrays, GLenum key, unsigned index );
339 static void fill_array_info_cache( struct array_state_vector * arrays );
340 static GLboolean glx_validate_array_args(__GLXcontext *gc, GLenum mode,
341 GLsizei count);
342
343
344 /**
345 * Table of sizes, in bytes, of a GL types. All of the type enums are be in
346 * the range 0x1400 - 0x140F. That includes types added by extensions (i.e.,
347 * \c GL_HALF_FLOAT_NV). This elements of this table correspond to the
348 * type enums masked with 0x0f.
349 *
350 * \notes
351 * \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES,
352 * \c GL_3_BYTES, or \c GL_4_BYTES.
353 */
354 const GLuint __glXTypeSize_table[16] = {
355 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
356 };
357
358
359
360 /**
361 * Initialize vertex array state of a GLX context.
362 *
363 * \param gc GLX context whose vertex array state is to be initialized.
364 *
365 * \warning
366 * This function may only be called after __GLXcontext::gl_extension_bits,
367 * __GLXcontext::server_minor, and __GLXcontext::server_major have been
368 * initialized. These values are used to determine what vertex arrays are
369 * supported.
370 *
371 * \bug
372 * Return values from malloc are not properly tested.
373 */
374 void
375 __glXInitVertexArrayState( __GLXcontext * gc )
376 {
377 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
378 struct array_state_vector * arrays;
379
380 unsigned array_count;
381 unsigned texture_units = 1;
382 unsigned i;
383
384 GLboolean got_fog = GL_FALSE;
385 GLboolean got_secondary_color = GL_FALSE;
386
387
388 arrays = malloc( sizeof( struct array_state_vector ) );
389 state->array_state = arrays;
390 arrays->enabled_array_count = 0;
391 arrays->array_info_cache = NULL;
392 arrays->array_info_cache_size = 0;
393 arrays->array_info_cache_buffer_size = 0;
394 arrays->array_info_cache_valid= GL_FALSE;
395
396 arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
397 arrays->new_DrawArrays_possible = GL_FALSE;
398 arrays->DrawArrays = NULL;
399
400 arrays->active_texture_unit = 0;
401
402
403 /* Determine how many arrays are actually needed. Only arrays that
404 * are supported by the server are create. For example, if the server
405 * supports only 2 texture units, then only 2 texture coordinate arrays
406 * are created.
407 *
408 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
409 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
410 * GL_EDGE_FLAG_ARRAY are supported.
411 */
412
413 array_count = 5;
414
415 if ( __glExtensionBitIsEnabled( gc, GL_EXT_fog_coord_bit )
416 || (gc->server_major > 1) || (gc->server_minor >= 4) ) {
417 got_fog = GL_TRUE;
418 array_count++;
419 }
420
421 if ( __glExtensionBitIsEnabled( gc, GL_EXT_secondary_color_bit )
422 || (gc->server_major > 1) || (gc->server_minor >= 4) ) {
423 got_secondary_color = GL_TRUE;
424 array_count++;
425 }
426
427 if ( __glExtensionBitIsEnabled( gc, GL_ARB_multitexture_bit )
428 || (gc->server_major > 1) || (gc->server_minor >= 3) ) {
429 glGetIntegerv( GL_MAX_TEXTURE_UNITS, & texture_units );
430 }
431 else {
432 texture_units = 1;
433 }
434
435 arrays->num_texture_units = texture_units;
436 array_count += texture_units;
437 arrays->num_arrays = array_count;
438 arrays->arrays = malloc( sizeof( struct array_state ) * array_count );
439
440 (void) memset( arrays->arrays, 0,
441 sizeof( struct array_state ) * array_count );
442
443
444 arrays->arrays[0].data_type = GL_FLOAT;
445 arrays->arrays[0].count = 3;
446 arrays->arrays[0].key = GL_NORMAL_ARRAY;
447 arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
448
449 arrays->arrays[1].data_type = GL_FLOAT;
450 arrays->arrays[1].count = 4;
451 arrays->arrays[1].key = GL_COLOR_ARRAY;
452 arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
453
454 arrays->arrays[2].data_type = GL_FLOAT;
455 arrays->arrays[2].count = 1;
456 arrays->arrays[2].key = GL_INDEX_ARRAY;
457 arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
458
459 arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
460 arrays->arrays[3].count = 1;
461 arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
462 arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
463
464 for ( i = 0 ; i < texture_units ; i++ ) {
465 arrays->arrays[4 + i].data_type = GL_FLOAT;
466 arrays->arrays[4 + i].count = 4;
467 arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
468
469 arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
470 arrays->arrays[4 + i].index = i;
471
472 arrays->arrays[4 + i].header[1] = i + GL_TEXTURE0;
473 }
474
475 i = 4 + texture_units;
476
477 if ( got_fog ) {
478 arrays->arrays[i].data_type = GL_FLOAT;
479 arrays->arrays[i].count = 1;
480 arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
481 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
482 i++;
483 }
484
485 if ( got_secondary_color ) {
486 arrays->arrays[i].data_type = GL_FLOAT;
487 arrays->arrays[i].count = 3;
488 arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
489 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
490 i++;
491 }
492
493
494 /* Vertex array *must* be last becuase of the way that
495 * emit_DrawArrays_none works.
496 */
497
498 arrays->arrays[i].data_type = GL_FLOAT;
499 arrays->arrays[i].count = 4;
500 arrays->arrays[i].key = GL_VERTEX_ARRAY;
501 arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
502
503
504 arrays->stack_index = 0;
505 arrays->stack = malloc( sizeof( struct array_stack_state )
506 * arrays->num_arrays );
507 }
508
509
510 /**
511 * Calculate the size of a single vertex for the "none" protocol. This is
512 * essentially the size of all the immediate-mode commands required to
513 * implement the enabled vertex arrays.
514 */
515 static size_t
516 calculate_single_vertex_size_none( const struct array_state_vector * arrays )
517 {
518 size_t single_vertex_size = 0;
519 unsigned i;
520
521
522 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
523 if ( arrays->arrays[i].enabled ) {
524 single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size)
525 + arrays->arrays[i].header_size;
526 }
527 }
528
529 return single_vertex_size;
530 }
531
532
533 /**
534 * Emit a single element using non-DrawArrays protocol.
535 */
536 GLubyte *
537 emit_element_none( GLubyte * dst,
538 const struct array_state_vector * arrays,
539 unsigned index )
540 {
541 unsigned i;
542
543
544 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
545 if ( arrays->arrays[i].enabled ) {
546 const size_t offset = index * arrays->arrays[i].true_stride;
547
548 (void) memcpy( dst, arrays->arrays[i].header,
549 arrays->arrays[i].header_size );
550
551 dst += arrays->arrays[i].header_size;
552
553 (void) memcpy( dst, ((GLubyte *) arrays->arrays[i].data) + offset,
554 arrays->arrays[i].element_size );
555
556 dst += __GLX_PAD( arrays->arrays[i].element_size );
557 }
558 }
559
560 return dst;
561 }
562
563
564 /**
565 * Emit a single element using "old" DrawArrays protocol from
566 * EXT_vertex_arrays / OpenGL 1.1.
567 */
568 GLubyte *
569 emit_element_old( GLubyte * dst,
570 const struct array_state_vector * arrays,
571 unsigned index )
572 {
573 unsigned i;
574
575
576 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
577 if ( arrays->arrays[i].enabled ) {
578 const size_t offset = index * arrays->arrays[i].true_stride;
579
580 (void) memcpy( dst, ((GLubyte *) arrays->arrays[i].data) + offset,
581 arrays->arrays[i].element_size );
582
583 dst += __GLX_PAD( arrays->arrays[i].element_size );
584 }
585 }
586
587 return dst;
588 }
589
590
591 struct array_state *
592 get_array_entry( const struct array_state_vector * arrays,
593 GLenum key, unsigned index )
594 {
595 unsigned i;
596
597 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
598 if ( (arrays->arrays[i].key == key)
599 && (arrays->arrays[i].index == index) ) {
600 return & arrays->arrays[i];
601 }
602 }
603
604 return NULL;
605 }
606
607
608 static GLboolean
609 allocate_array_info_cache( struct array_state_vector * arrays,
610 size_t required_size )
611 {
612 if ( arrays->array_info_cache_buffer_size < required_size ) {
613 GLubyte * temp = realloc( arrays->array_info_cache, required_size + 20 );
614
615 if ( temp == NULL ) {
616 return GL_FALSE;
617 }
618
619 arrays->large_header = temp;
620 arrays->array_info_cache = temp + 20;
621 arrays->array_info_cache_buffer_size = required_size;
622 }
623
624 arrays->array_info_cache_size = required_size;
625 return GL_TRUE;
626 }
627
628
629 /**
630 */
631 void
632 fill_array_info_cache( struct array_state_vector * arrays )
633 {
634 GLboolean old_DrawArrays_possible;
635 unsigned i;
636
637
638 /* Determine how many arrays are enabled.
639 */
640
641 arrays->enabled_array_count = 0;
642 old_DrawArrays_possible = arrays->old_DrawArrays_possible;
643 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
644 if ( arrays->arrays[i].enabled ) {
645 arrays->enabled_array_count++;
646 old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
647 }
648 }
649
650
651 if ( arrays->new_DrawArrays_possible ) {
652 assert( ! arrays->new_DrawArrays_possible );
653 }
654 else if ( old_DrawArrays_possible ) {
655 const size_t required_size = arrays->enabled_array_count * 12;
656 uint32_t * info;
657
658
659 if ( ! allocate_array_info_cache( arrays, required_size ) ) {
660 return;
661 }
662
663
664 info = (uint32_t *) arrays->array_info_cache;
665 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
666 if ( arrays->arrays[i].enabled ) {
667 *(info++) = arrays->arrays[i].data_type;
668 *(info++) = arrays->arrays[i].count;
669 *(info++) = arrays->arrays[i].key;
670 }
671 }
672
673 arrays->array_info_cache_valid = GL_TRUE;
674 arrays->DrawArrays = emit_DrawArrays_old;
675 arrays->DrawElements = emit_DrawElements_old;
676 }
677 else {
678 arrays->DrawArrays = emit_DrawArrays_none;
679 arrays->DrawElements = emit_DrawElements_none;
680 }
681 }
682
683
684 /**
685 * Emit a \c glDrawArrays command using the "none" protocol. That is,
686 * emit immediate-mode commands that are equivalent to the requiested
687 * \c glDrawArrays command. This is used with servers that don't support
688 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
689 * vertex state is enabled that is not compatible with that protocol.
690 */
691 void
692 emit_DrawArrays_none( GLenum mode, GLint first, GLsizei count )
693 {
694 __GLXcontext *gc = __glXGetCurrentContext();
695 const __GLXattribute * state =
696 (const __GLXattribute *)(gc->client_state_private);
697 struct array_state_vector * arrays = state->array_state;
698
699 size_t single_vertex_size;
700 GLubyte * pc;
701 unsigned i;
702 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
703 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
704
705
706 single_vertex_size = calculate_single_vertex_size_none( arrays );
707
708 pc = gc->pc;
709
710 (void) memcpy( pc, begin_cmd, 4 );
711 *(int *)(pc + 4) = mode;
712
713 pc += 8;
714
715 for ( i = 0 ; i < count ; i++ ) {
716 if ( (pc + single_vertex_size) >= gc->bufEnd ) {
717 pc = __glXFlushRenderBuffer(gc, gc->pc);
718 }
719
720 pc = emit_element_none( pc, arrays, first + i );
721 }
722
723 if ( (pc + 4) >= gc->bufEnd ) {
724 pc = __glXFlushRenderBuffer(gc, gc->pc);
725 }
726
727 (void) memcpy( pc, end_cmd, 4 );
728 pc += 4;
729
730 gc->pc = pc;
731 if ( gc->pc > gc->limit ) {
732 (void) __glXFlushRenderBuffer(gc, gc->pc);
733 }
734 }
735
736
737 /**
738 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
739 * protocol.
740 *
741 * \param gc GLX context.
742 * \param arrays Array state.
743 * \param elements_per_request Location to store the number of elements that
744 * can fit in a single Render / RenderLarge
745 * command.
746 * \param total_request Total number of requests for a RenderLarge
747 * command. If a Render command is used, this
748 * will be zero.
749 * \param mode Drawing mode.
750 * \param count Number of vertices.
751 *
752 * \returns
753 * A pointer to the buffer for array data.
754 */
755 static GLubyte *
756 emit_DrawArrays_header_old( __GLXcontext * gc,
757 struct array_state_vector * arrays,
758 size_t * elements_per_request,
759 size_t * total_requests,
760 GLenum mode, GLsizei count )
761 {
762 size_t command_size;
763 size_t single_vertex_size;
764 const unsigned header_size = 16;
765 unsigned i;
766 GLubyte * pc;
767
768
769 /* Determine the size of the whole command. This includes the header,
770 * the ARRAY_INFO data and the array data. Once this size is calculated,
771 * it will be known whether a Render or RenderLarge command is needed.
772 */
773
774 single_vertex_size = 0;
775 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
776 if ( arrays->arrays[i].enabled ) {
777 single_vertex_size += __GLX_PAD( arrays->arrays[i].element_size );
778 }
779 }
780
781 command_size = arrays->array_info_cache_size + header_size
782 + (single_vertex_size * count);
783
784
785 /* Write the header for either a Render command or a RenderLarge
786 * command. After the header is written, write the ARRAY_INFO data.
787 */
788
789 if ( command_size > gc->maxSmallRenderCommandSize ) {
790 /* maxSize is the maximum amount of data can be stuffed into a single
791 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
792 * packet size minus sz_xGLXRenderReq.
793 */
794 const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
795 - sz_xGLXRenderLargeReq;
796 unsigned vertex_requests;
797
798
799 /* Calculate the number of data packets that will be required to send
800 * the whole command. To do this, the number of verticies that
801 * will fit in a single buffer must be calculated.
802 *
803 * The important value here is elements_per_request. This is the
804 * number of complete array elements that will fit in a single
805 * buffer. There may be some wasted space at the end of the buffer,
806 * but splitting elements across buffer boundries would be painful.
807 */
808
809 elements_per_request[0] = maxSize / single_vertex_size;
810
811 vertex_requests = (count + elements_per_request[0] - 1)
812 / elements_per_request[0];
813
814 *total_requests = vertex_requests + 1;
815
816
817 __glXFlushRenderBuffer(gc, gc->pc);
818
819 command_size += 4;
820
821 pc = arrays->large_header;
822 *(uint32_t *)(pc + 0) = command_size;
823 *(uint32_t *)(pc + 4) = X_GLrop_DrawArrays;
824 *(uint32_t *)(pc + 8) = count;
825 *(uint32_t *)(pc + 12) = arrays->enabled_array_count;
826 *(uint32_t *)(pc + 16) = mode;
827
828 __glXSendLargeChunk( gc, 1, *total_requests, pc,
829 header_size + 4 + arrays->array_info_cache_size );
830
831 pc = gc->pc;
832 }
833 else {
834 if ( (gc->pc + command_size) >= gc->bufEnd ) {
835 (void) __glXFlushRenderBuffer(gc, gc->pc);
836 }
837
838 pc = gc->pc;
839 *(uint16_t *)(pc + 0) = command_size;
840 *(uint16_t *)(pc + 2) = X_GLrop_DrawArrays;
841 *(uint32_t *)(pc + 4) = count;
842 *(uint32_t *)(pc + 8) = arrays->enabled_array_count;
843 *(uint32_t *)(pc + 12) = mode;
844
845 pc += header_size;
846
847 (void) memcpy( pc, arrays->array_info_cache,
848 arrays->array_info_cache_size );
849 pc += arrays->array_info_cache_size;
850
851 *elements_per_request = count;
852 *total_requests = 0;
853 }
854
855
856 return pc;
857 }
858
859
860 /**
861 */
862 void
863 emit_DrawArrays_old( GLenum mode, GLint first, GLsizei count )
864 {
865 __GLXcontext *gc = __glXGetCurrentContext();
866 const __GLXattribute * state =
867 (const __GLXattribute *)(gc->client_state_private);
868 struct array_state_vector * arrays = state->array_state;
869
870 GLubyte * pc;
871 size_t elements_per_request;
872 unsigned total_requests = 0;
873 unsigned i;
874 size_t total_sent = 0;
875
876
877 pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
878 & total_requests, mode, count);
879
880
881 /* Write the arrays.
882 */
883
884 if ( total_requests == 0 ) {
885 assert( elements_per_request >= count );
886
887 for ( i = 0 ; i < count ; i++ ) {
888 pc = emit_element_old( pc, arrays, i + first );
889 }
890
891 assert( pc <= gc->bufEnd );
892
893 gc->pc = pc;
894 if ( gc->pc > gc->limit ) {
895 (void) __glXFlushRenderBuffer(gc, gc->pc);
896 }
897 }
898 else {
899 unsigned req;
900
901
902 for ( req = 2 ; req <= total_requests ; req++ ) {
903 if ( count < elements_per_request ) {
904 elements_per_request = count;
905 }
906
907 pc = gc->pc;
908 for ( i = 0 ; i < elements_per_request ; i++ ) {
909 pc = emit_element_old( pc, arrays, i + first );
910 }
911
912 first += elements_per_request;
913
914 total_sent += (size_t) (pc - gc->pc);
915 __glXSendLargeChunk( gc, req, total_requests, gc->pc,
916 pc - gc->pc );
917
918 count -= elements_per_request;
919 }
920 }
921 }
922
923
924 void
925 emit_DrawElements_none( GLenum mode, GLsizei count, GLenum type,
926 const GLvoid *indices )
927 {
928 __GLXcontext *gc = __glXGetCurrentContext();
929 const __GLXattribute * state =
930 (const __GLXattribute *)(gc->client_state_private);
931 struct array_state_vector * arrays = state->array_state;
932 static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
933 static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
934
935 GLubyte * pc;
936 size_t single_vertex_size;
937 unsigned i;
938
939
940 single_vertex_size = calculate_single_vertex_size_none( arrays );
941
942
943 if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {
944 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
945 }
946
947 pc = gc->pc;
948
949 (void) memcpy( pc, begin_cmd, 4 );
950 *(int *)(pc + 4) = mode;
951
952 pc += 8;
953
954 for ( i = 0 ; i < count ; i++ ) {
955 unsigned index;
956
957 if ( (pc + single_vertex_size) >= gc->bufEnd ) {
958 pc = __glXFlushRenderBuffer(gc, gc->pc);
959 }
960
961 switch( type ) {
962 case GL_UNSIGNED_INT:
963 index = (unsigned) (((GLuint *) indices)[i]);
964 break;
965 case GL_UNSIGNED_SHORT:
966 index = (unsigned) (((GLushort *) indices)[i]);
967 break;
968 case GL_UNSIGNED_BYTE:
969 index = (unsigned) (((GLubyte *) indices)[i]);
970 break;
971 }
972 pc = emit_element_none( pc, arrays, index );
973 }
974
975 if ( (pc + 4) >= gc->bufEnd ) {
976 pc = __glXFlushRenderBuffer(gc, gc->pc);
977 }
978
979 (void) memcpy( pc, end_cmd, 4 );
980 pc += 4;
981
982 gc->pc = pc;
983 if ( gc->pc > gc->limit ) {
984 (void) __glXFlushRenderBuffer(gc, gc->pc);
985 }
986 }
987
988
989 /**
990 */
991 void
992 emit_DrawElements_old( GLenum mode, GLsizei count, GLenum type,
993 const GLvoid *indices )
994 {
995 __GLXcontext *gc = __glXGetCurrentContext();
996 const __GLXattribute * state =
997 (const __GLXattribute *)(gc->client_state_private);
998 struct array_state_vector * arrays = state->array_state;
999
1000 GLubyte * pc;
1001 size_t elements_per_request;
1002 unsigned total_requests = 0;
1003 unsigned i;
1004 unsigned req;
1005 const GLuint * ui_ptr = (const GLuint *) indices;
1006 const GLushort * us_ptr = (const GLushort *) indices;
1007 const GLubyte * ub_ptr = (const GLubyte *) indices;
1008
1009
1010 pc = emit_DrawArrays_header_old( gc, arrays, & elements_per_request,
1011 & total_requests, mode, count);
1012
1013
1014 /* Write the arrays.
1015 */
1016
1017 req = 2;
1018 while ( count > 0 ) {
1019 if ( count < elements_per_request ) {
1020 elements_per_request = count;
1021 }
1022
1023 switch( type ) {
1024 case GL_UNSIGNED_INT:
1025 for ( i = 0 ; i < elements_per_request ; i++ ) {
1026 const GLint index = (GLint) *(ui_ptr++);
1027 pc = emit_element_old( pc, arrays, index );
1028 }
1029 break;
1030 case GL_UNSIGNED_SHORT:
1031 for ( i = 0 ; i < elements_per_request ; i++ ) {
1032 const GLint index = (GLint) *(us_ptr++);
1033 pc = emit_element_old( pc, arrays, index );
1034 }
1035 break;
1036 case GL_UNSIGNED_BYTE:
1037 for ( i = 0 ; i < elements_per_request ; i++ ) {
1038 const GLint index = (GLint) *(ub_ptr++);
1039 pc = emit_element_old( pc, arrays, index );
1040 }
1041 break;
1042 }
1043
1044 if ( total_requests != 0 ) {
1045 __glXSendLargeChunk( gc, req, total_requests, gc->pc,
1046 pc - gc->pc );
1047 pc = gc->pc;
1048 req++;
1049 }
1050
1051 count -= elements_per_request;
1052 }
1053
1054
1055 assert( (total_requests == 0) || ((req - 1) == total_requests) );
1056
1057 if ( total_requests == 0 ) {
1058 assert( pc <= gc->bufEnd );
1059
1060 gc->pc = pc;
1061 if ( gc->pc > gc->limit ) {
1062 (void) __glXFlushRenderBuffer(gc, gc->pc);
1063 }
1064 }
1065 }
1066
1067
1068 /**
1069 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
1070 * If it is not valid, then an error code is set in the GLX context.
1071 *
1072 * \returns
1073 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
1074 */
1075 static GLboolean
1076 validate_mode(__GLXcontext *gc, GLenum mode)
1077 {
1078 switch(mode) {
1079 case GL_POINTS:
1080 case GL_LINE_STRIP:
1081 case GL_LINE_LOOP:
1082 case GL_LINES:
1083 case GL_TRIANGLE_STRIP:
1084 case GL_TRIANGLE_FAN:
1085 case GL_TRIANGLES:
1086 case GL_QUAD_STRIP:
1087 case GL_QUADS:
1088 case GL_POLYGON:
1089 break;
1090 default:
1091 __glXSetError(gc, GL_INVALID_ENUM);
1092 return GL_FALSE;
1093 }
1094
1095 return GL_TRUE;
1096 }
1097
1098
1099 /**
1100 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
1101 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
1102 * being set. A value of zero will not result in an error being set, but
1103 * will result in \c GL_FALSE being returned.
1104 *
1105 * \returns
1106 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
1107 */
1108 static GLboolean
1109 validate_count(__GLXcontext *gc, GLsizei count)
1110 {
1111 if (count < 0) {
1112 __glXSetError(gc, GL_INVALID_VALUE);
1113 }
1114
1115 return (count > 0);
1116 }
1117
1118
1119 void __indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
1120 {
1121 __GLXcontext *gc = __glXGetCurrentContext();
1122 const __GLXattribute * state =
1123 (const __GLXattribute *)(gc->client_state_private);
1124 struct array_state_vector * arrays = state->array_state;
1125
1126
1127 if ( validate_mode(gc, mode) && validate_count(gc, count) ) {
1128 if ( ! arrays->array_info_cache_valid ) {
1129 fill_array_info_cache( arrays );
1130 }
1131
1132 arrays->DrawArrays(mode, first, count);
1133 }
1134 }
1135
1136
1137 void __indirect_glArrayElement(GLint index)
1138 {
1139 __GLXcontext *gc = __glXGetCurrentContext();
1140 const __GLXattribute * state =
1141 (const __GLXattribute *)(gc->client_state_private);
1142 struct array_state_vector * arrays = state->array_state;
1143
1144 size_t single_vertex_size;
1145
1146
1147 single_vertex_size = calculate_single_vertex_size_none( arrays );
1148
1149 if ( (gc->pc + single_vertex_size) >= gc->bufEnd ) {
1150 gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
1151 }
1152
1153 gc->pc = emit_element_none( gc->pc, arrays, index );
1154
1155 if ( gc->pc > gc->limit ) {
1156 (void) __glXFlushRenderBuffer(gc, gc->pc);
1157 }
1158 }
1159
1160
1161 void __indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
1162 const GLvoid *indices)
1163 {
1164 __GLXcontext *gc = __glXGetCurrentContext();
1165 const __GLXattribute * state =
1166 (const __GLXattribute *)(gc->client_state_private);
1167 struct array_state_vector * arrays = state->array_state;
1168
1169
1170 if ( validate_mode(gc, mode) && validate_count(gc, count) ) {
1171 if ( ! arrays->array_info_cache_valid ) {
1172 fill_array_info_cache( arrays );
1173 }
1174
1175 arrays->DrawElements(mode, count, type, indices);
1176 }
1177 }
1178
1179
1180 void __indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1181 GLsizei count, GLenum type,
1182 const GLvoid *indices)
1183 {
1184 __GLXcontext *gc = __glXGetCurrentContext();
1185 const __GLXattribute * state =
1186 (const __GLXattribute *)(gc->client_state_private);
1187 struct array_state_vector * arrays = state->array_state;
1188
1189
1190 if ( validate_mode(gc, mode) && validate_count(gc, count) ) {
1191 if (end < start) {
1192 __glXSetError(gc, GL_INVALID_VALUE);
1193 return;
1194 }
1195
1196 if ( ! arrays->array_info_cache_valid ) {
1197 fill_array_info_cache( arrays );
1198 }
1199
1200 arrays->DrawElements(mode, count, type, indices);
1201 }
1202 }
1203
1204
1205 void __indirect_glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count,
1206 GLsizei primcount)
1207 {
1208 __GLXcontext *gc = __glXGetCurrentContext();
1209 const __GLXattribute * state =
1210 (const __GLXattribute *)(gc->client_state_private);
1211 struct array_state_vector * arrays = state->array_state;
1212 GLsizei i;
1213
1214
1215 if ( validate_mode(gc, mode) ) {
1216 if ( ! arrays->array_info_cache_valid ) {
1217 fill_array_info_cache( arrays );
1218 }
1219
1220 for ( i = 0 ; i < primcount ; i++ ) {
1221 if ( validate_count( gc, count[i] ) ) {
1222 arrays->DrawArrays(mode, first[i], count[i]);
1223 }
1224 }
1225 }
1226 }
1227
1228
1229 void __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei *count,
1230 GLenum type, const GLvoid ** indices,
1231 GLsizei primcount)
1232 {
1233 __GLXcontext *gc = __glXGetCurrentContext();
1234 const __GLXattribute * state =
1235 (const __GLXattribute *)(gc->client_state_private);
1236 struct array_state_vector * arrays = state->array_state;
1237 GLsizei i;
1238
1239
1240 if ( validate_mode(gc, mode) ) {
1241 if ( ! arrays->array_info_cache_valid ) {
1242 fill_array_info_cache( arrays );
1243 }
1244
1245 for ( i = 0 ; i < primcount ; i++ ) {
1246 if ( validate_count( gc, count[i] ) ) {
1247 arrays->DrawElements(mode, count[i], type, indices[i]);
1248 }
1249 }
1250 }
1251 }
1252
1253
1254 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, HDR_SIZE, OPCODE) \
1255 do { \
1256 (a)->data = PTR; \
1257 (a)->data_type = TYPE; \
1258 (a)->user_stride = STRIDE; \
1259 (a)->count = COUNT; \
1260 \
1261 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1262 (a)->true_stride = (STRIDE == 0) \
1263 ? (a)->element_size : STRIDE; \
1264 \
1265 (a)->header_size = HDR_SIZE; \
1266 ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1267 ((uint16_t *) (a)->header)[1] = OPCODE; \
1268 } while(0)
1269
1270
1271 void __indirect_glVertexPointer( GLint size, GLenum type, GLsizei stride,
1272 const GLvoid * pointer )
1273 {
1274 static const uint16_t short_ops[5] = {
1275 0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1276 };
1277 static const uint16_t int_ops[5] = {
1278 0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1279 };
1280 static const uint16_t float_ops[5] = {
1281 0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1282 };
1283 static const uint16_t double_ops[5] = {
1284 0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1285 };
1286 uint16_t opcode;
1287 __GLXcontext *gc = __glXGetCurrentContext();
1288 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1289 struct array_state_vector * arrays = state->array_state;
1290 struct array_state * a;
1291
1292
1293 if (size < 2 || size > 4 || stride < 0) {
1294 __glXSetError(gc, GL_INVALID_VALUE);
1295 return;
1296 }
1297
1298 switch ( type ) {
1299 case GL_SHORT: opcode = short_ops[size]; break;
1300 case GL_INT: opcode = int_ops[size]; break;
1301 case GL_FLOAT: opcode = float_ops[size]; break;
1302 case GL_DOUBLE: opcode = double_ops[size]; break;
1303 default:
1304 __glXSetError(gc, GL_INVALID_ENUM);
1305 return;
1306 }
1307
1308 a = get_array_entry( arrays, GL_VERTEX_ARRAY, 0 );
1309 assert( a != NULL );
1310 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 4, opcode );
1311
1312 if ( a->enabled ) {
1313 arrays->array_info_cache_valid = GL_FALSE;
1314 }
1315 }
1316
1317
1318 void __indirect_glNormalPointer( GLenum type, GLsizei stride,
1319 const GLvoid * pointer )
1320 {
1321 uint16_t opcode;
1322 __GLXcontext *gc = __glXGetCurrentContext();
1323 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1324 struct array_state_vector * arrays = state->array_state;
1325 struct array_state * a;
1326
1327
1328 if (stride < 0) {
1329 __glXSetError(gc, GL_INVALID_VALUE);
1330 return;
1331 }
1332
1333 switch ( type ) {
1334 case GL_BYTE: opcode = X_GLrop_Normal3bv; break;
1335 case GL_SHORT: opcode = X_GLrop_Normal3sv; break;
1336 case GL_INT: opcode = X_GLrop_Normal3iv; break;
1337 case GL_FLOAT: opcode = X_GLrop_Normal3fv; break;
1338 case GL_DOUBLE: opcode = X_GLrop_Normal3dv; break;
1339 default:
1340 __glXSetError(gc, GL_INVALID_ENUM);
1341 return;
1342 }
1343
1344 a = get_array_entry( arrays, GL_NORMAL_ARRAY, 0 );
1345 assert( a != NULL );
1346 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 3, 4, opcode );
1347
1348 if ( a->enabled ) {
1349 arrays->array_info_cache_valid = GL_FALSE;
1350 }
1351 }
1352
1353
1354 void __indirect_glColorPointer( GLint size, GLenum type, GLsizei stride,
1355 const GLvoid * pointer )
1356 {
1357 static const uint16_t byte_ops[5] = {
1358 0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1359 };
1360 static const uint16_t ubyte_ops[5] = {
1361 0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1362 };
1363 static const uint16_t short_ops[5] = {
1364 0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1365 };
1366 static const uint16_t ushort_ops[5] = {
1367 0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1368 };
1369 static const uint16_t int_ops[5] = {
1370 0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1371 };
1372 static const uint16_t uint_ops[5] = {
1373 0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1374 };
1375 static const uint16_t float_ops[5] = {
1376 0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1377 };
1378 static const uint16_t double_ops[5] = {
1379 0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1380 };
1381 uint16_t opcode;
1382 __GLXcontext *gc = __glXGetCurrentContext();
1383 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1384 struct array_state_vector * arrays = state->array_state;
1385 struct array_state * a;
1386
1387
1388 if (size < 3 || size > 4 || stride < 0) {
1389 __glXSetError(gc, GL_INVALID_VALUE);
1390 return;
1391 }
1392
1393 switch ( type ) {
1394 case GL_BYTE: opcode = byte_ops[size]; break;
1395 case GL_UNSIGNED_BYTE: opcode = ubyte_ops[size]; break;
1396 case GL_SHORT: opcode = short_ops[size]; break;
1397 case GL_UNSIGNED_SHORT: opcode = ushort_ops[size]; break;
1398 case GL_INT: opcode = int_ops[size]; break;
1399 case GL_UNSIGNED_INT: opcode = uint_ops[size]; break;
1400 case GL_FLOAT: opcode = float_ops[size]; break;
1401 case GL_DOUBLE: opcode = double_ops[size]; break;
1402 default:
1403 __glXSetError(gc, GL_INVALID_ENUM);
1404 return;
1405 }
1406
1407 a = get_array_entry( arrays, GL_COLOR_ARRAY, 0 );
1408 assert( a != NULL );
1409 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 4, opcode );
1410
1411 if ( a->enabled ) {
1412 arrays->array_info_cache_valid = GL_FALSE;
1413 }
1414 }
1415
1416
1417 void __indirect_glIndexPointer( GLenum type, GLsizei stride,
1418 const GLvoid * pointer )
1419 {
1420 uint16_t opcode;
1421 __GLXcontext *gc = __glXGetCurrentContext();
1422 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1423 struct array_state_vector * arrays = state->array_state;
1424 struct array_state * a;
1425
1426
1427 if (stride < 0) {
1428 __glXSetError(gc, GL_INVALID_VALUE);
1429 return;
1430 }
1431
1432 switch ( type ) {
1433 case GL_UNSIGNED_BYTE: opcode = X_GLrop_Indexubv; break;
1434 case GL_SHORT: opcode = X_GLrop_Indexsv; break;
1435 case GL_INT: opcode = X_GLrop_Indexiv; break;
1436 case GL_FLOAT: opcode = X_GLrop_Indexfv; break;
1437 case GL_DOUBLE: opcode = X_GLrop_Indexdv; break;
1438 default:
1439 __glXSetError(gc, GL_INVALID_ENUM);
1440 return;
1441 }
1442
1443 a = get_array_entry( arrays, GL_INDEX_ARRAY, 0 );
1444 assert( a != NULL );
1445 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 1, 4, opcode );
1446
1447 if ( a->enabled ) {
1448 arrays->array_info_cache_valid = GL_FALSE;
1449 }
1450 }
1451
1452
1453 void __indirect_glEdgeFlagPointer( GLsizei stride, const GLvoid * pointer )
1454 {
1455 __GLXcontext *gc = __glXGetCurrentContext();
1456 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1457 struct array_state_vector * arrays = state->array_state;
1458 struct array_state * a;
1459
1460
1461 if (stride < 0) {
1462 __glXSetError(gc, GL_INVALID_VALUE);
1463 return;
1464 }
1465
1466
1467 a = get_array_entry( arrays, GL_EDGE_FLAG_ARRAY, 0 );
1468 assert( a != NULL );
1469 COMMON_ARRAY_DATA_INIT( a, pointer, GL_UNSIGNED_BYTE, stride, 1, 4, X_GLrop_EdgeFlagv );
1470
1471 if ( a->enabled ) {
1472 arrays->array_info_cache_valid = GL_FALSE;
1473 }
1474 }
1475
1476
1477 void __indirect_glTexCoordPointer( GLint size, GLenum type, GLsizei stride,
1478 const GLvoid * pointer )
1479 {
1480 static const uint16_t short_ops[5] = {
1481 0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv, X_GLrop_TexCoord4sv
1482 };
1483 static const uint16_t int_ops[5] = {
1484 0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv, X_GLrop_TexCoord4iv
1485 };
1486 static const uint16_t float_ops[5] = {
1487 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv, X_GLrop_TexCoord4fv
1488 };
1489 static const uint16_t double_ops[5] = {
1490 0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv, X_GLrop_TexCoord4dv
1491 };
1492
1493 static const uint16_t mshort_ops[5] = {
1494 0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB, X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
1495 };
1496 static const uint16_t mint_ops[5] = {
1497 0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB, X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
1498 };
1499 static const uint16_t mfloat_ops[5] = {
1500 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB, X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
1501 };
1502 static const uint16_t mdouble_ops[5] = {
1503 0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB, X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
1504 };
1505
1506 uint16_t opcode;
1507 __GLXcontext *gc = __glXGetCurrentContext();
1508 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1509 struct array_state_vector * arrays = state->array_state;
1510 struct array_state * a;
1511 unsigned header_size;
1512 unsigned index;
1513
1514
1515 if (size < 1 || size > 4 || stride < 0) {
1516 __glXSetError(gc, GL_INVALID_VALUE);
1517 return;
1518 }
1519
1520 index = arrays->active_texture_unit;
1521 if ( index == 0 ) {
1522 switch ( type ) {
1523 case GL_SHORT: opcode = short_ops[size]; break;
1524 case GL_INT: opcode = int_ops[size]; break;
1525 case GL_FLOAT: opcode = float_ops[size]; break;
1526 case GL_DOUBLE: opcode = double_ops[size]; break;
1527 default:
1528 __glXSetError(gc, GL_INVALID_ENUM);
1529 return;
1530 }
1531
1532 header_size = 4;
1533 }
1534 else {
1535 switch ( type ) {
1536 case GL_SHORT: opcode = mshort_ops[size]; break;
1537 case GL_INT: opcode = mint_ops[size]; break;
1538 case GL_FLOAT: opcode = mfloat_ops[size]; break;
1539 case GL_DOUBLE: opcode = mdouble_ops[size]; break;
1540 default:
1541 __glXSetError(gc, GL_INVALID_ENUM);
1542 return;
1543 }
1544
1545 header_size = 8;
1546 }
1547
1548 a = get_array_entry( arrays, GL_TEXTURE_COORD_ARRAY, index );
1549 assert( a != NULL );
1550 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, header_size, opcode );
1551
1552 if ( a->enabled ) {
1553 arrays->array_info_cache_valid = GL_FALSE;
1554 }
1555 }
1556
1557
1558 void __indirect_glSecondaryColorPointerEXT( GLint size, GLenum type, GLsizei stride,
1559 const GLvoid * pointer )
1560 {
1561 uint16_t opcode;
1562 __GLXcontext *gc = __glXGetCurrentContext();
1563 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1564 struct array_state_vector * arrays = state->array_state;
1565 struct array_state * a;
1566
1567
1568 if (size != 3 || stride < 0) {
1569 __glXSetError(gc, GL_INVALID_VALUE);
1570 return;
1571 }
1572
1573 switch ( type ) {
1574 case GL_BYTE: opcode = 4126; break;
1575 case GL_UNSIGNED_BYTE: opcode = 4131; break;
1576 case GL_SHORT: opcode = 4127; break;
1577 case GL_UNSIGNED_SHORT: opcode = 4132; break;
1578 case GL_INT: opcode = 4128; break;
1579 case GL_UNSIGNED_INT: opcode = 4133; break;
1580 case GL_FLOAT: opcode = 4129; break;
1581 case GL_DOUBLE: opcode = 4130; break;
1582 default:
1583 __glXSetError(gc, GL_INVALID_ENUM);
1584 return;
1585 }
1586
1587 a = get_array_entry( arrays, GL_SECONDARY_COLOR_ARRAY, 0 );
1588 if ( a == NULL ) {
1589 __glXSetError(gc, GL_INVALID_OPERATION);
1590 return;
1591 }
1592
1593 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, size, 4, opcode );
1594
1595 if ( a->enabled ) {
1596 arrays->array_info_cache_valid = GL_FALSE;
1597 }
1598 }
1599
1600
1601 void __indirect_glFogCoordPointerEXT( GLenum type, GLsizei stride,
1602 const GLvoid * pointer )
1603 {
1604 uint16_t opcode;
1605 __GLXcontext *gc = __glXGetCurrentContext();
1606 __GLXattribute * state = (__GLXattribute *)(gc->client_state_private);
1607 struct array_state_vector * arrays = state->array_state;
1608 struct array_state * a;
1609
1610
1611 if (stride < 0) {
1612 __glXSetError(gc, GL_INVALID_VALUE);
1613 return;
1614 }
1615
1616 switch ( type ) {
1617 case GL_FLOAT: opcode = 4124; break;
1618 case GL_DOUBLE: opcode = 4125; break;
1619 default:
1620 __glXSetError(gc, GL_INVALID_ENUM);
1621 return;
1622 }
1623
1624 a = get_array_entry( arrays, GL_FOG_COORD_ARRAY, 0 );
1625 if ( a == NULL ) {
1626 __glXSetError(gc, GL_INVALID_OPERATION);
1627 return;
1628 }
1629
1630 COMMON_ARRAY_DATA_INIT( a, pointer, type, stride, 1, 4, opcode );
1631
1632 if ( a->enabled ) {
1633 arrays->array_info_cache_valid = GL_FALSE;
1634 }
1635 }
1636
1637
1638 void __indirect_glClientActiveTextureARB(GLenum texture)
1639 {
1640 __GLXcontext * const gc = __glXGetCurrentContext();
1641 __GLXattribute * const state = (__GLXattribute *)(gc->client_state_private);
1642 struct array_state_vector * const arrays = state->array_state;
1643 const GLint unit = (GLint) texture - GL_TEXTURE0;
1644
1645
1646 if ( (unit < 0) || (unit > arrays->num_texture_units) ) {
1647 __glXSetError(gc, GL_INVALID_ENUM);
1648 return;
1649 }
1650
1651 arrays->active_texture_unit = unit;
1652 }
1653
1654
1655 /**
1656 */
1657 GLboolean
1658 __glXSetArrayEnable( __GLXattribute * state,
1659 GLenum key, unsigned index, GLboolean enable )
1660 {
1661 struct array_state_vector * arrays = state->array_state;
1662 struct array_state * a;
1663
1664
1665 if ( key == GL_TEXTURE_COORD_ARRAY ) {
1666 index = arrays->active_texture_unit;
1667 }
1668
1669 a = get_array_entry( arrays, key, index );
1670
1671 if ( (a != NULL) && (a->enabled != enable) ) {
1672 a->enabled = enable;
1673 arrays->array_info_cache_valid = GL_FALSE;
1674 }
1675
1676 return (a != NULL);
1677 }
1678
1679
1680 void
1681 __glXArrayDisableAll( __GLXattribute * state )
1682 {
1683 struct array_state_vector * arrays = state->array_state;
1684 unsigned i;
1685
1686
1687 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1688 arrays->arrays[i].enabled = GL_FALSE;
1689 }
1690
1691 arrays->array_info_cache_valid = GL_FALSE;
1692 }
1693
1694
1695 /**
1696 */
1697 GLboolean
1698 __glXGetArrayEnable( const __GLXattribute * const state,
1699 GLenum key, unsigned index, GLintptr * dest )
1700 {
1701 const struct array_state_vector * arrays = state->array_state;
1702 const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1703 key, index );
1704
1705 if ( a != NULL ) {
1706 *dest = (GLintptr) a->enabled;
1707 }
1708
1709 return (a != NULL);
1710 }
1711
1712
1713 /**
1714 */
1715 GLboolean
1716 __glXGetArrayType( const __GLXattribute * const state,
1717 GLenum key, unsigned index, GLintptr * dest )
1718 {
1719 const struct array_state_vector * arrays = state->array_state;
1720 const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1721 key, index );
1722
1723 if ( a != NULL ) {
1724 *dest = (GLintptr) a->enabled;
1725 }
1726
1727 return (a != NULL);
1728 }
1729
1730
1731 /**
1732 */
1733 GLboolean
1734 __glXGetArraySize( const __GLXattribute * const state,
1735 GLenum key, unsigned index, GLintptr * dest )
1736 {
1737 const struct array_state_vector * arrays = state->array_state;
1738 const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1739 key, index );
1740
1741 if ( a != NULL ) {
1742 *dest = (GLintptr) a->count;
1743 }
1744
1745 return (a != NULL);
1746 }
1747
1748
1749 /**
1750 */
1751 GLboolean
1752 __glXGetArrayStride( const __GLXattribute * const state,
1753 GLenum key, unsigned index, GLintptr * dest )
1754 {
1755 const struct array_state_vector * arrays = state->array_state;
1756 const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1757 key, index );
1758
1759 if ( a != NULL ) {
1760 *dest = (GLintptr) a->user_stride;
1761 }
1762
1763 return (a != NULL);
1764 }
1765
1766
1767 /**
1768 */
1769 GLboolean
1770 __glXGetArrayPointer( const __GLXattribute * const state,
1771 GLenum key, unsigned index, void ** dest )
1772 {
1773 const struct array_state_vector * arrays = state->array_state;
1774 const struct array_state * a = get_array_entry( (struct array_state_vector *) arrays,
1775 key, index );
1776
1777
1778 if ( a != NULL ) {
1779 *dest = a->data;
1780 }
1781
1782 return (a != NULL);
1783 }
1784
1785
1786 /**
1787 */
1788 GLuint
1789 __glXGetActiveTextureUnit( const __GLXattribute * const state )
1790 {
1791 return state->array_state->active_texture_unit;
1792 }
1793
1794
1795 void
1796 __glXPushArrayState( __GLXattribute * state )
1797 {
1798 struct array_state_vector * arrays = state->array_state;
1799 struct array_stack_state * stack = & arrays->stack[ (arrays->stack_index * arrays->num_arrays)];
1800 unsigned i;
1801
1802
1803 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1804 stack[i].data = arrays->arrays[i].data;
1805 stack[i].data_type = arrays->arrays[i].data_type;
1806 stack[i].user_stride = arrays->arrays[i].user_stride;
1807 stack[i].count = arrays->arrays[i].count;
1808 stack[i].key = arrays->arrays[i].key;
1809 stack[i].enabled = arrays->arrays[i].enabled;
1810 }
1811
1812 arrays->active_texture_unit_stack[ arrays->stack_index ] =
1813 arrays->active_texture_unit;
1814
1815 arrays->stack_index++;
1816 }
1817
1818
1819 void
1820 __glXPopArrayState( __GLXattribute * state )
1821 {
1822 struct array_state_vector * arrays = state->array_state;
1823 struct array_stack_state * stack;
1824 unsigned i;
1825
1826
1827 arrays->stack_index--;
1828 stack = & arrays->stack[ (arrays->stack_index * arrays->num_arrays) ];
1829
1830 for ( i = 0 ; i < arrays->num_arrays ; i++ ) {
1831 switch ( stack[i].key ) {
1832 case GL_NORMAL_ARRAY:
1833 __indirect_glNormalPointer( stack[i].data_type,
1834 stack[i].user_stride,
1835 stack[i].data );
1836 break;
1837 case GL_COLOR_ARRAY:
1838 __indirect_glColorPointer( stack[i].count,
1839 stack[i].data_type,
1840 stack[i].user_stride,
1841 stack[i].data );
1842 break;
1843 case GL_INDEX_ARRAY:
1844 __indirect_glIndexPointer( stack[i].data_type,
1845 stack[i].user_stride,
1846 stack[i].data );
1847 break;
1848 case GL_EDGE_FLAG_ARRAY:
1849 __indirect_glEdgeFlagPointer( stack[i].user_stride,
1850 stack[i].data );
1851 break;
1852 case GL_TEXTURE_COORD_ARRAY:
1853 arrays->active_texture_unit = stack[i].index;
1854 __indirect_glTexCoordPointer( stack[i].count,
1855 stack[i].data_type,
1856 stack[i].user_stride,
1857 stack[i].data );
1858 break;
1859 case GL_SECONDARY_COLOR_ARRAY:
1860 __indirect_glSecondaryColorPointerEXT( stack[i].count,
1861 stack[i].data_type,
1862 stack[i].user_stride,
1863 stack[i].data );
1864 break;
1865 case GL_FOG_COORDINATE_ARRAY:
1866 __indirect_glFogCoordPointerEXT( stack[i].data_type,
1867 stack[i].user_stride,
1868 stack[i].data );
1869 break;
1870
1871 }
1872
1873 __glXSetArrayEnable( state, stack[i].key, stack[i].index,
1874 stack[i].enabled );
1875 }
1876
1877 arrays->active_texture_unit = arrays->active_texture_unit_stack[ arrays->stack_index ];
1878 }