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
30 #include "glxclient.h"
32 #include <GL/glxproto.h>
33 #include "glxextensions.h"
34 #include "indirect_vertex_array.h"
36 #define __GLX_PAD(n) (((n)+3) & ~3)
39 * \file indirect_vertex_array.c
40 * Implement GLX protocol for vertex arrays and vertex buffer objects.
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
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.
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.
64 * \author Ian Romanick <idr@us.ibm.com>
69 * State descriptor for a single array of vertex data.
73 * Pointer to the application supplied data.
78 * Enum representing the type of the application supplied data.
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.
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.
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.
103 * Number of data values in each element.
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.
111 GLboolean normalized
;
114 * Pre-calculated GLX protocol command header.
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.
124 unsigned header_size
;
127 * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
133 * For multi-arrayed data (e.g., texture coordinates, generic vertex
134 * program attributes, etc.), this specifies which array this is.
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,
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.
150 GLboolean old_DrawArrays_possible
;
155 * Array state that is pushed / poped by \c glPushClientAttrib and
156 * \c glPopClientAttrib.
158 struct array_stack_state
{
160 * Pointer to the application supplied data.
165 * Enum representing the type of the application supplied data.
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.
177 * Number of data values in each element.
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,
190 * For multi-arrayed data (e.g., texture coordinates, generic vertex
191 * program attributes, etc.), this specifies which array this is.
196 * Set to \c GL_TRUE if this array is enabled. Otherwise, it is set
204 * Collection of all the vertex array state.
206 struct array_state_vector
{
208 * Number of arrays tracked by \c ::arrays.
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
219 struct array_state
* arrays
;
222 * Number of currently enabled arrays. The value of this field is
223 * only valid if \c array_info_cache_valid is true.
225 size_t enabled_array_count
;
228 * \name ARRAY_INFO cache.
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.
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.
244 * \c array_info_cache_size and \c array_info_cache_buffer_size do
245 * NOT include the size of \c large_header.
248 size_t array_info_cache_size
;
249 size_t array_info_cache_buffer_size
;
250 void * array_info_cache
;
251 GLubyte
* large_header
;
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.
261 GLboolean array_info_cache_valid
;
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
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.
274 GLboolean old_DrawArrays_possible
;
277 * Is it possible to use the new GL X.X / ARB_vertex_buffer_object
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.
284 GLboolean new_DrawArrays_possible
;
287 * Active texture unit set by \c glClientActiveTexture.
289 * \sa __glXGetActiveTextureUnit
291 unsigned active_texture_unit
;
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.
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).
304 unsigned num_texture_units
;
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.
312 unsigned num_vertex_program_attribs
;
315 * \n Methods for implementing various GL functions.
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
322 * \sa fill_array_info_cache
325 * Write code to plug these functions directly into the dispatch table.
328 void (*DrawArrays
)( GLenum
, GLint
, GLsizei
);
329 void (*DrawElements
)( GLenum mode
, GLsizei count
, GLenum type
,
330 const GLvoid
*indices
);
333 struct array_stack_state
* stack
;
334 unsigned active_texture_unit_stack
[ __GL_CLIENT_ATTRIB_STACK_DEPTH
];
335 unsigned stack_index
;
339 static void emit_DrawArrays_none( GLenum mode
, GLint first
, GLsizei count
);
340 static void emit_DrawArrays_old ( GLenum mode
, GLint first
, GLsizei count
);
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
);
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
);
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.
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.
370 const GLuint __glXTypeSize_table
[16] = {
371 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
377 * Initialize vertex array state of a GLX context.
379 * \param gc GLX context whose vertex array state is to be initialized.
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
388 * Return values from malloc are not properly tested.
391 __glXInitVertexArrayState( __GLXcontext
* gc
)
393 __GLXattribute
* state
= (__GLXattribute
*)(gc
->client_state_private
);
394 struct array_state_vector
* arrays
;
396 unsigned array_count
;
397 unsigned texture_units
= 1;
400 unsigned vertex_program_attribs
= 0;
402 GLboolean got_fog
= GL_FALSE
;
403 GLboolean got_secondary_color
= GL_FALSE
;
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
;
414 arrays
->old_DrawArrays_possible
= !state
->NoDrawArraysProtocol
;
415 arrays
->new_DrawArrays_possible
= GL_FALSE
;
416 arrays
->DrawArrays
= NULL
;
418 arrays
->active_texture_unit
= 0;
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
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.
433 if ( __glExtensionBitIsEnabled( gc
, GL_EXT_fog_coord_bit
)
434 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4) ) {
439 if ( __glExtensionBitIsEnabled( gc
, GL_EXT_secondary_color_bit
)
440 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4) ) {
441 got_secondary_color
= GL_TRUE
;
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
);
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
);
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
);
462 (void) memset( arrays
->arrays
, 0,
463 sizeof( struct array_state
) * array_count
);
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
;
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
;
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
;
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
;
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
;
493 arrays
->arrays
[4 + i
].old_DrawArrays_possible
= (i
== 0);
494 arrays
->arrays
[4 + i
].index
= i
;
496 arrays
->arrays
[4 + i
].header
[1] = i
+ GL_TEXTURE0
;
499 i
= 4 + texture_units
;
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
;
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
;
519 for ( j
= 0 ; j
< vertex_program_attribs
; j
++ ) {
520 const unsigned idx
= (vertex_program_attribs
- (j
+ 1));
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
;
527 arrays
->arrays
[idx
+ i
].old_DrawArrays_possible
= 0;
528 arrays
->arrays
[idx
+ i
].index
= idx
;
530 arrays
->arrays
[idx
+ i
].header
[1] = idx
;
533 i
+= vertex_program_attribs
;
536 /* Vertex array *must* be last becuase of the way that
537 * emit_DrawArrays_none works.
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
;
546 arrays
->stack_index
= 0;
547 arrays
->stack
= malloc( sizeof( struct array_stack_state
)
548 * arrays
->num_arrays
);
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.
558 calculate_single_vertex_size_none( const struct array_state_vector
* arrays
)
560 size_t single_vertex_size
= 0;
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];
570 return single_vertex_size
;
575 * Emit a single element using non-DrawArrays protocol.
578 emit_element_none( GLubyte
* dst
,
579 const struct array_state_vector
* arrays
,
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
;
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.
595 (void) memset( dst
, 0,
596 ((uint16_t *)arrays
->arrays
[i
].header
)[0] );
598 (void) memcpy( dst
, arrays
->arrays
[i
].header
,
599 arrays
->arrays
[i
].header_size
);
601 dst
+= arrays
->arrays
[i
].header_size
;
603 (void) memcpy( dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
604 arrays
->arrays
[i
].element_size
);
606 dst
+= __GLX_PAD( arrays
->arrays
[i
].element_size
);
615 * Emit a single element using "old" DrawArrays protocol from
616 * EXT_vertex_arrays / OpenGL 1.1.
619 emit_element_old( GLubyte
* dst
,
620 const struct array_state_vector
* arrays
,
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
;
630 (void) memcpy( dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
631 arrays
->arrays
[i
].element_size
);
633 dst
+= __GLX_PAD( arrays
->arrays
[i
].element_size
);
642 get_array_entry( const struct array_state_vector
* arrays
,
643 GLenum key
, unsigned index
)
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
];
659 allocate_array_info_cache( struct array_state_vector
* arrays
,
660 size_t required_size
)
662 if ( arrays
->array_info_cache_buffer_size
< required_size
) {
663 GLubyte
* temp
= realloc( arrays
->array_info_cache
, required_size
+ 20 );
665 if ( temp
== NULL
) {
669 arrays
->large_header
= temp
;
670 arrays
->array_info_cache
= temp
+ 20;
671 arrays
->array_info_cache_buffer_size
= required_size
;
674 arrays
->array_info_cache_size
= required_size
;
682 fill_array_info_cache( struct array_state_vector
* arrays
)
684 GLboolean old_DrawArrays_possible
;
688 /* Determine how many arrays are enabled.
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
;
701 if ( arrays
->new_DrawArrays_possible
) {
702 assert( ! arrays
->new_DrawArrays_possible
);
704 else if ( old_DrawArrays_possible
) {
705 const size_t required_size
= arrays
->enabled_array_count
* 12;
709 if ( ! allocate_array_info_cache( arrays
, required_size
) ) {
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
;
723 arrays
->array_info_cache_valid
= GL_TRUE
;
724 arrays
->DrawArrays
= emit_DrawArrays_old
;
725 arrays
->DrawElements
= emit_DrawElements_old
;
728 arrays
->DrawArrays
= emit_DrawArrays_none
;
729 arrays
->DrawElements
= emit_DrawElements_none
;
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.
742 emit_DrawArrays_none( GLenum mode
, GLint first
, GLsizei count
)
744 __GLXcontext
*gc
= __glXGetCurrentContext();
745 const __GLXattribute
* state
=
746 (const __GLXattribute
*)(gc
->client_state_private
);
747 struct array_state_vector
* arrays
= state
->array_state
;
749 size_t single_vertex_size
;
752 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
753 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
756 single_vertex_size
= calculate_single_vertex_size_none( arrays
);
760 (void) memcpy( pc
, begin_cmd
, 4 );
761 *(int *)(pc
+ 4) = mode
;
765 for ( i
= 0 ; i
< count
; i
++ ) {
766 if ( (pc
+ single_vertex_size
) >= gc
->bufEnd
) {
767 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
770 pc
= emit_element_none( pc
, arrays
, first
+ i
);
773 if ( (pc
+ 4) >= gc
->bufEnd
) {
774 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
777 (void) memcpy( pc
, end_cmd
, 4 );
781 if ( gc
->pc
> gc
->limit
) {
782 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
788 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
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
796 * \param total_request Total number of requests for a RenderLarge
797 * command. If a Render command is used, this
799 * \param mode Drawing mode.
800 * \param count Number of vertices.
803 * A pointer to the buffer for array data.
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
)
813 size_t single_vertex_size
;
814 const unsigned header_size
= 16;
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.
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
);
831 command_size
= arrays
->array_info_cache_size
+ header_size
832 + (single_vertex_size
* count
);
835 /* Write the header for either a Render command or a RenderLarge
836 * command. After the header is written, write the ARRAY_INFO data.
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.
844 const size_t maxSize
= (gc
->bufSize
+ sz_xGLXRenderReq
)
845 - sz_xGLXRenderLargeReq
;
846 unsigned vertex_requests
;
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.
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.
859 elements_per_request
[0] = maxSize
/ single_vertex_size
;
861 vertex_requests
= (count
+ elements_per_request
[0] - 1)
862 / elements_per_request
[0];
864 *total_requests
= vertex_requests
+ 1;
867 __glXFlushRenderBuffer(gc
, gc
->pc
);
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
;
878 __glXSendLargeChunk( gc
, 1, *total_requests
, pc
,
879 header_size
+ 4 + arrays
->array_info_cache_size
);
884 if ( (gc
->pc
+ command_size
) >= gc
->bufEnd
) {
885 (void) __glXFlushRenderBuffer(gc
, 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
;
897 (void) memcpy( pc
, arrays
->array_info_cache
,
898 arrays
->array_info_cache_size
);
899 pc
+= arrays
->array_info_cache_size
;
901 *elements_per_request
= count
;
913 emit_DrawArrays_old( GLenum mode
, GLint first
, GLsizei count
)
915 __GLXcontext
*gc
= __glXGetCurrentContext();
916 const __GLXattribute
* state
=
917 (const __GLXattribute
*)(gc
->client_state_private
);
918 struct array_state_vector
* arrays
= state
->array_state
;
921 size_t elements_per_request
;
922 unsigned total_requests
= 0;
924 size_t total_sent
= 0;
927 pc
= emit_DrawArrays_header_old( gc
, arrays
, & elements_per_request
,
928 & total_requests
, mode
, count
);
934 if ( total_requests
== 0 ) {
935 assert( elements_per_request
>= count
);
937 for ( i
= 0 ; i
< count
; i
++ ) {
938 pc
= emit_element_old( pc
, arrays
, i
+ first
);
941 assert( pc
<= gc
->bufEnd
);
944 if ( gc
->pc
> gc
->limit
) {
945 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
952 for ( req
= 2 ; req
<= total_requests
; req
++ ) {
953 if ( count
< elements_per_request
) {
954 elements_per_request
= count
;
958 for ( i
= 0 ; i
< elements_per_request
; i
++ ) {
959 pc
= emit_element_old( pc
, arrays
, i
+ first
);
962 first
+= elements_per_request
;
964 total_sent
+= (size_t) (pc
- gc
->pc
);
965 __glXSendLargeChunk( gc
, req
, total_requests
, gc
->pc
,
968 count
-= elements_per_request
;
975 emit_DrawElements_none( GLenum mode
, GLsizei count
, GLenum type
,
976 const GLvoid
*indices
)
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
};
986 size_t single_vertex_size
;
990 single_vertex_size
= calculate_single_vertex_size_none( arrays
);
993 if ( (gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
994 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
999 (void) memcpy( pc
, begin_cmd
, 4 );
1000 *(int *)(pc
+ 4) = mode
;
1004 for ( i
= 0 ; i
< count
; i
++ ) {
1007 if ( (pc
+ single_vertex_size
) >= gc
->bufEnd
) {
1008 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
1012 case GL_UNSIGNED_INT
:
1013 index
= (unsigned) (((GLuint
*) indices
)[i
]);
1015 case GL_UNSIGNED_SHORT
:
1016 index
= (unsigned) (((GLushort
*) indices
)[i
]);
1018 case GL_UNSIGNED_BYTE
:
1019 index
= (unsigned) (((GLubyte
*) indices
)[i
]);
1022 pc
= emit_element_none( pc
, arrays
, index
);
1025 if ( (pc
+ 4) >= gc
->bufEnd
) {
1026 pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
1029 (void) memcpy( pc
, end_cmd
, 4 );
1033 if ( gc
->pc
> gc
->limit
) {
1034 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
1042 emit_DrawElements_old( GLenum mode
, GLsizei count
, GLenum type
,
1043 const GLvoid
*indices
)
1045 __GLXcontext
*gc
= __glXGetCurrentContext();
1046 const __GLXattribute
* state
=
1047 (const __GLXattribute
*)(gc
->client_state_private
);
1048 struct array_state_vector
* arrays
= state
->array_state
;
1051 size_t elements_per_request
;
1052 unsigned total_requests
= 0;
1055 const GLuint
* ui_ptr
= (const GLuint
*) indices
;
1056 const GLushort
* us_ptr
= (const GLushort
*) indices
;
1057 const GLubyte
* ub_ptr
= (const GLubyte
*) indices
;
1060 pc
= emit_DrawArrays_header_old( gc
, arrays
, & elements_per_request
,
1061 & total_requests
, mode
, count
);
1064 /* Write the arrays.
1068 while ( count
> 0 ) {
1069 if ( count
< elements_per_request
) {
1070 elements_per_request
= count
;
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
);
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
);
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
);
1094 if ( total_requests
!= 0 ) {
1095 __glXSendLargeChunk( gc
, req
, total_requests
, gc
->pc
,
1101 count
-= elements_per_request
;
1105 assert( (total_requests
== 0) || ((req
- 1) == total_requests
) );
1107 if ( total_requests
== 0 ) {
1108 assert( pc
<= gc
->bufEnd
);
1111 if ( gc
->pc
> gc
->limit
) {
1112 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
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.
1123 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
1126 validate_mode(__GLXcontext
*gc
, GLenum mode
)
1133 case GL_TRIANGLE_STRIP
:
1134 case GL_TRIANGLE_FAN
:
1141 __glXSetError(gc
, GL_INVALID_ENUM
);
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.
1156 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
1159 validate_count(__GLXcontext
*gc
, GLsizei count
)
1162 __glXSetError(gc
, GL_INVALID_VALUE
);
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.
1175 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
1177 static GLboolean
validate_type(__GLXcontext
*gc
, GLenum type
)
1180 case GL_UNSIGNED_INT
:
1181 case GL_UNSIGNED_SHORT
:
1182 case GL_UNSIGNED_BYTE
:
1185 __glXSetError(gc
, GL_INVALID_ENUM
);
1191 void __indirect_glDrawArrays(GLenum mode
, GLint first
, GLsizei count
)
1193 __GLXcontext
*gc
= __glXGetCurrentContext();
1194 const __GLXattribute
* state
=
1195 (const __GLXattribute
*)(gc
->client_state_private
);
1196 struct array_state_vector
* arrays
= state
->array_state
;
1199 if ( validate_mode(gc
, mode
) && validate_count(gc
, count
) ) {
1200 if ( ! arrays
->array_info_cache_valid
) {
1201 fill_array_info_cache( arrays
);
1204 arrays
->DrawArrays(mode
, first
, count
);
1209 void __indirect_glArrayElement(GLint index
)
1211 __GLXcontext
*gc
= __glXGetCurrentContext();
1212 const __GLXattribute
* state
=
1213 (const __GLXattribute
*)(gc
->client_state_private
);
1214 struct array_state_vector
* arrays
= state
->array_state
;
1216 size_t single_vertex_size
;
1219 single_vertex_size
= calculate_single_vertex_size_none( arrays
);
1221 if ( (gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
1222 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
1225 gc
->pc
= emit_element_none( gc
->pc
, arrays
, index
);
1227 if ( gc
->pc
> gc
->limit
) {
1228 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
1233 void __indirect_glDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1234 const GLvoid
*indices
)
1236 __GLXcontext
*gc
= __glXGetCurrentContext();
1237 const __GLXattribute
* state
=
1238 (const __GLXattribute
*)(gc
->client_state_private
);
1239 struct array_state_vector
* arrays
= state
->array_state
;
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
);
1248 arrays
->DrawElements(mode
, count
, type
, indices
);
1253 void __indirect_glDrawRangeElements(GLenum mode
, GLuint start
, GLuint end
,
1254 GLsizei count
, GLenum type
,
1255 const GLvoid
*indices
)
1257 __GLXcontext
*gc
= __glXGetCurrentContext();
1258 const __GLXattribute
* state
=
1259 (const __GLXattribute
*)(gc
->client_state_private
);
1260 struct array_state_vector
* arrays
= state
->array_state
;
1263 if ( validate_mode(gc
, mode
) && validate_count(gc
, count
)
1264 && validate_type(gc
, type
) ) {
1266 __glXSetError(gc
, GL_INVALID_VALUE
);
1270 if ( ! arrays
->array_info_cache_valid
) {
1271 fill_array_info_cache( arrays
);
1274 arrays
->DrawElements(mode
, count
, type
, indices
);
1279 void __indirect_glMultiDrawArraysEXT(GLenum mode
, GLint
*first
, GLsizei
*count
,
1282 __GLXcontext
*gc
= __glXGetCurrentContext();
1283 const __GLXattribute
* state
=
1284 (const __GLXattribute
*)(gc
->client_state_private
);
1285 struct array_state_vector
* arrays
= state
->array_state
;
1289 if ( validate_mode(gc
, mode
) ) {
1290 if ( ! arrays
->array_info_cache_valid
) {
1291 fill_array_info_cache( arrays
);
1294 for ( i
= 0 ; i
< primcount
; i
++ ) {
1295 if ( validate_count( gc
, count
[i
] ) ) {
1296 arrays
->DrawArrays(mode
, first
[i
], count
[i
]);
1303 void __indirect_glMultiDrawElementsEXT(GLenum mode
, const GLsizei
*count
,
1304 GLenum type
, const GLvoid
** indices
,
1307 __GLXcontext
*gc
= __glXGetCurrentContext();
1308 const __GLXattribute
* state
=
1309 (const __GLXattribute
*)(gc
->client_state_private
);
1310 struct array_state_vector
* arrays
= state
->array_state
;
1314 if ( validate_mode(gc
, mode
) && validate_type(gc
, type
) ) {
1315 if ( ! arrays
->array_info_cache_valid
) {
1316 fill_array_info_cache( arrays
);
1319 for ( i
= 0 ; i
< primcount
; i
++ ) {
1320 if ( validate_count( gc
, count
[i
] ) ) {
1321 arrays
->DrawElements(mode
, count
[i
], type
, indices
[i
]);
1328 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, HDR_SIZE, OPCODE) \
1331 (a)->data_type = TYPE; \
1332 (a)->user_stride = STRIDE; \
1333 (a)->count = COUNT; \
1335 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1336 (a)->true_stride = (STRIDE == 0) \
1337 ? (a)->element_size : STRIDE; \
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; \
1345 void __indirect_glVertexPointer( GLint size
, GLenum type
, GLsizei stride
,
1346 const GLvoid
* pointer
)
1348 static const uint16_t short_ops
[5] = {
1349 0, 0, X_GLrop_Vertex2sv
, X_GLrop_Vertex3sv
, X_GLrop_Vertex4sv
1351 static const uint16_t int_ops
[5] = {
1352 0, 0, X_GLrop_Vertex2iv
, X_GLrop_Vertex3iv
, X_GLrop_Vertex4iv
1354 static const uint16_t float_ops
[5] = {
1355 0, 0, X_GLrop_Vertex2fv
, X_GLrop_Vertex3fv
, X_GLrop_Vertex4fv
1357 static const uint16_t double_ops
[5] = {
1358 0, 0, X_GLrop_Vertex2dv
, X_GLrop_Vertex3dv
, X_GLrop_Vertex4dv
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
;
1367 if (size
< 2 || size
> 4 || stride
< 0) {
1368 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1378 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1387 arrays
->array_info_cache_valid
= GL_FALSE
;
1392 void __indirect_glNormalPointer( GLenum type
, GLsizei stride
,
1393 const GLvoid
* pointer
)
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
;
1403 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1414 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1423 arrays
->array_info_cache_valid
= GL_FALSE
;
1428 void __indirect_glColorPointer( GLint size
, GLenum type
, GLsizei stride
,
1429 const GLvoid
* pointer
)
1431 static const uint16_t byte_ops
[5] = {
1432 0, 0, 0, X_GLrop_Color3bv
, X_GLrop_Color4bv
1434 static const uint16_t ubyte_ops
[5] = {
1435 0, 0, 0, X_GLrop_Color3ubv
, X_GLrop_Color4ubv
1437 static const uint16_t short_ops
[5] = {
1438 0, 0, 0, X_GLrop_Color3sv
, X_GLrop_Color4sv
1440 static const uint16_t ushort_ops
[5] = {
1441 0, 0, 0, X_GLrop_Color3usv
, X_GLrop_Color4usv
1443 static const uint16_t int_ops
[5] = {
1444 0, 0, 0, X_GLrop_Color3iv
, X_GLrop_Color4iv
1446 static const uint16_t uint_ops
[5] = {
1447 0, 0, 0, X_GLrop_Color3uiv
, X_GLrop_Color4uiv
1449 static const uint16_t float_ops
[5] = {
1450 0, 0, 0, X_GLrop_Color3fv
, X_GLrop_Color4fv
1452 static const uint16_t double_ops
[5] = {
1453 0, 0, 0, X_GLrop_Color3dv
, X_GLrop_Color4dv
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
;
1462 if (size
< 3 || size
> 4 || stride
< 0) {
1463 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1477 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1486 arrays
->array_info_cache_valid
= GL_FALSE
;
1491 void __indirect_glIndexPointer( GLenum type
, GLsizei stride
,
1492 const GLvoid
* pointer
)
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
;
1502 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1513 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1522 arrays
->array_info_cache_valid
= GL_FALSE
;
1527 void __indirect_glEdgeFlagPointer( GLsizei stride
, const GLvoid
* pointer
)
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
;
1536 __glXSetError(gc
, GL_INVALID_VALUE
);
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
);
1546 arrays
->array_info_cache_valid
= GL_FALSE
;
1551 void __indirect_glTexCoordPointer( GLint size
, GLenum type
, GLsizei stride
,
1552 const GLvoid
* pointer
)
1554 static const uint16_t short_ops
[5] = {
1555 0, X_GLrop_TexCoord1sv
, X_GLrop_TexCoord2sv
, X_GLrop_TexCoord3sv
, X_GLrop_TexCoord4sv
1557 static const uint16_t int_ops
[5] = {
1558 0, X_GLrop_TexCoord1iv
, X_GLrop_TexCoord2iv
, X_GLrop_TexCoord3iv
, X_GLrop_TexCoord4iv
1560 static const uint16_t float_ops
[5] = {
1561 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2fv
, X_GLrop_TexCoord3fv
, X_GLrop_TexCoord4fv
1563 static const uint16_t double_ops
[5] = {
1564 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2dv
, X_GLrop_TexCoord3dv
, X_GLrop_TexCoord4dv
1567 static const uint16_t mshort_ops
[5] = {
1568 0, X_GLrop_MultiTexCoord1svARB
, X_GLrop_MultiTexCoord2svARB
, X_GLrop_MultiTexCoord3svARB
, X_GLrop_MultiTexCoord4svARB
1570 static const uint16_t mint_ops
[5] = {
1571 0, X_GLrop_MultiTexCoord1ivARB
, X_GLrop_MultiTexCoord2ivARB
, X_GLrop_MultiTexCoord3ivARB
, X_GLrop_MultiTexCoord4ivARB
1573 static const uint16_t mfloat_ops
[5] = {
1574 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2fvARB
, X_GLrop_MultiTexCoord3fvARB
, X_GLrop_MultiTexCoord4fvARB
1576 static const uint16_t mdouble_ops
[5] = {
1577 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2dvARB
, X_GLrop_MultiTexCoord3dvARB
, X_GLrop_MultiTexCoord4dvARB
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
;
1589 if (size
< 1 || size
> 4 || stride
< 0) {
1590 __glXSetError(gc
, GL_INVALID_VALUE
);
1594 index
= arrays
->active_texture_unit
;
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;
1602 __glXSetError(gc
, GL_INVALID_ENUM
);
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;
1615 __glXSetError(gc
, GL_INVALID_ENUM
);
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
);
1627 arrays
->array_info_cache_valid
= GL_FALSE
;
1632 void __indirect_glSecondaryColorPointerEXT( GLint size
, GLenum type
, GLsizei stride
,
1633 const GLvoid
* pointer
)
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
;
1642 if (size
!= 3 || stride
< 0) {
1643 __glXSetError(gc
, GL_INVALID_VALUE
);
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;
1657 __glXSetError(gc
, GL_INVALID_ENUM
);
1661 a
= get_array_entry( arrays
, GL_SECONDARY_COLOR_ARRAY
, 0 );
1663 __glXSetError(gc
, GL_INVALID_OPERATION
);
1667 COMMON_ARRAY_DATA_INIT( a
, pointer
, type
, stride
, size
, 4, opcode
);
1670 arrays
->array_info_cache_valid
= GL_FALSE
;
1675 void __indirect_glFogCoordPointerEXT( GLenum type
, GLsizei stride
,
1676 const GLvoid
* pointer
)
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
;
1686 __glXSetError(gc
, GL_INVALID_VALUE
);
1691 case GL_FLOAT
: opcode
= 4124; break;
1692 case GL_DOUBLE
: opcode
= 4125; break;
1694 __glXSetError(gc
, GL_INVALID_ENUM
);
1698 a
= get_array_entry( arrays
, GL_FOG_COORD_ARRAY
, 0 );
1700 __glXSetError(gc
, GL_INVALID_OPERATION
);
1704 COMMON_ARRAY_DATA_INIT( a
, pointer
, type
, stride
, 1, 4, opcode
);
1707 arrays
->array_info_cache_valid
= GL_FALSE
;
1712 void __indirect_glVertexAttribPointerARB(GLuint index
, GLint size
,
1713 GLenum type
, GLboolean normalized
,
1715 const GLvoid
* pointer
)
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 };
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
;
1730 if ( (size
< 1) || (size
> 4) || (stride
< 0)
1731 || (index
> arrays
->num_vertex_program_attribs
) ){
1732 __glXSetError(gc
, GL_INVALID_VALUE
);
1736 if ( normalized
&& (type
!= GL_FLOAT
) && (type
!= GL_DOUBLE
)) {
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;
1745 __glXSetError(gc
, GL_INVALID_ENUM
);
1749 true_immediate_count
= 4;
1752 true_immediate_count
= size
;
1756 opcode
= X_GLrop_VertexAttrib4bvARB
;
1757 true_immediate_count
= 4;
1759 case GL_UNSIGNED_BYTE
:
1760 opcode
= X_GLrop_VertexAttrib4ubvARB
;
1761 true_immediate_count
= 4;
1764 opcode
= short_ops
[size
];
1766 case GL_UNSIGNED_SHORT
:
1767 opcode
= X_GLrop_VertexAttrib4usvARB
;
1768 true_immediate_count
= 4;
1771 opcode
= X_GLrop_VertexAttrib4ivARB
;
1772 true_immediate_count
= 4;
1774 case GL_UNSIGNED_INT
:
1775 opcode
= X_GLrop_VertexAttrib4uivARB
;
1776 true_immediate_count
= 4;
1779 opcode
= float_ops
[size
];
1782 opcode
= double_ops
[size
];
1785 __glXSetError(gc
, GL_INVALID_ENUM
);
1790 a
= get_array_entry( arrays
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, index
);
1792 __glXSetError(gc
, GL_INVALID_OPERATION
);
1796 COMMON_ARRAY_DATA_INIT( a
, pointer
, type
, stride
, size
, 8, opcode
);
1798 true_immediate_size
= __glXTypeSize(type
) * true_immediate_count
;
1799 ((uint16_t *) (a
)->header
)[0] = __GLX_PAD(a
->header_size
1800 + true_immediate_size
);
1803 arrays
->array_info_cache_valid
= GL_FALSE
;
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
1817 void __indirect_glVertexAttribPointerNV( GLuint index
, GLint size
,
1818 GLenum type
, GLsizei stride
,
1819 const GLvoid
* pointer
)
1821 __GLXcontext
*gc
= __glXGetCurrentContext();
1822 GLboolean normalized
= GL_FALSE
;
1826 case GL_UNSIGNED_BYTE
:
1828 __glXSetError(gc
, GL_INVALID_VALUE
);
1831 normalized
= GL_TRUE
;
1836 __indirect_glVertexAttribPointerARB(index
, size
, type
,
1841 __glXSetError(gc
, GL_INVALID_ENUM
);
1847 void __indirect_glClientActiveTextureARB(GLenum texture
)
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
;
1855 if ( (unit
< 0) || (unit
> arrays
->num_texture_units
) ) {
1856 __glXSetError(gc
, GL_INVALID_ENUM
);
1860 arrays
->active_texture_unit
= unit
;
1867 __glXSetArrayEnable( __GLXattribute
* state
,
1868 GLenum key
, unsigned index
, GLboolean enable
)
1870 struct array_state_vector
* arrays
= state
->array_state
;
1871 struct array_state
* a
;
1874 if ( key
== GL_TEXTURE_COORD_ARRAY
) {
1875 index
= arrays
->active_texture_unit
;
1878 a
= get_array_entry( arrays
, key
, index
);
1880 if ( (a
!= NULL
) && (a
->enabled
!= enable
) ) {
1881 a
->enabled
= enable
;
1882 arrays
->array_info_cache_valid
= GL_FALSE
;
1890 __glXArrayDisableAll( __GLXattribute
* state
)
1892 struct array_state_vector
* arrays
= state
->array_state
;
1896 for ( i
= 0 ; i
< arrays
->num_arrays
; i
++ ) {
1897 arrays
->arrays
[i
].enabled
= GL_FALSE
;
1900 arrays
->array_info_cache_valid
= GL_FALSE
;
1907 __glXGetArrayEnable( const __GLXattribute
* const state
,
1908 GLenum key
, unsigned index
, GLintptr
* dest
)
1910 const struct array_state_vector
* arrays
= state
->array_state
;
1911 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1915 *dest
= (GLintptr
) a
->enabled
;
1925 __glXGetArrayType( const __GLXattribute
* const state
,
1926 GLenum key
, unsigned index
, GLintptr
* dest
)
1928 const struct array_state_vector
* arrays
= state
->array_state
;
1929 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1933 *dest
= (GLintptr
) a
->enabled
;
1943 __glXGetArraySize( const __GLXattribute
* const state
,
1944 GLenum key
, unsigned index
, GLintptr
* dest
)
1946 const struct array_state_vector
* arrays
= state
->array_state
;
1947 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1951 *dest
= (GLintptr
) a
->count
;
1961 __glXGetArrayStride( const __GLXattribute
* const state
,
1962 GLenum key
, unsigned index
, GLintptr
* dest
)
1964 const struct array_state_vector
* arrays
= state
->array_state
;
1965 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1969 *dest
= (GLintptr
) a
->user_stride
;
1979 __glXGetArrayPointer( const __GLXattribute
* const state
,
1980 GLenum key
, unsigned index
, void ** dest
)
1982 const struct array_state_vector
* arrays
= state
->array_state
;
1983 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
1988 *dest
= (void *) (a
->data
);
1998 __glXGetArrayNormalized( const __GLXattribute
* const state
,
1999 GLenum key
, unsigned index
, GLintptr
* dest
)
2001 const struct array_state_vector
* arrays
= state
->array_state
;
2002 const struct array_state
* a
= get_array_entry( (struct array_state_vector
*) arrays
,
2007 *dest
= (GLintptr
) a
->normalized
;
2017 __glXGetActiveTextureUnit( const __GLXattribute
* const state
)
2019 return state
->array_state
->active_texture_unit
;
2024 __glXPushArrayState( __GLXattribute
* state
)
2026 struct array_state_vector
* arrays
= state
->array_state
;
2027 struct array_stack_state
* stack
= & arrays
->stack
[ (arrays
->stack_index
* arrays
->num_arrays
)];
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
;
2040 arrays
->active_texture_unit_stack
[ arrays
->stack_index
] =
2041 arrays
->active_texture_unit
;
2043 arrays
->stack_index
++;
2048 __glXPopArrayState( __GLXattribute
* state
)
2050 struct array_state_vector
* arrays
= state
->array_state
;
2051 struct array_stack_state
* stack
;
2055 arrays
->stack_index
--;
2056 stack
= & arrays
->stack
[ (arrays
->stack_index
* arrays
->num_arrays
) ];
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
,
2065 case GL_COLOR_ARRAY
:
2066 __indirect_glColorPointer( stack
[i
].count
,
2068 stack
[i
].user_stride
,
2071 case GL_INDEX_ARRAY
:
2072 __indirect_glIndexPointer( stack
[i
].data_type
,
2073 stack
[i
].user_stride
,
2076 case GL_EDGE_FLAG_ARRAY
:
2077 __indirect_glEdgeFlagPointer( stack
[i
].user_stride
,
2080 case GL_TEXTURE_COORD_ARRAY
:
2081 arrays
->active_texture_unit
= stack
[i
].index
;
2082 __indirect_glTexCoordPointer( stack
[i
].count
,
2084 stack
[i
].user_stride
,
2087 case GL_SECONDARY_COLOR_ARRAY
:
2088 __indirect_glSecondaryColorPointerEXT( stack
[i
].count
,
2090 stack
[i
].user_stride
,
2093 case GL_FOG_COORDINATE_ARRAY
:
2094 __indirect_glFogCoordPointerEXT( stack
[i
].data_type
,
2095 stack
[i
].user_stride
,
2101 __glXSetArrayEnable( state
, stack
[i
].key
, stack
[i
].index
,
2105 arrays
->active_texture_unit
= arrays
->active_texture_unit_stack
[ arrays
->stack_index
];