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