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"
35 #include "indirect_vertex_array_priv.h"
37 #define __GLX_PAD(n) (((n)+3) & ~3)
40 * \file indirect_vertex_array.c
41 * Implement GLX protocol for vertex arrays and vertex buffer objects.
43 * The most important function in this fill is \c fill_array_info_cache.
44 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
45 * in the DrawArrays protocol. Certain operations, such as enabling or
46 * disabling an array, can invalidate this cache. \c fill_array_info_cache
47 * fills-in this data. Additionally, it examines the enabled state and
48 * other factors to determine what "version" of DrawArrays protocoal can be
51 * Current, only two versions of DrawArrays protocol are implemented. The
52 * first version is the "none" protocol. This is the fallback when the
53 * server does not support GL 1.1 / EXT_vertex_arrays. It is implemented
54 * by sending batches of immediate mode commands that are equivalent to the
55 * DrawArrays protocol.
57 * The other protocol that is currently implemented is the "old" protocol.
58 * This is the GL 1.1 DrawArrays protocol. The only difference between GL
59 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
60 * This protocol is called "old" because the ARB is in the process of
61 * defining a new protocol, which will probably be called wither "new" or
62 * "vbo", to support multiple texture coordinate arrays, generic attributes,
63 * and vertex buffer objects.
65 * \author Ian Romanick <ian.d.romanick@intel.com>
68 static void emit_DrawArrays_none(GLenum mode
, GLint first
, GLsizei count
);
69 static void emit_DrawArrays_old(GLenum mode
, GLint first
, GLsizei count
);
71 static void emit_DrawElements_none(GLenum mode
, GLsizei count
, GLenum type
,
72 const GLvoid
* indices
);
73 static void emit_DrawElements_old(GLenum mode
, GLsizei count
, GLenum type
,
74 const GLvoid
* indices
);
77 static GLubyte
*emit_element_none(GLubyte
* dst
,
78 const struct array_state_vector
*arrays
,
80 static GLubyte
*emit_element_old(GLubyte
* dst
,
81 const struct array_state_vector
*arrays
,
83 static struct array_state
*get_array_entry(const struct array_state_vector
86 static void fill_array_info_cache(struct array_state_vector
*arrays
);
87 static GLboolean
validate_mode(struct glx_context
* gc
, GLenum mode
);
88 static GLboolean
validate_count(struct glx_context
* gc
, GLsizei count
);
89 static GLboolean
validate_type(struct glx_context
* gc
, GLenum type
);
93 * Table of sizes, in bytes, of a GL types. All of the type enums are be in
94 * the range 0x1400 - 0x140F. That includes types added by extensions (i.e.,
95 * \c GL_HALF_FLOAT_NV). This elements of this table correspond to the
96 * type enums masked with 0x0f.
99 * \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES,
100 * \c GL_3_BYTES, or \c GL_4_BYTES.
102 const GLuint __glXTypeSize_table
[16] = {
103 1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
108 * Free the per-context array state that was allocated with
109 * __glXInitVertexArrayState().
112 __glXFreeVertexArrayState(struct glx_context
* gc
)
114 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
115 struct array_state_vector
*arrays
= state
->array_state
;
119 arrays
->stack
= NULL
;
120 free(arrays
->arrays
);
121 arrays
->arrays
= NULL
;
123 state
->array_state
= NULL
;
129 * Initialize vertex array state of a GLX context.
131 * \param gc GLX context whose vertex array state is to be initialized.
134 * This function may only be called after struct glx_context::gl_extension_bits,
135 * struct glx_context::server_minor, and __GLXcontext::server_major have been
136 * initialized. These values are used to determine what vertex arrays are
140 __glXInitVertexArrayState(struct glx_context
* gc
)
142 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
143 struct array_state_vector
*arrays
;
145 unsigned array_count
;
146 int texture_units
= 1, vertex_program_attribs
= 0;
149 GLboolean got_fog
= GL_FALSE
;
150 GLboolean got_secondary_color
= GL_FALSE
;
153 arrays
= calloc(1, sizeof(struct array_state_vector
));
155 if (arrays
== NULL
) {
156 __glXSetError(gc
, GL_OUT_OF_MEMORY
);
160 arrays
->old_DrawArrays_possible
= !state
->NoDrawArraysProtocol
;
161 arrays
->new_DrawArrays_possible
= GL_FALSE
;
162 arrays
->DrawArrays
= NULL
;
164 arrays
->active_texture_unit
= 0;
167 /* Determine how many arrays are actually needed. Only arrays that
168 * are supported by the server are create. For example, if the server
169 * supports only 2 texture units, then only 2 texture coordinate arrays
172 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
173 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
174 * GL_EDGE_FLAG_ARRAY are supported.
179 if (__glExtensionBitIsEnabled(gc
, GL_EXT_fog_coord_bit
)
180 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4)) {
185 if (__glExtensionBitIsEnabled(gc
, GL_EXT_secondary_color_bit
)
186 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4)) {
187 got_secondary_color
= GL_TRUE
;
191 if (__glExtensionBitIsEnabled(gc
, GL_ARB_multitexture_bit
)
192 || (gc
->server_major
> 1) || (gc
->server_minor
>= 3)) {
193 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS
, &texture_units
);
196 if (__glExtensionBitIsEnabled(gc
, GL_ARB_vertex_program_bit
)) {
197 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
,
198 GL_MAX_PROGRAM_ATTRIBS_ARB
,
199 &vertex_program_attribs
);
202 arrays
->num_texture_units
= texture_units
;
203 arrays
->num_vertex_program_attribs
= vertex_program_attribs
;
204 array_count
+= texture_units
+ vertex_program_attribs
;
205 arrays
->num_arrays
= array_count
;
206 arrays
->arrays
= calloc(array_count
, sizeof(struct array_state
));
208 if (arrays
->arrays
== NULL
) {
210 __glXSetError(gc
, GL_OUT_OF_MEMORY
);
214 arrays
->arrays
[0].data_type
= GL_FLOAT
;
215 arrays
->arrays
[0].count
= 3;
216 arrays
->arrays
[0].key
= GL_NORMAL_ARRAY
;
217 arrays
->arrays
[0].normalized
= GL_TRUE
;
218 arrays
->arrays
[0].old_DrawArrays_possible
= GL_TRUE
;
220 arrays
->arrays
[1].data_type
= GL_FLOAT
;
221 arrays
->arrays
[1].count
= 4;
222 arrays
->arrays
[1].key
= GL_COLOR_ARRAY
;
223 arrays
->arrays
[1].normalized
= GL_TRUE
;
224 arrays
->arrays
[1].old_DrawArrays_possible
= GL_TRUE
;
226 arrays
->arrays
[2].data_type
= GL_FLOAT
;
227 arrays
->arrays
[2].count
= 1;
228 arrays
->arrays
[2].key
= GL_INDEX_ARRAY
;
229 arrays
->arrays
[2].old_DrawArrays_possible
= GL_TRUE
;
231 arrays
->arrays
[3].data_type
= GL_UNSIGNED_BYTE
;
232 arrays
->arrays
[3].count
= 1;
233 arrays
->arrays
[3].key
= GL_EDGE_FLAG_ARRAY
;
234 arrays
->arrays
[3].old_DrawArrays_possible
= GL_TRUE
;
236 for (i
= 0; i
< texture_units
; i
++) {
237 arrays
->arrays
[4 + i
].data_type
= GL_FLOAT
;
238 arrays
->arrays
[4 + i
].count
= 4;
239 arrays
->arrays
[4 + i
].key
= GL_TEXTURE_COORD_ARRAY
;
241 arrays
->arrays
[4 + i
].old_DrawArrays_possible
= (i
== 0);
242 arrays
->arrays
[4 + i
].index
= i
;
244 arrays
->arrays
[4 + i
].header
[1] = i
+ GL_TEXTURE0
;
247 i
= 4 + texture_units
;
250 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
251 arrays
->arrays
[i
].count
= 1;
252 arrays
->arrays
[i
].key
= GL_FOG_COORDINATE_ARRAY
;
253 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
257 if (got_secondary_color
) {
258 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
259 arrays
->arrays
[i
].count
= 3;
260 arrays
->arrays
[i
].key
= GL_SECONDARY_COLOR_ARRAY
;
261 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
262 arrays
->arrays
[i
].normalized
= GL_TRUE
;
267 for (j
= 0; j
< vertex_program_attribs
; j
++) {
268 const unsigned idx
= (vertex_program_attribs
- (j
+ 1));
271 arrays
->arrays
[idx
+ i
].data_type
= GL_FLOAT
;
272 arrays
->arrays
[idx
+ i
].count
= 4;
273 arrays
->arrays
[idx
+ i
].key
= GL_VERTEX_ATTRIB_ARRAY_POINTER
;
275 arrays
->arrays
[idx
+ i
].old_DrawArrays_possible
= 0;
276 arrays
->arrays
[idx
+ i
].index
= idx
;
278 arrays
->arrays
[idx
+ i
].header
[1] = idx
;
281 i
+= vertex_program_attribs
;
284 /* Vertex array *must* be last becuase of the way that
285 * emit_DrawArrays_none works.
288 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
289 arrays
->arrays
[i
].count
= 4;
290 arrays
->arrays
[i
].key
= GL_VERTEX_ARRAY
;
291 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
293 assert((i
+ 1) == arrays
->num_arrays
);
295 arrays
->stack_index
= 0;
296 arrays
->stack
= malloc(sizeof(struct array_stack_state
)
298 * __GL_CLIENT_ATTRIB_STACK_DEPTH
);
300 if (arrays
->stack
== NULL
) {
301 free(arrays
->arrays
);
303 __glXSetError(gc
, GL_OUT_OF_MEMORY
);
307 /* Everything went ok so we put vertex array state in place
310 state
->array_state
= arrays
;
315 * Calculate the size of a single vertex for the "none" protocol. This is
316 * essentially the size of all the immediate-mode commands required to
317 * implement the enabled vertex arrays.
320 calculate_single_vertex_size_none(const struct array_state_vector
*arrays
)
322 size_t single_vertex_size
= 0;
326 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
327 if (arrays
->arrays
[i
].enabled
) {
328 single_vertex_size
+= ((uint16_t *) arrays
->arrays
[i
].header
)[0];
332 return single_vertex_size
;
337 * Emit a single element using non-DrawArrays protocol.
340 emit_element_none(GLubyte
* dst
,
341 const struct array_state_vector
* arrays
, unsigned index
)
346 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
347 if (arrays
->arrays
[i
].enabled
) {
348 const size_t offset
= index
* arrays
->arrays
[i
].true_stride
;
350 /* The generic attributes can have more data than is in the
351 * elements. This is because a vertex array can be a 2 element,
352 * normalized, unsigned short, but the "closest" immediate mode
353 * protocol is for a 4Nus. Since the sizes are small, the
354 * performance impact on modern processors should be negligible.
356 (void) memset(dst
, 0, ((uint16_t *) arrays
->arrays
[i
].header
)[0]);
358 (void) memcpy(dst
, arrays
->arrays
[i
].header
,
359 arrays
->arrays
[i
].header_size
);
361 dst
+= arrays
->arrays
[i
].header_size
;
363 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
364 arrays
->arrays
[i
].element_size
);
366 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
375 * Emit a single element using "old" DrawArrays protocol from
376 * EXT_vertex_arrays / OpenGL 1.1.
379 emit_element_old(GLubyte
* dst
,
380 const struct array_state_vector
* arrays
, unsigned index
)
385 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
386 if (arrays
->arrays
[i
].enabled
) {
387 const size_t offset
= index
* arrays
->arrays
[i
].true_stride
;
389 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
390 arrays
->arrays
[i
].element_size
);
392 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
401 get_array_entry(const struct array_state_vector
*arrays
,
402 GLenum key
, unsigned index
)
406 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
407 if ((arrays
->arrays
[i
].key
== key
)
408 && (arrays
->arrays
[i
].index
== index
)) {
409 return &arrays
->arrays
[i
];
418 allocate_array_info_cache(struct array_state_vector
*arrays
,
419 size_t required_size
)
421 #define MAX_HEADER_SIZE 20
422 if (arrays
->array_info_cache_buffer_size
< required_size
) {
423 GLubyte
*temp
= realloc(arrays
->array_info_cache_base
,
424 required_size
+ MAX_HEADER_SIZE
);
430 arrays
->array_info_cache_base
= temp
;
431 arrays
->array_info_cache
= temp
+ MAX_HEADER_SIZE
;
432 arrays
->array_info_cache_buffer_size
= required_size
;
435 arrays
->array_info_cache_size
= required_size
;
443 fill_array_info_cache(struct array_state_vector
*arrays
)
445 GLboolean old_DrawArrays_possible
;
449 /* Determine how many arrays are enabled.
452 arrays
->enabled_client_array_count
= 0;
453 old_DrawArrays_possible
= arrays
->old_DrawArrays_possible
;
454 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
455 if (arrays
->arrays
[i
].enabled
) {
456 arrays
->enabled_client_array_count
++;
457 old_DrawArrays_possible
&= arrays
->arrays
[i
].old_DrawArrays_possible
;
461 if (arrays
->new_DrawArrays_possible
) {
462 assert(!arrays
->new_DrawArrays_possible
);
464 else if (old_DrawArrays_possible
) {
465 const size_t required_size
= arrays
->enabled_client_array_count
* 12;
469 if (!allocate_array_info_cache(arrays
, required_size
)) {
474 info
= (uint32_t *) arrays
->array_info_cache
;
475 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
476 if (arrays
->arrays
[i
].enabled
) {
477 *(info
++) = arrays
->arrays
[i
].data_type
;
478 *(info
++) = arrays
->arrays
[i
].count
;
479 *(info
++) = arrays
->arrays
[i
].key
;
483 arrays
->DrawArrays
= emit_DrawArrays_old
;
484 arrays
->DrawElements
= emit_DrawElements_old
;
487 arrays
->DrawArrays
= emit_DrawArrays_none
;
488 arrays
->DrawElements
= emit_DrawElements_none
;
491 arrays
->array_info_cache_valid
= GL_TRUE
;
496 * Emit a \c glDrawArrays command using the "none" protocol. That is,
497 * emit immediate-mode commands that are equivalent to the requiested
498 * \c glDrawArrays command. This is used with servers that don't support
499 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
500 * vertex state is enabled that is not compatible with that protocol.
503 emit_DrawArrays_none(GLenum mode
, GLint first
, GLsizei count
)
505 struct glx_context
*gc
= __glXGetCurrentContext();
506 const __GLXattribute
*state
=
507 (const __GLXattribute
*) (gc
->client_state_private
);
508 struct array_state_vector
*arrays
= state
->array_state
;
510 size_t single_vertex_size
;
513 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
514 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
517 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
521 (void) memcpy(pc
, begin_cmd
, 4);
522 *(int *) (pc
+ 4) = mode
;
526 for (i
= 0; i
< count
; i
++) {
527 if ((pc
+ single_vertex_size
) >= gc
->bufEnd
) {
528 pc
= __glXFlushRenderBuffer(gc
, pc
);
531 pc
= emit_element_none(pc
, arrays
, first
+ i
);
534 if ((pc
+ 4) >= gc
->bufEnd
) {
535 pc
= __glXFlushRenderBuffer(gc
, pc
);
538 (void) memcpy(pc
, end_cmd
, 4);
542 if (gc
->pc
> gc
->limit
) {
543 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
549 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
552 * \param gc GLX context.
553 * \param arrays Array state.
554 * \param elements_per_request Location to store the number of elements that
555 * can fit in a single Render / RenderLarge
557 * \param total_request Total number of requests for a RenderLarge
558 * command. If a Render command is used, this
560 * \param mode Drawing mode.
561 * \param count Number of vertices.
564 * A pointer to the buffer for array data.
567 emit_DrawArrays_header_old(struct glx_context
* gc
,
568 struct array_state_vector
*arrays
,
569 size_t * elements_per_request
,
570 unsigned int *total_requests
,
571 GLenum mode
, GLsizei count
)
574 size_t single_vertex_size
;
575 const unsigned header_size
= 16;
580 /* Determine the size of the whole command. This includes the header,
581 * the ARRAY_INFO data and the array data. Once this size is calculated,
582 * it will be known whether a Render or RenderLarge command is needed.
585 single_vertex_size
= 0;
586 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
587 if (arrays
->arrays
[i
].enabled
) {
588 single_vertex_size
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
592 command_size
= arrays
->array_info_cache_size
+ header_size
593 + (single_vertex_size
* count
);
596 /* Write the header for either a Render command or a RenderLarge
597 * command. After the header is written, write the ARRAY_INFO data.
600 if (command_size
> gc
->maxSmallRenderCommandSize
) {
601 /* maxSize is the maximum amount of data can be stuffed into a single
602 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
603 * packet size minus sz_xGLXRenderReq.
605 const size_t maxSize
= (gc
->bufSize
+ sz_xGLXRenderReq
)
606 - sz_xGLXRenderLargeReq
;
607 unsigned vertex_requests
;
610 /* Calculate the number of data packets that will be required to send
611 * the whole command. To do this, the number of verticies that
612 * will fit in a single buffer must be calculated.
614 * The important value here is elements_per_request. This is the
615 * number of complete array elements that will fit in a single
616 * buffer. There may be some wasted space at the end of the buffer,
617 * but splitting elements across buffer boundries would be painful.
620 elements_per_request
[0] = maxSize
/ single_vertex_size
;
622 vertex_requests
= (count
+ elements_per_request
[0] - 1)
623 / elements_per_request
[0];
625 *total_requests
= vertex_requests
+ 1;
628 __glXFlushRenderBuffer(gc
, gc
->pc
);
632 pc
= ((GLubyte
*) arrays
->array_info_cache
) - (header_size
+ 4);
633 *(uint32_t *) (pc
+ 0) = command_size
;
634 *(uint32_t *) (pc
+ 4) = X_GLrop_DrawArrays
;
635 *(uint32_t *) (pc
+ 8) = count
;
636 *(uint32_t *) (pc
+ 12) = arrays
->enabled_client_array_count
;
637 *(uint32_t *) (pc
+ 16) = mode
;
639 __glXSendLargeChunk(gc
, 1, *total_requests
, pc
,
640 header_size
+ 4 + arrays
->array_info_cache_size
);
645 if ((gc
->pc
+ command_size
) >= gc
->bufEnd
) {
646 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
650 *(uint16_t *) (pc
+ 0) = command_size
;
651 *(uint16_t *) (pc
+ 2) = X_GLrop_DrawArrays
;
652 *(uint32_t *) (pc
+ 4) = count
;
653 *(uint32_t *) (pc
+ 8) = arrays
->enabled_client_array_count
;
654 *(uint32_t *) (pc
+ 12) = mode
;
658 (void) memcpy(pc
, arrays
->array_info_cache
,
659 arrays
->array_info_cache_size
);
660 pc
+= arrays
->array_info_cache_size
;
662 *elements_per_request
= count
;
674 emit_DrawArrays_old(GLenum mode
, GLint first
, GLsizei count
)
676 struct glx_context
*gc
= __glXGetCurrentContext();
677 const __GLXattribute
*state
=
678 (const __GLXattribute
*) (gc
->client_state_private
);
679 struct array_state_vector
*arrays
= state
->array_state
;
682 size_t elements_per_request
;
683 unsigned total_requests
= 0;
685 size_t total_sent
= 0;
688 pc
= emit_DrawArrays_header_old(gc
, arrays
, &elements_per_request
,
689 &total_requests
, mode
, count
);
695 if (total_requests
== 0) {
696 assert(elements_per_request
>= count
);
698 for (i
= 0; i
< count
; i
++) {
699 pc
= emit_element_old(pc
, arrays
, i
+ first
);
702 assert(pc
<= gc
->bufEnd
);
705 if (gc
->pc
> gc
->limit
) {
706 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
713 for (req
= 2; req
<= total_requests
; req
++) {
714 if (count
< elements_per_request
) {
715 elements_per_request
= count
;
719 for (i
= 0; i
< elements_per_request
; i
++) {
720 pc
= emit_element_old(pc
, arrays
, i
+ first
);
723 first
+= elements_per_request
;
725 total_sent
+= (size_t) (pc
- gc
->pc
);
726 __glXSendLargeChunk(gc
, req
, total_requests
, gc
->pc
, pc
- gc
->pc
);
728 count
-= elements_per_request
;
735 emit_DrawElements_none(GLenum mode
, GLsizei count
, GLenum type
,
736 const GLvoid
* indices
)
738 struct glx_context
*gc
= __glXGetCurrentContext();
739 const __GLXattribute
*state
=
740 (const __GLXattribute
*) (gc
->client_state_private
);
741 struct array_state_vector
*arrays
= state
->array_state
;
742 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
743 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
746 size_t single_vertex_size
;
750 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
753 if ((gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
754 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
759 (void) memcpy(pc
, begin_cmd
, 4);
760 *(int *) (pc
+ 4) = mode
;
764 for (i
= 0; i
< count
; i
++) {
767 if ((pc
+ single_vertex_size
) >= gc
->bufEnd
) {
768 pc
= __glXFlushRenderBuffer(gc
, pc
);
772 case GL_UNSIGNED_INT
:
773 index
= (unsigned) (((GLuint
*) indices
)[i
]);
775 case GL_UNSIGNED_SHORT
:
776 index
= (unsigned) (((GLushort
*) indices
)[i
]);
778 case GL_UNSIGNED_BYTE
:
779 index
= (unsigned) (((GLubyte
*) indices
)[i
]);
782 pc
= emit_element_none(pc
, arrays
, index
);
785 if ((pc
+ 4) >= gc
->bufEnd
) {
786 pc
= __glXFlushRenderBuffer(gc
, pc
);
789 (void) memcpy(pc
, end_cmd
, 4);
793 if (gc
->pc
> gc
->limit
) {
794 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
802 emit_DrawElements_old(GLenum mode
, GLsizei count
, GLenum type
,
803 const GLvoid
* indices
)
805 struct glx_context
*gc
= __glXGetCurrentContext();
806 const __GLXattribute
*state
=
807 (const __GLXattribute
*) (gc
->client_state_private
);
808 struct array_state_vector
*arrays
= state
->array_state
;
811 size_t elements_per_request
;
812 unsigned total_requests
= 0;
815 unsigned req_element
= 0;
818 pc
= emit_DrawArrays_header_old(gc
, arrays
, &elements_per_request
,
819 &total_requests
, mode
, count
);
827 if (count
< elements_per_request
) {
828 elements_per_request
= count
;
832 case GL_UNSIGNED_INT
:{
833 const GLuint
*ui_ptr
= (const GLuint
*) indices
+ req_element
;
835 for (i
= 0; i
< elements_per_request
; i
++) {
836 const GLint index
= (GLint
) * (ui_ptr
++);
837 pc
= emit_element_old(pc
, arrays
, index
);
841 case GL_UNSIGNED_SHORT
:{
842 const GLushort
*us_ptr
= (const GLushort
*) indices
+ req_element
;
844 for (i
= 0; i
< elements_per_request
; i
++) {
845 const GLint index
= (GLint
) * (us_ptr
++);
846 pc
= emit_element_old(pc
, arrays
, index
);
850 case GL_UNSIGNED_BYTE
:{
851 const GLubyte
*ub_ptr
= (const GLubyte
*) indices
+ req_element
;
853 for (i
= 0; i
< elements_per_request
; i
++) {
854 const GLint index
= (GLint
) * (ub_ptr
++);
855 pc
= emit_element_old(pc
, arrays
, index
);
861 if (total_requests
!= 0) {
862 __glXSendLargeChunk(gc
, req
, total_requests
, gc
->pc
, pc
- gc
->pc
);
867 count
-= elements_per_request
;
868 req_element
+= elements_per_request
;
872 assert((total_requests
== 0) || ((req
- 1) == total_requests
));
874 if (total_requests
== 0) {
875 assert(pc
<= gc
->bufEnd
);
878 if (gc
->pc
> gc
->limit
) {
879 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
886 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
887 * If it is not valid, then an error code is set in the GLX context.
890 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
893 validate_mode(struct glx_context
* gc
, GLenum mode
)
900 case GL_TRIANGLE_STRIP
:
901 case GL_TRIANGLE_FAN
:
908 __glXSetError(gc
, GL_INVALID_ENUM
);
917 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
918 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
919 * being set. A value of zero will not result in an error being set, but
920 * will result in \c GL_FALSE being returned.
923 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
926 validate_count(struct glx_context
* gc
, GLsizei count
)
929 __glXSetError(gc
, GL_INVALID_VALUE
);
937 * Validate that the \c type parameter to \c glDrawElements, et. al. is
938 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
939 * \c GL_UNSIGNED_INT are valid.
942 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
945 validate_type(struct glx_context
* gc
, GLenum type
)
948 case GL_UNSIGNED_INT
:
949 case GL_UNSIGNED_SHORT
:
950 case GL_UNSIGNED_BYTE
:
953 __glXSetError(gc
, GL_INVALID_ENUM
);
960 __indirect_glDrawArrays(GLenum mode
, GLint first
, GLsizei count
)
962 struct glx_context
*gc
= __glXGetCurrentContext();
963 const __GLXattribute
*state
=
964 (const __GLXattribute
*) (gc
->client_state_private
);
965 struct array_state_vector
*arrays
= state
->array_state
;
968 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)) {
969 if (!arrays
->array_info_cache_valid
) {
970 fill_array_info_cache(arrays
);
973 arrays
->DrawArrays(mode
, first
, count
);
979 __indirect_glArrayElement(GLint index
)
981 struct glx_context
*gc
= __glXGetCurrentContext();
982 const __GLXattribute
*state
=
983 (const __GLXattribute
*) (gc
->client_state_private
);
984 struct array_state_vector
*arrays
= state
->array_state
;
986 size_t single_vertex_size
;
989 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
991 if ((gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
992 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
995 gc
->pc
= emit_element_none(gc
->pc
, arrays
, index
);
997 if (gc
->pc
> gc
->limit
) {
998 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
1004 __indirect_glDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1005 const GLvoid
* indices
)
1007 struct glx_context
*gc
= __glXGetCurrentContext();
1008 const __GLXattribute
*state
=
1009 (const __GLXattribute
*) (gc
->client_state_private
);
1010 struct array_state_vector
*arrays
= state
->array_state
;
1013 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)
1014 && validate_type(gc
, type
)) {
1015 if (!arrays
->array_info_cache_valid
) {
1016 fill_array_info_cache(arrays
);
1019 arrays
->DrawElements(mode
, count
, type
, indices
);
1025 __indirect_glDrawRangeElements(GLenum mode
, GLuint start
, GLuint end
,
1026 GLsizei count
, GLenum type
,
1027 const GLvoid
* indices
)
1029 struct glx_context
*gc
= __glXGetCurrentContext();
1030 const __GLXattribute
*state
=
1031 (const __GLXattribute
*) (gc
->client_state_private
);
1032 struct array_state_vector
*arrays
= state
->array_state
;
1035 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)
1036 && validate_type(gc
, type
)) {
1038 __glXSetError(gc
, GL_INVALID_VALUE
);
1042 if (!arrays
->array_info_cache_valid
) {
1043 fill_array_info_cache(arrays
);
1046 arrays
->DrawElements(mode
, count
, type
, indices
);
1052 __indirect_glMultiDrawArrays(GLenum mode
, const GLint
*first
,
1053 const GLsizei
*count
, GLsizei primcount
)
1055 struct glx_context
*gc
= __glXGetCurrentContext();
1056 const __GLXattribute
*state
=
1057 (const __GLXattribute
*) (gc
->client_state_private
);
1058 struct array_state_vector
*arrays
= state
->array_state
;
1062 if (validate_mode(gc
, mode
)) {
1063 if (!arrays
->array_info_cache_valid
) {
1064 fill_array_info_cache(arrays
);
1067 for (i
= 0; i
< primcount
; i
++) {
1068 if (validate_count(gc
, count
[i
])) {
1069 arrays
->DrawArrays(mode
, first
[i
], count
[i
]);
1077 __indirect_glMultiDrawElementsEXT(GLenum mode
, const GLsizei
* count
,
1078 GLenum type
, const GLvoid
* const * indices
,
1081 struct glx_context
*gc
= __glXGetCurrentContext();
1082 const __GLXattribute
*state
=
1083 (const __GLXattribute
*) (gc
->client_state_private
);
1084 struct array_state_vector
*arrays
= state
->array_state
;
1088 if (validate_mode(gc
, mode
) && validate_type(gc
, type
)) {
1089 if (!arrays
->array_info_cache_valid
) {
1090 fill_array_info_cache(arrays
);
1093 for (i
= 0; i
< primcount
; i
++) {
1094 if (validate_count(gc
, count
[i
])) {
1095 arrays
->DrawElements(mode
, count
[i
], type
, indices
[i
]);
1102 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1105 (a)->data_type = TYPE; \
1106 (a)->user_stride = STRIDE; \
1107 (a)->count = COUNT; \
1108 (a)->normalized = NORMALIZED; \
1110 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1111 (a)->true_stride = (STRIDE == 0) \
1112 ? (a)->element_size : STRIDE; \
1114 (a)->header_size = HDR_SIZE; \
1115 ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1116 ((uint16_t *) (a)->header)[1] = OPCODE; \
1121 __indirect_glVertexPointer(GLint size
, GLenum type
, GLsizei stride
,
1122 const GLvoid
* pointer
)
1124 static const uint16_t short_ops
[5] = {
1125 0, 0, X_GLrop_Vertex2sv
, X_GLrop_Vertex3sv
, X_GLrop_Vertex4sv
1127 static const uint16_t int_ops
[5] = {
1128 0, 0, X_GLrop_Vertex2iv
, X_GLrop_Vertex3iv
, X_GLrop_Vertex4iv
1130 static const uint16_t float_ops
[5] = {
1131 0, 0, X_GLrop_Vertex2fv
, X_GLrop_Vertex3fv
, X_GLrop_Vertex4fv
1133 static const uint16_t double_ops
[5] = {
1134 0, 0, X_GLrop_Vertex2dv
, X_GLrop_Vertex3dv
, X_GLrop_Vertex4dv
1137 struct glx_context
*gc
= __glXGetCurrentContext();
1138 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1139 struct array_state_vector
*arrays
= state
->array_state
;
1140 struct array_state
*a
;
1143 if (size
< 2 || size
> 4 || stride
< 0) {
1144 __glXSetError(gc
, GL_INVALID_VALUE
);
1150 opcode
= short_ops
[size
];
1153 opcode
= int_ops
[size
];
1156 opcode
= float_ops
[size
];
1159 opcode
= double_ops
[size
];
1162 __glXSetError(gc
, GL_INVALID_ENUM
);
1166 a
= get_array_entry(arrays
, GL_VERTEX_ARRAY
, 0);
1168 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_FALSE
, 4,
1172 arrays
->array_info_cache_valid
= GL_FALSE
;
1178 __indirect_glNormalPointer(GLenum type
, GLsizei stride
,
1179 const GLvoid
* pointer
)
1182 struct glx_context
*gc
= __glXGetCurrentContext();
1183 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1184 struct array_state_vector
*arrays
= state
->array_state
;
1185 struct array_state
*a
;
1189 __glXSetError(gc
, GL_INVALID_VALUE
);
1195 opcode
= X_GLrop_Normal3bv
;
1198 opcode
= X_GLrop_Normal3sv
;
1201 opcode
= X_GLrop_Normal3iv
;
1204 opcode
= X_GLrop_Normal3fv
;
1207 opcode
= X_GLrop_Normal3dv
;
1210 __glXSetError(gc
, GL_INVALID_ENUM
);
1214 a
= get_array_entry(arrays
, GL_NORMAL_ARRAY
, 0);
1216 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 3, GL_TRUE
, 4, opcode
);
1219 arrays
->array_info_cache_valid
= GL_FALSE
;
1225 __indirect_glColorPointer(GLint size
, GLenum type
, GLsizei stride
,
1226 const GLvoid
* pointer
)
1228 static const uint16_t byte_ops
[5] = {
1229 0, 0, 0, X_GLrop_Color3bv
, X_GLrop_Color4bv
1231 static const uint16_t ubyte_ops
[5] = {
1232 0, 0, 0, X_GLrop_Color3ubv
, X_GLrop_Color4ubv
1234 static const uint16_t short_ops
[5] = {
1235 0, 0, 0, X_GLrop_Color3sv
, X_GLrop_Color4sv
1237 static const uint16_t ushort_ops
[5] = {
1238 0, 0, 0, X_GLrop_Color3usv
, X_GLrop_Color4usv
1240 static const uint16_t int_ops
[5] = {
1241 0, 0, 0, X_GLrop_Color3iv
, X_GLrop_Color4iv
1243 static const uint16_t uint_ops
[5] = {
1244 0, 0, 0, X_GLrop_Color3uiv
, X_GLrop_Color4uiv
1246 static const uint16_t float_ops
[5] = {
1247 0, 0, 0, X_GLrop_Color3fv
, X_GLrop_Color4fv
1249 static const uint16_t double_ops
[5] = {
1250 0, 0, 0, X_GLrop_Color3dv
, X_GLrop_Color4dv
1253 struct glx_context
*gc
= __glXGetCurrentContext();
1254 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1255 struct array_state_vector
*arrays
= state
->array_state
;
1256 struct array_state
*a
;
1259 if (size
< 3 || size
> 4 || stride
< 0) {
1260 __glXSetError(gc
, GL_INVALID_VALUE
);
1266 opcode
= byte_ops
[size
];
1268 case GL_UNSIGNED_BYTE
:
1269 opcode
= ubyte_ops
[size
];
1272 opcode
= short_ops
[size
];
1274 case GL_UNSIGNED_SHORT
:
1275 opcode
= ushort_ops
[size
];
1278 opcode
= int_ops
[size
];
1280 case GL_UNSIGNED_INT
:
1281 opcode
= uint_ops
[size
];
1284 opcode
= float_ops
[size
];
1287 opcode
= double_ops
[size
];
1290 __glXSetError(gc
, GL_INVALID_ENUM
);
1294 a
= get_array_entry(arrays
, GL_COLOR_ARRAY
, 0);
1296 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_TRUE
, 4, opcode
);
1299 arrays
->array_info_cache_valid
= GL_FALSE
;
1305 __indirect_glIndexPointer(GLenum type
, GLsizei stride
, const GLvoid
* pointer
)
1308 struct glx_context
*gc
= __glXGetCurrentContext();
1309 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1310 struct array_state_vector
*arrays
= state
->array_state
;
1311 struct array_state
*a
;
1315 __glXSetError(gc
, GL_INVALID_VALUE
);
1320 case GL_UNSIGNED_BYTE
:
1321 opcode
= X_GLrop_Indexubv
;
1324 opcode
= X_GLrop_Indexsv
;
1327 opcode
= X_GLrop_Indexiv
;
1330 opcode
= X_GLrop_Indexfv
;
1333 opcode
= X_GLrop_Indexdv
;
1336 __glXSetError(gc
, GL_INVALID_ENUM
);
1340 a
= get_array_entry(arrays
, GL_INDEX_ARRAY
, 0);
1342 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 1, GL_FALSE
, 4, opcode
);
1345 arrays
->array_info_cache_valid
= GL_FALSE
;
1351 __indirect_glEdgeFlagPointer(GLsizei stride
, const GLvoid
* pointer
)
1353 struct glx_context
*gc
= __glXGetCurrentContext();
1354 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1355 struct array_state_vector
*arrays
= state
->array_state
;
1356 struct array_state
*a
;
1360 __glXSetError(gc
, GL_INVALID_VALUE
);
1365 a
= get_array_entry(arrays
, GL_EDGE_FLAG_ARRAY
, 0);
1367 COMMON_ARRAY_DATA_INIT(a
, pointer
, GL_UNSIGNED_BYTE
, stride
, 1, GL_FALSE
,
1368 4, X_GLrop_EdgeFlagv
);
1371 arrays
->array_info_cache_valid
= GL_FALSE
;
1377 __indirect_glTexCoordPointer(GLint size
, GLenum type
, GLsizei stride
,
1378 const GLvoid
* pointer
)
1380 static const uint16_t short_ops
[5] = {
1381 0, X_GLrop_TexCoord1sv
, X_GLrop_TexCoord2sv
, X_GLrop_TexCoord3sv
,
1384 static const uint16_t int_ops
[5] = {
1385 0, X_GLrop_TexCoord1iv
, X_GLrop_TexCoord2iv
, X_GLrop_TexCoord3iv
,
1388 static const uint16_t float_ops
[5] = {
1389 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2fv
, X_GLrop_TexCoord3fv
,
1392 static const uint16_t double_ops
[5] = {
1393 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2dv
, X_GLrop_TexCoord3dv
,
1397 static const uint16_t mshort_ops
[5] = {
1398 0, X_GLrop_MultiTexCoord1svARB
, X_GLrop_MultiTexCoord2svARB
,
1399 X_GLrop_MultiTexCoord3svARB
, X_GLrop_MultiTexCoord4svARB
1401 static const uint16_t mint_ops
[5] = {
1402 0, X_GLrop_MultiTexCoord1ivARB
, X_GLrop_MultiTexCoord2ivARB
,
1403 X_GLrop_MultiTexCoord3ivARB
, X_GLrop_MultiTexCoord4ivARB
1405 static const uint16_t mfloat_ops
[5] = {
1406 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2fvARB
,
1407 X_GLrop_MultiTexCoord3fvARB
, X_GLrop_MultiTexCoord4fvARB
1409 static const uint16_t mdouble_ops
[5] = {
1410 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2dvARB
,
1411 X_GLrop_MultiTexCoord3dvARB
, X_GLrop_MultiTexCoord4dvARB
1415 struct glx_context
*gc
= __glXGetCurrentContext();
1416 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1417 struct array_state_vector
*arrays
= state
->array_state
;
1418 struct array_state
*a
;
1419 unsigned header_size
;
1423 if (size
< 1 || size
> 4 || stride
< 0) {
1424 __glXSetError(gc
, GL_INVALID_VALUE
);
1428 index
= arrays
->active_texture_unit
;
1432 opcode
= short_ops
[size
];
1435 opcode
= int_ops
[size
];
1438 opcode
= float_ops
[size
];
1441 opcode
= double_ops
[size
];
1444 __glXSetError(gc
, GL_INVALID_ENUM
);
1453 opcode
= mshort_ops
[size
];
1456 opcode
= mint_ops
[size
];
1459 opcode
= mfloat_ops
[size
];
1462 opcode
= mdouble_ops
[size
];
1465 __glXSetError(gc
, GL_INVALID_ENUM
);
1472 a
= get_array_entry(arrays
, GL_TEXTURE_COORD_ARRAY
, index
);
1474 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_FALSE
,
1475 header_size
, opcode
);
1478 arrays
->array_info_cache_valid
= GL_FALSE
;
1484 __indirect_glSecondaryColorPointer(GLint size
, GLenum type
, GLsizei stride
,
1485 const GLvoid
* pointer
)
1488 struct glx_context
*gc
= __glXGetCurrentContext();
1489 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1490 struct array_state_vector
*arrays
= state
->array_state
;
1491 struct array_state
*a
;
1494 if (size
!= 3 || stride
< 0) {
1495 __glXSetError(gc
, GL_INVALID_VALUE
);
1503 case GL_UNSIGNED_BYTE
:
1509 case GL_UNSIGNED_SHORT
:
1515 case GL_UNSIGNED_INT
:
1525 __glXSetError(gc
, GL_INVALID_ENUM
);
1529 a
= get_array_entry(arrays
, GL_SECONDARY_COLOR_ARRAY
, 0);
1531 __glXSetError(gc
, GL_INVALID_OPERATION
);
1535 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_TRUE
, 4, opcode
);
1538 arrays
->array_info_cache_valid
= GL_FALSE
;
1544 __indirect_glFogCoordPointer(GLenum type
, GLsizei stride
,
1545 const GLvoid
* pointer
)
1548 struct glx_context
*gc
= __glXGetCurrentContext();
1549 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1550 struct array_state_vector
*arrays
= state
->array_state
;
1551 struct array_state
*a
;
1555 __glXSetError(gc
, GL_INVALID_VALUE
);
1567 __glXSetError(gc
, GL_INVALID_ENUM
);
1571 a
= get_array_entry(arrays
, GL_FOG_COORD_ARRAY
, 0);
1573 __glXSetError(gc
, GL_INVALID_OPERATION
);
1577 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 1, GL_FALSE
, 4, opcode
);
1580 arrays
->array_info_cache_valid
= GL_FALSE
;
1586 __indirect_glVertexAttribPointer(GLuint index
, GLint size
,
1587 GLenum type
, GLboolean normalized
,
1588 GLsizei stride
, const GLvoid
* pointer
)
1590 static const uint16_t short_ops
[5] = { 0, 4189, 4190, 4191, 4192 };
1591 static const uint16_t float_ops
[5] = { 0, 4193, 4194, 4195, 4196 };
1592 static const uint16_t double_ops
[5] = { 0, 4197, 4198, 4199, 4200 };
1595 struct glx_context
*gc
= __glXGetCurrentContext();
1596 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1597 struct array_state_vector
*arrays
= state
->array_state
;
1598 struct array_state
*a
;
1599 unsigned true_immediate_count
;
1600 unsigned true_immediate_size
;
1603 if ((size
< 1) || (size
> 4) || (stride
< 0)
1604 || (index
> arrays
->num_vertex_program_attribs
)) {
1605 __glXSetError(gc
, GL_INVALID_VALUE
);
1609 if (normalized
&& (type
!= GL_FLOAT
) && (type
!= GL_DOUBLE
)) {
1612 opcode
= X_GLrop_VertexAttrib4NbvARB
;
1614 case GL_UNSIGNED_BYTE
:
1615 opcode
= X_GLrop_VertexAttrib4NubvARB
;
1618 opcode
= X_GLrop_VertexAttrib4NsvARB
;
1620 case GL_UNSIGNED_SHORT
:
1621 opcode
= X_GLrop_VertexAttrib4NusvARB
;
1624 opcode
= X_GLrop_VertexAttrib4NivARB
;
1626 case GL_UNSIGNED_INT
:
1627 opcode
= X_GLrop_VertexAttrib4NuivARB
;
1630 __glXSetError(gc
, GL_INVALID_ENUM
);
1634 true_immediate_count
= 4;
1637 true_immediate_count
= size
;
1641 opcode
= X_GLrop_VertexAttrib4bvARB
;
1642 true_immediate_count
= 4;
1644 case GL_UNSIGNED_BYTE
:
1645 opcode
= X_GLrop_VertexAttrib4ubvARB
;
1646 true_immediate_count
= 4;
1649 opcode
= short_ops
[size
];
1651 case GL_UNSIGNED_SHORT
:
1652 opcode
= X_GLrop_VertexAttrib4usvARB
;
1653 true_immediate_count
= 4;
1656 opcode
= X_GLrop_VertexAttrib4ivARB
;
1657 true_immediate_count
= 4;
1659 case GL_UNSIGNED_INT
:
1660 opcode
= X_GLrop_VertexAttrib4uivARB
;
1661 true_immediate_count
= 4;
1664 opcode
= float_ops
[size
];
1667 opcode
= double_ops
[size
];
1670 __glXSetError(gc
, GL_INVALID_ENUM
);
1675 a
= get_array_entry(arrays
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, index
);
1677 __glXSetError(gc
, GL_INVALID_OPERATION
);
1681 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, normalized
, 8,
1684 true_immediate_size
= __glXTypeSize(type
) * true_immediate_count
;
1685 ((uint16_t *) (a
)->header
)[0] = __GLX_PAD(a
->header_size
1686 + true_immediate_size
);
1689 arrays
->array_info_cache_valid
= GL_FALSE
;
1695 * I don't have 100% confidence that this is correct. The different rules
1696 * about whether or not generic vertex attributes alias "classic" vertex
1697 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1698 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1699 * feeling is that the client-side doesn't have to worry about it. The
1700 * client just sends all the data to the server and lets the server deal
1704 __indirect_glVertexAttribPointerNV(GLuint index
, GLint size
,
1705 GLenum type
, GLsizei stride
,
1706 const GLvoid
* pointer
)
1708 struct glx_context
*gc
= __glXGetCurrentContext();
1709 GLboolean normalized
= GL_FALSE
;
1713 case GL_UNSIGNED_BYTE
:
1715 __glXSetError(gc
, GL_INVALID_VALUE
);
1718 normalized
= GL_TRUE
;
1723 __indirect_glVertexAttribPointer(index
, size
, type
,
1724 normalized
, stride
, pointer
);
1727 __glXSetError(gc
, GL_INVALID_ENUM
);
1734 __indirect_glClientActiveTexture(GLenum texture
)
1736 struct glx_context
*const gc
= __glXGetCurrentContext();
1737 __GLXattribute
*const state
=
1738 (__GLXattribute
*) (gc
->client_state_private
);
1739 struct array_state_vector
*const arrays
= state
->array_state
;
1740 const GLint unit
= (GLint
) texture
- GL_TEXTURE0
;
1743 if ((unit
< 0) || (unit
>= arrays
->num_texture_units
)) {
1744 __glXSetError(gc
, GL_INVALID_ENUM
);
1748 arrays
->active_texture_unit
= unit
;
1753 * Modify the enable state for the selected array
1756 __glXSetArrayEnable(__GLXattribute
* state
, GLenum key
, unsigned index
,
1759 struct array_state_vector
*arrays
= state
->array_state
;
1760 struct array_state
*a
;
1763 /* Texture coordinate arrays have an implict index set when the
1764 * application calls glClientActiveTexture.
1766 if (key
== GL_TEXTURE_COORD_ARRAY
) {
1767 index
= arrays
->active_texture_unit
;
1770 a
= get_array_entry(arrays
, key
, index
);
1772 if ((a
!= NULL
) && (a
->enabled
!= enable
)) {
1773 a
->enabled
= enable
;
1774 arrays
->array_info_cache_valid
= GL_FALSE
;
1782 __glXArrayDisableAll(__GLXattribute
* state
)
1784 struct array_state_vector
*arrays
= state
->array_state
;
1788 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1789 arrays
->arrays
[i
].enabled
= GL_FALSE
;
1792 arrays
->array_info_cache_valid
= GL_FALSE
;
1799 __glXGetArrayEnable(const __GLXattribute
* const state
,
1800 GLenum key
, unsigned index
, GLintptr
* dest
)
1802 const struct array_state_vector
*arrays
= state
->array_state
;
1803 const struct array_state
*a
=
1804 get_array_entry((struct array_state_vector
*) arrays
,
1808 *dest
= (GLintptr
) a
->enabled
;
1818 __glXGetArrayType(const __GLXattribute
* const state
,
1819 GLenum key
, unsigned index
, GLintptr
* dest
)
1821 const struct array_state_vector
*arrays
= state
->array_state
;
1822 const struct array_state
*a
=
1823 get_array_entry((struct array_state_vector
*) arrays
,
1827 *dest
= (GLintptr
) a
->data_type
;
1837 __glXGetArraySize(const __GLXattribute
* const state
,
1838 GLenum key
, unsigned index
, GLintptr
* dest
)
1840 const struct array_state_vector
*arrays
= state
->array_state
;
1841 const struct array_state
*a
=
1842 get_array_entry((struct array_state_vector
*) arrays
,
1846 *dest
= (GLintptr
) a
->count
;
1856 __glXGetArrayStride(const __GLXattribute
* const state
,
1857 GLenum key
, unsigned index
, GLintptr
* dest
)
1859 const struct array_state_vector
*arrays
= state
->array_state
;
1860 const struct array_state
*a
=
1861 get_array_entry((struct array_state_vector
*) arrays
,
1865 *dest
= (GLintptr
) a
->user_stride
;
1875 __glXGetArrayPointer(const __GLXattribute
* const state
,
1876 GLenum key
, unsigned index
, void **dest
)
1878 const struct array_state_vector
*arrays
= state
->array_state
;
1879 const struct array_state
*a
=
1880 get_array_entry((struct array_state_vector
*) arrays
,
1885 *dest
= (void *) (a
->data
);
1895 __glXGetArrayNormalized(const __GLXattribute
* const state
,
1896 GLenum key
, unsigned index
, GLintptr
* dest
)
1898 const struct array_state_vector
*arrays
= state
->array_state
;
1899 const struct array_state
*a
=
1900 get_array_entry((struct array_state_vector
*) arrays
,
1905 *dest
= (GLintptr
) a
->normalized
;
1915 __glXGetActiveTextureUnit(const __GLXattribute
* const state
)
1917 return state
->array_state
->active_texture_unit
;
1922 __glXPushArrayState(__GLXattribute
* state
)
1924 struct array_state_vector
*arrays
= state
->array_state
;
1925 struct array_stack_state
*stack
=
1926 &arrays
->stack
[(arrays
->stack_index
* arrays
->num_arrays
)];
1929 /* XXX are we pushing _all_ the necessary fields? */
1930 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1931 stack
[i
].data
= arrays
->arrays
[i
].data
;
1932 stack
[i
].data_type
= arrays
->arrays
[i
].data_type
;
1933 stack
[i
].user_stride
= arrays
->arrays
[i
].user_stride
;
1934 stack
[i
].count
= arrays
->arrays
[i
].count
;
1935 stack
[i
].key
= arrays
->arrays
[i
].key
;
1936 stack
[i
].index
= arrays
->arrays
[i
].index
;
1937 stack
[i
].enabled
= arrays
->arrays
[i
].enabled
;
1940 arrays
->active_texture_unit_stack
[arrays
->stack_index
] =
1941 arrays
->active_texture_unit
;
1943 arrays
->stack_index
++;
1948 __glXPopArrayState(__GLXattribute
* state
)
1950 struct array_state_vector
*arrays
= state
->array_state
;
1951 struct array_stack_state
*stack
;
1955 arrays
->stack_index
--;
1956 stack
= &arrays
->stack
[(arrays
->stack_index
* arrays
->num_arrays
)];
1958 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1959 switch (stack
[i
].key
) {
1960 case GL_NORMAL_ARRAY
:
1961 __indirect_glNormalPointer(stack
[i
].data_type
,
1962 stack
[i
].user_stride
, stack
[i
].data
);
1964 case GL_COLOR_ARRAY
:
1965 __indirect_glColorPointer(stack
[i
].count
,
1967 stack
[i
].user_stride
, stack
[i
].data
);
1969 case GL_INDEX_ARRAY
:
1970 __indirect_glIndexPointer(stack
[i
].data_type
,
1971 stack
[i
].user_stride
, stack
[i
].data
);
1973 case GL_EDGE_FLAG_ARRAY
:
1974 __indirect_glEdgeFlagPointer(stack
[i
].user_stride
, stack
[i
].data
);
1976 case GL_TEXTURE_COORD_ARRAY
:
1977 arrays
->active_texture_unit
= stack
[i
].index
;
1978 __indirect_glTexCoordPointer(stack
[i
].count
,
1980 stack
[i
].user_stride
, stack
[i
].data
);
1982 case GL_SECONDARY_COLOR_ARRAY
:
1983 __indirect_glSecondaryColorPointer(stack
[i
].count
,
1985 stack
[i
].user_stride
,
1988 case GL_FOG_COORDINATE_ARRAY
:
1989 __indirect_glFogCoordPointer(stack
[i
].data_type
,
1990 stack
[i
].user_stride
, stack
[i
].data
);
1995 __glXSetArrayEnable(state
, stack
[i
].key
, stack
[i
].index
,
1999 arrays
->active_texture_unit
=
2000 arrays
->active_texture_unit_stack
[arrays
->stack_index
];