2 * (C) Copyright IBM Corporation 2004, 2005
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:
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
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
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
28 #include "glxclient.h"
29 #include "packrender.h"
33 #include <GL/glxproto.h>
34 #include "glxextensions.h"
35 #include "indirect_vertex_array.h"
38 * \file indirect_vertex_array.c
39 * Implement GLX protocol for vertex arrays and vertex buffer objects.
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
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.
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.
63 * \author Ian Romanick <idr@us.ibm.com>
68 * State descriptor for a single array of vertex data.
72 * Pointer to the application supplied data.
77 * Enum representing the type of the application supplied data.
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.
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.
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.
102 * Number of data values in each element.
107 * Pre-calculated GLX protocol command header.
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.
117 unsigned header_size
;
120 * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
126 * For multi-arrayed data (e.g., texture coordinates, generic vertex
127 * program attributes, etc.), this specifies which array this is.
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,
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.
143 GLboolean old_DrawArrays_possible
;
148 * Array state that is pushed / poped by \c glPushClientAttrib and
149 * \c glPopClientAttrib.
151 struct array_stack_state
{
153 * Pointer to the application supplied data.
158 * Enum representing the type of the application supplied data.
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.
170 * Number of data values in each element.
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,
183 * For multi-arrayed data (e.g., texture coordinates, generic vertex
184 * program attributes, etc.), this specifies which array this is.
189 * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
197 * Collection of all the vertex array state.
199 struct array_state_vector
{
201 * Number of arrays tracked by \c ::arrays.
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
212 struct array_state
* arrays
;
215 * Number of currently enabled arrays. The value of this field is
216 * only valid if \c array_info_cache_valid is true.
218 size_t enabled_array_count
;
221 * \name ARRAY_INFO cache.
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.
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.
237 * \c array_info_cache_size and \c array_info_cache_buffer_size do
238 * NOT include the size of \c large_header.
241 size_t array_info_cache_size
;
242 size_t array_info_cache_buffer_size
;
243 void * array_info_cache
;
244 GLubyte
* large_header
;
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.
254 GLboolean array_info_cache_valid
;
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
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.
267 GLboolean old_DrawArrays_possible
;
270 * Is it possible to use the new GL X.X / ARB_vertex_buffer_object
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.
277 GLboolean new_DrawArrays_possible
;
280 * Active texture unit set by \c glClientActiveTexture.
282 * \sa __glXGetActiveTextureUnit
284 unsigned active_texture_unit
;
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.
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).
297 unsigned num_texture_units
;
300 * \n Methods for implementing various GL functions.
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
307 * \sa fill_array_info_cache
310 * Write code to plug these functions directly into the dispatch table.
313 void (*DrawArrays
)( GLenum
, GLint
, GLsizei
);
314 void (*DrawElements
)( GLenum mode
, GLsizei count
, GLenum type
,
315 const GLvoid
*indices
);
318 struct array_stack_state
* stack
;
319 unsigned active_texture_unit_stack
[ __GL_CLIENT_ATTRIB_STACK_DEPTH
];
320 unsigned stack_index
;
324 static void emit_DrawArrays_none( GLenum mode
, GLint first
, GLsizei count
);
325 static void emit_DrawArrays_old ( GLenum mode
, GLint first
, GLsizei count
);
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
);
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
,
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.
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.
354 const GLuint __glXTypeSize_table
[16] = {
355 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
361 * Initialize vertex array state of a GLX context.
363 * \param gc GLX context whose vertex array state is to be initialized.
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
372 * Return values from malloc are not properly tested.
375 __glXInitVertexArrayState( __GLXcontext
* gc
)
377 __GLXattribute
* state
= (__GLXattribute
*)(gc
->client_state_private
);
378 struct array_state_vector
* arrays
;
380 unsigned array_count
;
381 unsigned texture_units
= 1;
384 GLboolean got_fog
= GL_FALSE
;
385 GLboolean got_secondary_color
= GL_FALSE
;
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
;
396 arrays
->old_DrawArrays_possible
= !state
->NoDrawArraysProtocol
;
397 arrays
->new_DrawArrays_possible
= GL_FALSE
;
398 arrays
->DrawArrays
= NULL
;
400 arrays
->active_texture_unit
= 0;
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
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.
415 if ( __glExtensionBitIsEnabled( gc
, GL_EXT_fog_coord_bit
)
416 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4) ) {
421 if ( __glExtensionBitIsEnabled( gc
, GL_EXT_secondary_color_bit
)
422 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4) ) {
423 got_secondary_color
= GL_TRUE
;
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
);
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
);
440 (void) memset( arrays
->arrays
, 0,
441 sizeof( struct array_state
) * array_count
);
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
;
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
;
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
;
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
;
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
;
469 arrays
->arrays
[4 + i
].old_DrawArrays_possible
= (i
== 0);
470 arrays
->arrays
[4 + i
].index
= i
;
472 arrays
->arrays
[4 + i
].header
[1] = i
+ GL_TEXTURE0
;
475 i
= 4 + texture_units
;
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
;
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
;
494 /* Vertex array *must* be last becuase of the way that
495 * emit_DrawArrays_none works.
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
;
504 arrays
->stack_index
= 0;
505 arrays
->stack
= malloc( sizeof( struct array_stack_state
)
506 * arrays
->num_arrays
);
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.
516 calculate_single_vertex_size_none( const struct array_state_vector
* arrays
)
518 size_t single_vertex_size
= 0;
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
;
529 return single_vertex_size
;
534 * Emit a single element using non-DrawArrays protocol.
537 emit_element_none( GLubyte
* dst
,
538 const struct array_state_vector
* arrays
,
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
;
548 (void) memcpy( dst
, arrays
->arrays
[i
].header
,
549 arrays
->arrays
[i
].header_size
);
551 dst
+= arrays
->arrays
[i
].header_size
;
553 (void) memcpy( dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
554 arrays
->arrays
[i
].element_size
);
556 dst
+= __GLX_PAD( arrays
->arrays
[i
].element_size
);
565 * Emit a single element using "old" DrawArrays protocol from
566 * EXT_vertex_arrays / OpenGL 1.1.
569 emit_element_old( GLubyte
* dst
,
570 const struct array_state_vector
* arrays
,
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
;
580 (void) memcpy( dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
581 arrays
->arrays
[i
].element_size
);
583 dst
+= __GLX_PAD( arrays
->arrays
[i
].element_size
);
592 get_array_entry( const struct array_state_vector
* arrays
,
593 GLenum key
, unsigned index
)
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
];
609 allocate_array_info_cache( struct array_state_vector
* arrays
,
610 size_t required_size
)
612 if ( arrays
->array_info_cache_buffer_size
< required_size
) {
613 GLubyte
* temp
= realloc( arrays
->array_info_cache
, required_size
+ 20 );
615 if ( temp
== NULL
) {
619 arrays
->large_header
= temp
;
620 arrays
->array_info_cache
= temp
+ 20;
621 arrays
->array_info_cache_buffer_size
= required_size
;
624 arrays
->array_info_cache_size
= required_size
;
632 fill_array_info_cache( struct array_state_vector
* arrays
)
634 GLboolean old_DrawArrays_possible
;
638 /* Determine how many arrays are enabled.
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
;
651 if ( arrays
->new_DrawArrays_possible
) {
652 assert( ! arrays
->new_DrawArrays_possible
);
654 else if ( old_DrawArrays_possible
) {
655 const size_t required_size
= arrays
->enabled_array_count
* 12;
659 if ( ! allocate_array_info_cache( arrays
, required_size
) ) {
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
;
673 arrays
->array_info_cache_valid
= GL_TRUE
;
674 arrays
->DrawArrays
= emit_DrawArrays_old
;
675 arrays
->DrawElements
= emit_DrawElements_old
;
678 arrays
->DrawArrays
= emit_DrawArrays_none
;
679 arrays
->DrawElements
= emit_DrawElements_none
;
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.
692 emit_DrawArrays_none( GLenum mode
, GLint first
, GLsizei count
)
694 __GLXcontext
*gc
= __glXGetCurrentContext();
695 const __GLXattribute
* state
=
696 (const __GLXattribute
*)(gc
->client_state_private
);
697 struct array_state_vector
* arrays
= state
->array_state
;
699 size_t single_vertex_size
;
702 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
703 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
706 single_vertex_size
= calculate_single_vertex_size_none( arrays
);
710 (void) memcpy( pc
, begin_cmd
, 4 );
711 *(int *)(pc
+ 4) = mode
;
715 for ( i
= 0 ; i
< count
; i
++ ) {
716 if ( (pc
+ single_vertex_size
) >= gc
->bufEnd
) {
717 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
720 pc
= emit_element_none( pc
, arrays
, first
+ i
);
723 if ( (pc
+ 4) >= gc
->bufEnd
) {
724 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
727 (void) memcpy( pc
, end_cmd
, 4 );
731 if ( gc
->pc
> gc
->limit
) {
732 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
738 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
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
746 * \param total_request Total number of requests for a RenderLarge
747 * command. If a Render command is used, this
749 * \param mode Drawing mode.
750 * \param count Number of vertices.
753 * A pointer to the buffer for array data.
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
)
763 size_t single_vertex_size
;
764 const unsigned header_size
= 16;
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.
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
);
781 command_size
= arrays
->array_info_cache_size
+ header_size
782 + (single_vertex_size
* count
);
785 /* Write the header for either a Render command or a RenderLarge
786 * command. After the header is written, write the ARRAY_INFO data.
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.
794 const size_t maxSize
= (gc
->bufSize
+ sz_xGLXRenderReq
)
795 - sz_xGLXRenderLargeReq
;
796 unsigned vertex_requests
;
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.
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.
809 elements_per_request
[0] = maxSize
/ single_vertex_size
;
811 vertex_requests
= (count
+ elements_per_request
[0] - 1)
812 / elements_per_request
[0];
814 *total_requests
= vertex_requests
+ 1;
817 __glXFlushRenderBuffer(gc
, gc
->pc
);
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
;
828 __glXSendLargeChunk( gc
, 1, *total_requests
, pc
,
829 header_size
+ 4 + arrays
->array_info_cache_size
);
834 if ( (gc
->pc
+ command_size
) >= gc
->bufEnd
) {
835 (void) __glXFlushRenderBuffer(gc
, 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
;
847 (void) memcpy( pc
, arrays
->array_info_cache
,
848 arrays
->array_info_cache_size
);
849 pc
+= arrays
->array_info_cache_size
;
851 *elements_per_request
= count
;
863 emit_DrawArrays_old( GLenum mode
, GLint first
, GLsizei count
)
865 __GLXcontext
*gc
= __glXGetCurrentContext();
866 const __GLXattribute
* state
=
867 (const __GLXattribute
*)(gc
->client_state_private
);
868 struct array_state_vector
* arrays
= state
->array_state
;
871 size_t elements_per_request
;
872 unsigned total_requests
= 0;
874 size_t total_sent
= 0;
877 pc
= emit_DrawArrays_header_old( gc
, arrays
, & elements_per_request
,
878 & total_requests
, mode
, count
);
884 if ( total_requests
== 0 ) {
885 assert( elements_per_request
>= count
);
887 for ( i
= 0 ; i
< count
; i
++ ) {
888 pc
= emit_element_old( pc
, arrays
, i
+ first
);
891 assert( pc
<= gc
->bufEnd
);
894 if ( gc
->pc
> gc
->limit
) {
895 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
902 for ( req
= 2 ; req
<= total_requests
; req
++ ) {
903 if ( count
< elements_per_request
) {
904 elements_per_request
= count
;
908 for ( i
= 0 ; i
< elements_per_request
; i
++ ) {
909 pc
= emit_element_old( pc
, arrays
, i
+ first
);
912 first
+= elements_per_request
;
914 total_sent
+= (size_t) (pc
- gc
->pc
);
915 __glXSendLargeChunk( gc
, req
, total_requests
, gc
->pc
,
918 count
-= elements_per_request
;
925 emit_DrawElements_none( GLenum mode
, GLsizei count
, GLenum type
,
926 const GLvoid
*indices
)
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
};
936 size_t single_vertex_size
;
940 single_vertex_size
= calculate_single_vertex_size_none( arrays
);
943 if ( (gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
944 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
949 (void) memcpy( pc
, begin_cmd
, 4 );
950 *(int *)(pc
+ 4) = mode
;
954 for ( i
= 0 ; i
< count
; i
++ ) {
957 if ( (pc
+ single_vertex_size
) >= gc
->bufEnd
) {
958 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
962 case GL_UNSIGNED_INT
:
963 index
= (unsigned) (((GLuint
*) indices
)[i
]);
965 case GL_UNSIGNED_SHORT
:
966 index
= (unsigned) (((GLushort
*) indices
)[i
]);
968 case GL_UNSIGNED_BYTE
:
969 index
= (unsigned) (((GLubyte
*) indices
)[i
]);
972 pc
= emit_element_none( pc
, arrays
, index
);
975 if ( (pc
+ 4) >= gc
->bufEnd
) {
976 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
979 (void) memcpy( pc
, end_cmd
, 4 );
983 if ( gc
->pc
> gc
->limit
) {
984 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
992 emit_DrawElements_old( GLenum mode
, GLsizei count
, GLenum type
,
993 const GLvoid
*indices
)
995 __GLXcontext
*gc
= __glXGetCurrentContext();
996 const __GLXattribute
* state
=
997 (const __GLXattribute
*)(gc
->client_state_private
);
998 struct array_state_vector
* arrays
= state
->array_state
;
1001 size_t elements_per_request
;
1002 unsigned total_requests
= 0;
1005 const GLuint
* ui_ptr
= (const GLuint
*) indices
;
1006 const GLushort
* us_ptr
= (const GLushort
*) indices
;
1007 const GLubyte
* ub_ptr
= (const GLubyte
*) indices
;
1010 pc
= emit_DrawArrays_header_old( gc
, arrays
, & elements_per_request
,
1011 & total_requests
, mode
, count
);
1014 /* Write the arrays.
1018 while ( count
> 0 ) {
1019 if ( count
< elements_per_request
) {
1020 elements_per_request
= count
;
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
);
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
);
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
);
1044 if ( total_requests
!= 0 ) {
1045 __glXSendLargeChunk( gc
, req
, total_requests
, gc
->pc
,
1051 count
-= elements_per_request
;
1055 assert( (total_requests
== 0) || ((req
- 1) == total_requests
) );
1057 if ( total_requests
== 0 ) {
1058 assert( pc
<= gc
->bufEnd
);
1061 if ( gc
->pc
> gc
->limit
) {
1062 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
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.
1073 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
1076 validate_mode(__GLXcontext
*gc
, GLenum mode
)
1083 case GL_TRIANGLE_STRIP
:
1084 case GL_TRIANGLE_FAN
:
1091 __glXSetError(gc
, GL_INVALID_ENUM
);
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.
1106 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
1109 validate_count(__GLXcontext
*gc
, GLsizei count
)
1112 __glXSetError(gc
, GL_INVALID_VALUE
);
1119 void __indirect_glDrawArrays(GLenum mode
, GLint first
, GLsizei count
)
1121 __GLXcontext
*gc
= __glXGetCurrentContext();
1122 const __GLXattribute
* state
=
1123 (const __GLXattribute
*)(gc
->client_state_private
);
1124 struct array_state_vector
* arrays
= state
->array_state
;
1127 if ( validate_mode(gc
, mode
) && validate_count(gc
, count
) ) {
1128 if ( ! arrays
->array_info_cache_valid
) {
1129 fill_array_info_cache( arrays
);
1132 arrays
->DrawArrays(mode
, first
, count
);
1137 void __indirect_glArrayElement(GLint index
)
1139 __GLXcontext
*gc
= __glXGetCurrentContext();
1140 const __GLXattribute
* state
=
1141 (const __GLXattribute
*)(gc
->client_state_private
);
1142 struct array_state_vector
* arrays
= state
->array_state
;
1144 size_t single_vertex_size
;
1147 single_vertex_size
= calculate_single_vertex_size_none( arrays
);
1149 if ( (gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
1150 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
1153 gc
->pc
= emit_element_none( gc
->pc
, arrays
, index
);
1155 if ( gc
->pc
> gc
->limit
) {
1156 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
1161 void __indirect_glDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1162 const GLvoid
*indices
)
1164 __GLXcontext
*gc
= __glXGetCurrentContext();
1165 const __GLXattribute
* state
=
1166 (const __GLXattribute
*)(gc
->client_state_private
);
1167 struct array_state_vector
* arrays
= state
->array_state
;
1170 if ( validate_mode(gc
, mode
) && validate_count(gc
, count
) ) {
1171 if ( ! arrays
->array_info_cache_valid
) {
1172 fill_array_info_cache( arrays
);
1175 arrays
->DrawElements(mode
, count
, type
, indices
);
1180 void __indirect_glDrawRangeElements(GLenum mode
, GLuint start
, GLuint end
,
1181 GLsizei count
, GLenum type
,
1182 const GLvoid
*indices
)
1184 __GLXcontext
*gc
= __glXGetCurrentContext();
1185 const __GLXattribute
* state
=
1186 (const __GLXattribute
*)(gc
->client_state_private
);
1187 struct array_state_vector
* arrays
= state
->array_state
;
1190 if ( validate_mode(gc
, mode
) && validate_count(gc
, count
) ) {
1192 __glXSetError(gc
, GL_INVALID_VALUE
);
1196 if ( ! arrays
->array_info_cache_valid
) {
1197 fill_array_info_cache( arrays
);
1200 arrays
->DrawElements(mode
, count
, type
, indices
);
1205 void __indirect_glMultiDrawArraysEXT(GLenum mode
, GLint
*first
, GLsizei
*count
,
1208 __GLXcontext
*gc
= __glXGetCurrentContext();
1209 const __GLXattribute
* state
=
1210 (const __GLXattribute
*)(gc
->client_state_private
);
1211 struct array_state_vector
* arrays
= state
->array_state
;
1215 if ( validate_mode(gc
, mode
) ) {
1216 if ( ! arrays
->array_info_cache_valid
) {
1217 fill_array_info_cache( arrays
);
1220 for ( i
= 0 ; i
< primcount
; i
++ ) {
1221 if ( validate_count( gc
, count
[i
] ) ) {
1222 arrays
->DrawArrays(mode
, first
[i
], count
[i
]);
1229 void __indirect_glMultiDrawElementsEXT(GLenum mode
, const GLsizei
*count
,
1230 GLenum type
, const GLvoid
** indices
,
1233 __GLXcontext
*gc
= __glXGetCurrentContext();
1234 const __GLXattribute
* state
=
1235 (const __GLXattribute
*)(gc
->client_state_private
);
1236 struct array_state_vector
* arrays
= state
->array_state
;
1240 if ( validate_mode(gc
, mode
) ) {
1241 if ( ! arrays
->array_info_cache_valid
) {
1242 fill_array_info_cache( arrays
);
1245 for ( i
= 0 ; i
< primcount
; i
++ ) {
1246 if ( validate_count( gc
, count
[i
] ) ) {
1247 arrays
->DrawElements(mode
, count
[i
], type
, indices
[i
]);
1254 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, HDR_SIZE, OPCODE) \
1257 (a)->data_type = TYPE; \
1258 (a)->user_stride = STRIDE; \
1259 (a)->count = COUNT; \
1261 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1262 (a)->true_stride = (STRIDE == 0) \
1263 ? (a)->element_size : STRIDE; \
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; \
1271 void __indirect_glVertexPointer( GLint size
, GLenum type
, GLsizei stride
,
1272 const GLvoid
* pointer
)
1274 static const uint16_t short_ops
[5] = {
1275 0, 0, X_GLrop_Vertex2sv
, X_GLrop_Vertex3sv
, X_GLrop_Vertex4sv
1277 static const uint16_t int_ops
[5] = {
1278 0, 0, X_GLrop_Vertex2iv
, X_GLrop_Vertex3iv
, X_GLrop_Vertex4iv
1280 static const uint16_t float_ops
[5] = {
1281 0, 0, X_GLrop_Vertex2fv
, X_GLrop_Vertex3fv
, X_GLrop_Vertex4fv
1283 static const uint16_t double_ops
[5] = {
1284 0, 0, X_GLrop_Vertex2dv
, X_GLrop_Vertex3dv
, X_GLrop_Vertex4dv
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
;
1293 if (size
< 2 || size
> 4 || stride
< 0) {
1294 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1304 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1313 arrays
->array_info_cache_valid
= GL_FALSE
;
1318 void __indirect_glNormalPointer( GLenum type
, GLsizei stride
,
1319 const GLvoid
* pointer
)
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
;
1329 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1340 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1349 arrays
->array_info_cache_valid
= GL_FALSE
;
1354 void __indirect_glColorPointer( GLint size
, GLenum type
, GLsizei stride
,
1355 const GLvoid
* pointer
)
1357 static const uint16_t byte_ops
[5] = {
1358 0, 0, 0, X_GLrop_Color3bv
, X_GLrop_Color4bv
1360 static const uint16_t ubyte_ops
[5] = {
1361 0, 0, 0, X_GLrop_Color3ubv
, X_GLrop_Color4ubv
1363 static const uint16_t short_ops
[5] = {
1364 0, 0, 0, X_GLrop_Color3sv
, X_GLrop_Color4sv
1366 static const uint16_t ushort_ops
[5] = {
1367 0, 0, 0, X_GLrop_Color3usv
, X_GLrop_Color4usv
1369 static const uint16_t int_ops
[5] = {
1370 0, 0, 0, X_GLrop_Color3iv
, X_GLrop_Color4iv
1372 static const uint16_t uint_ops
[5] = {
1373 0, 0, 0, X_GLrop_Color3uiv
, X_GLrop_Color4uiv
1375 static const uint16_t float_ops
[5] = {
1376 0, 0, 0, X_GLrop_Color3fv
, X_GLrop_Color4fv
1378 static const uint16_t double_ops
[5] = {
1379 0, 0, 0, X_GLrop_Color3dv
, X_GLrop_Color4dv
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
;
1388 if (size
< 3 || size
> 4 || stride
< 0) {
1389 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1403 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1412 arrays
->array_info_cache_valid
= GL_FALSE
;
1417 void __indirect_glIndexPointer( GLenum type
, GLsizei stride
,
1418 const GLvoid
* pointer
)
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
;
1428 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1439 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1448 arrays
->array_info_cache_valid
= GL_FALSE
;
1453 void __indirect_glEdgeFlagPointer( GLsizei stride
, const GLvoid
* pointer
)
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
;
1462 __glXSetError(gc
, GL_INVALID_VALUE
);
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
);
1472 arrays
->array_info_cache_valid
= GL_FALSE
;
1477 void __indirect_glTexCoordPointer( GLint size
, GLenum type
, GLsizei stride
,
1478 const GLvoid
* pointer
)
1480 static const uint16_t short_ops
[5] = {
1481 0, X_GLrop_TexCoord1sv
, X_GLrop_TexCoord2sv
, X_GLrop_TexCoord3sv
, X_GLrop_TexCoord4sv
1483 static const uint16_t int_ops
[5] = {
1484 0, X_GLrop_TexCoord1iv
, X_GLrop_TexCoord2iv
, X_GLrop_TexCoord3iv
, X_GLrop_TexCoord4iv
1486 static const uint16_t float_ops
[5] = {
1487 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2fv
, X_GLrop_TexCoord3fv
, X_GLrop_TexCoord4fv
1489 static const uint16_t double_ops
[5] = {
1490 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2dv
, X_GLrop_TexCoord3dv
, X_GLrop_TexCoord4dv
1493 static const uint16_t mshort_ops
[5] = {
1494 0, X_GLrop_MultiTexCoord1svARB
, X_GLrop_MultiTexCoord2svARB
, X_GLrop_MultiTexCoord3svARB
, X_GLrop_MultiTexCoord4svARB
1496 static const uint16_t mint_ops
[5] = {
1497 0, X_GLrop_MultiTexCoord1ivARB
, X_GLrop_MultiTexCoord2ivARB
, X_GLrop_MultiTexCoord3ivARB
, X_GLrop_MultiTexCoord4ivARB
1499 static const uint16_t mfloat_ops
[5] = {
1500 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2fvARB
, X_GLrop_MultiTexCoord3fvARB
, X_GLrop_MultiTexCoord4fvARB
1502 static const uint16_t mdouble_ops
[5] = {
1503 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2dvARB
, X_GLrop_MultiTexCoord3dvARB
, X_GLrop_MultiTexCoord4dvARB
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
;
1515 if (size
< 1 || size
> 4 || stride
< 0) {
1516 __glXSetError(gc
, GL_INVALID_VALUE
);
1520 index
= arrays
->active_texture_unit
;
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;
1528 __glXSetError(gc
, GL_INVALID_ENUM
);
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;
1541 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1553 arrays
->array_info_cache_valid
= GL_FALSE
;
1558 void __indirect_glSecondaryColorPointerEXT( GLint size
, GLenum type
, GLsizei stride
,
1559 const GLvoid
* pointer
)
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
;
1568 if (size
!= 3 || stride
< 0) {
1569 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1583 __glXSetError(gc
, GL_INVALID_ENUM
);
1587 a
= get_array_entry( arrays
, GL_SECONDARY_COLOR_ARRAY
, 0 );
1589 __glXSetError(gc
, GL_INVALID_OPERATION
);
1593 COMMON_ARRAY_DATA_INIT( a
, pointer
, type
, stride
, size
, 4, opcode
);
1596 arrays
->array_info_cache_valid
= GL_FALSE
;
1601 void __indirect_glFogCoordPointerEXT( GLenum type
, GLsizei stride
,
1602 const GLvoid
* pointer
)
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
;
1612 __glXSetError(gc
, GL_INVALID_VALUE
);
1617 case GL_FLOAT
: opcode
= 4124; break;
1618 case GL_DOUBLE
: opcode
= 4125; break;
1620 __glXSetError(gc
, GL_INVALID_ENUM
);
1624 a
= get_array_entry( arrays
, GL_FOG_COORD_ARRAY
, 0 );
1626 __glXSetError(gc
, GL_INVALID_OPERATION
);
1630 COMMON_ARRAY_DATA_INIT( a
, pointer
, type
, stride
, 1, 4, opcode
);
1633 arrays
->array_info_cache_valid
= GL_FALSE
;
1638 void __indirect_glClientActiveTextureARB(GLenum texture
)
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
;
1646 if ( (unit
< 0) || (unit
> arrays
->num_texture_units
) ) {
1647 __glXSetError(gc
, GL_INVALID_ENUM
);
1651 arrays
->active_texture_unit
= unit
;
1658 __glXSetArrayEnable( __GLXattribute
* state
,
1659 GLenum key
, unsigned index
, GLboolean enable
)
1661 struct array_state_vector
* arrays
= state
->array_state
;
1662 struct array_state
* a
;
1665 if ( key
== GL_TEXTURE_COORD_ARRAY
) {
1666 index
= arrays
->active_texture_unit
;
1669 a
= get_array_entry( arrays
, key
, index
);
1671 if ( (a
!= NULL
) && (a
->enabled
!= enable
) ) {
1672 a
->enabled
= enable
;
1673 arrays
->array_info_cache_valid
= GL_FALSE
;
1681 __glXArrayDisableAll( __GLXattribute
* state
)
1683 struct array_state_vector
* arrays
= state
->array_state
;
1687 for ( i
= 0 ; i
< arrays
->num_arrays
; i
++ ) {
1688 arrays
->arrays
[i
].enabled
= GL_FALSE
;
1691 arrays
->array_info_cache_valid
= GL_FALSE
;
1698 __glXGetArrayEnable( const __GLXattribute
* const state
,
1699 GLenum key
, unsigned index
, GLintptr
* dest
)
1701 const struct array_state_vector
* arrays
= state
->array_state
;
1702 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1706 *dest
= (GLintptr
) a
->enabled
;
1716 __glXGetArrayType( const __GLXattribute
* const state
,
1717 GLenum key
, unsigned index
, GLintptr
* dest
)
1719 const struct array_state_vector
* arrays
= state
->array_state
;
1720 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1724 *dest
= (GLintptr
) a
->enabled
;
1734 __glXGetArraySize( const __GLXattribute
* const state
,
1735 GLenum key
, unsigned index
, GLintptr
* dest
)
1737 const struct array_state_vector
* arrays
= state
->array_state
;
1738 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1742 *dest
= (GLintptr
) a
->count
;
1752 __glXGetArrayStride( const __GLXattribute
* const state
,
1753 GLenum key
, unsigned index
, GLintptr
* dest
)
1755 const struct array_state_vector
* arrays
= state
->array_state
;
1756 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1760 *dest
= (GLintptr
) a
->user_stride
;
1770 __glXGetArrayPointer( const __GLXattribute
* const state
,
1771 GLenum key
, unsigned index
, void ** dest
)
1773 const struct array_state_vector
* arrays
= state
->array_state
;
1774 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1789 __glXGetActiveTextureUnit( const __GLXattribute
* const state
)
1791 return state
->array_state
->active_texture_unit
;
1796 __glXPushArrayState( __GLXattribute
* state
)
1798 struct array_state_vector
* arrays
= state
->array_state
;
1799 struct array_stack_state
* stack
= & arrays
->stack
[ (arrays
->stack_index
* arrays
->num_arrays
)];
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
;
1812 arrays
->active_texture_unit_stack
[ arrays
->stack_index
] =
1813 arrays
->active_texture_unit
;
1815 arrays
->stack_index
++;
1820 __glXPopArrayState( __GLXattribute
* state
)
1822 struct array_state_vector
* arrays
= state
->array_state
;
1823 struct array_stack_state
* stack
;
1827 arrays
->stack_index
--;
1828 stack
= & arrays
->stack
[ (arrays
->stack_index
* arrays
->num_arrays
) ];
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
,
1837 case GL_COLOR_ARRAY
:
1838 __indirect_glColorPointer( stack
[i
].count
,
1840 stack
[i
].user_stride
,
1843 case GL_INDEX_ARRAY
:
1844 __indirect_glIndexPointer( stack
[i
].data_type
,
1845 stack
[i
].user_stride
,
1848 case GL_EDGE_FLAG_ARRAY
:
1849 __indirect_glEdgeFlagPointer( stack
[i
].user_stride
,
1852 case GL_TEXTURE_COORD_ARRAY
:
1853 arrays
->active_texture_unit
= stack
[i
].index
;
1854 __indirect_glTexCoordPointer( stack
[i
].count
,
1856 stack
[i
].user_stride
,
1859 case GL_SECONDARY_COLOR_ARRAY
:
1860 __indirect_glSecondaryColorPointerEXT( stack
[i
].count
,
1862 stack
[i
].user_stride
,
1865 case GL_FOG_COORDINATE_ARRAY
:
1866 __indirect_glFogCoordPointerEXT( stack
[i
].data_type
,
1867 stack
[i
].user_stride
,
1873 __glXSetArrayEnable( state
, stack
[i
].key
, stack
[i
].index
,
1877 arrays
->active_texture_unit
= arrays
->active_texture_unit_stack
[ arrays
->stack_index
];