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
));
154 state
->array_state
= arrays
;
156 if (arrays
== NULL
) {
157 __glXSetError(gc
, GL_OUT_OF_MEMORY
);
161 arrays
->old_DrawArrays_possible
= !state
->NoDrawArraysProtocol
;
162 arrays
->new_DrawArrays_possible
= GL_FALSE
;
163 arrays
->DrawArrays
= NULL
;
165 arrays
->active_texture_unit
= 0;
168 /* Determine how many arrays are actually needed. Only arrays that
169 * are supported by the server are create. For example, if the server
170 * supports only 2 texture units, then only 2 texture coordinate arrays
173 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
174 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
175 * GL_EDGE_FLAG_ARRAY are supported.
180 if (__glExtensionBitIsEnabled(gc
, GL_EXT_fog_coord_bit
)
181 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4)) {
186 if (__glExtensionBitIsEnabled(gc
, GL_EXT_secondary_color_bit
)
187 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4)) {
188 got_secondary_color
= GL_TRUE
;
192 if (__glExtensionBitIsEnabled(gc
, GL_ARB_multitexture_bit
)
193 || (gc
->server_major
> 1) || (gc
->server_minor
>= 3)) {
194 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS
, &texture_units
);
197 if (__glExtensionBitIsEnabled(gc
, GL_ARB_vertex_program_bit
)) {
198 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
,
199 GL_MAX_PROGRAM_ATTRIBS_ARB
,
200 &vertex_program_attribs
);
203 arrays
->num_texture_units
= texture_units
;
204 arrays
->num_vertex_program_attribs
= vertex_program_attribs
;
205 array_count
+= texture_units
+ vertex_program_attribs
;
206 arrays
->num_arrays
= array_count
;
207 arrays
->arrays
= calloc(array_count
, sizeof(struct array_state
));
209 if (arrays
->arrays
== NULL
) {
211 __glXSetError(gc
, GL_OUT_OF_MEMORY
);
215 arrays
->arrays
[0].data_type
= GL_FLOAT
;
216 arrays
->arrays
[0].count
= 3;
217 arrays
->arrays
[0].key
= GL_NORMAL_ARRAY
;
218 arrays
->arrays
[0].normalized
= GL_TRUE
;
219 arrays
->arrays
[0].old_DrawArrays_possible
= GL_TRUE
;
221 arrays
->arrays
[1].data_type
= GL_FLOAT
;
222 arrays
->arrays
[1].count
= 4;
223 arrays
->arrays
[1].key
= GL_COLOR_ARRAY
;
224 arrays
->arrays
[1].normalized
= GL_TRUE
;
225 arrays
->arrays
[1].old_DrawArrays_possible
= GL_TRUE
;
227 arrays
->arrays
[2].data_type
= GL_FLOAT
;
228 arrays
->arrays
[2].count
= 1;
229 arrays
->arrays
[2].key
= GL_INDEX_ARRAY
;
230 arrays
->arrays
[2].old_DrawArrays_possible
= GL_TRUE
;
232 arrays
->arrays
[3].data_type
= GL_UNSIGNED_BYTE
;
233 arrays
->arrays
[3].count
= 1;
234 arrays
->arrays
[3].key
= GL_EDGE_FLAG_ARRAY
;
235 arrays
->arrays
[3].old_DrawArrays_possible
= GL_TRUE
;
237 for (i
= 0; i
< texture_units
; i
++) {
238 arrays
->arrays
[4 + i
].data_type
= GL_FLOAT
;
239 arrays
->arrays
[4 + i
].count
= 4;
240 arrays
->arrays
[4 + i
].key
= GL_TEXTURE_COORD_ARRAY
;
242 arrays
->arrays
[4 + i
].old_DrawArrays_possible
= (i
== 0);
243 arrays
->arrays
[4 + i
].index
= i
;
246 i
= 4 + texture_units
;
249 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
250 arrays
->arrays
[i
].count
= 1;
251 arrays
->arrays
[i
].key
= GL_FOG_COORDINATE_ARRAY
;
252 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
256 if (got_secondary_color
) {
257 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
258 arrays
->arrays
[i
].count
= 3;
259 arrays
->arrays
[i
].key
= GL_SECONDARY_COLOR_ARRAY
;
260 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
261 arrays
->arrays
[i
].normalized
= GL_TRUE
;
266 for (j
= 0; j
< vertex_program_attribs
; j
++) {
267 const unsigned idx
= (vertex_program_attribs
- (j
+ 1));
270 arrays
->arrays
[idx
+ i
].data_type
= GL_FLOAT
;
271 arrays
->arrays
[idx
+ i
].count
= 4;
272 arrays
->arrays
[idx
+ i
].key
= GL_VERTEX_ATTRIB_ARRAY_POINTER
;
274 arrays
->arrays
[idx
+ i
].old_DrawArrays_possible
= 0;
275 arrays
->arrays
[idx
+ i
].index
= idx
;
278 i
+= vertex_program_attribs
;
281 /* Vertex array *must* be last because of the way that
282 * emit_DrawArrays_none works.
285 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
286 arrays
->arrays
[i
].count
= 4;
287 arrays
->arrays
[i
].key
= GL_VERTEX_ARRAY
;
288 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
290 assert((i
+ 1) == arrays
->num_arrays
);
292 arrays
->stack_index
= 0;
293 arrays
->stack
= malloc(sizeof(struct array_stack_state
)
295 * __GL_CLIENT_ATTRIB_STACK_DEPTH
);
297 if (arrays
->stack
== NULL
) {
298 free(arrays
->arrays
);
300 __glXSetError(gc
, GL_OUT_OF_MEMORY
);
307 * Calculate the size of a single vertex for the "none" protocol. This is
308 * essentially the size of all the immediate-mode commands required to
309 * implement the enabled vertex arrays.
312 calculate_single_vertex_size_none(const struct array_state_vector
*arrays
)
314 size_t single_vertex_size
= 0;
318 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
319 if (arrays
->arrays
[i
].enabled
) {
320 single_vertex_size
+= arrays
->arrays
[i
].header
[0];
324 return single_vertex_size
;
329 * Emit a single element using non-DrawArrays protocol.
332 emit_element_none(GLubyte
* dst
,
333 const struct array_state_vector
* arrays
, unsigned index
)
338 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
339 if (arrays
->arrays
[i
].enabled
) {
340 const size_t offset
= index
* arrays
->arrays
[i
].true_stride
;
342 /* The generic attributes can have more data than is in the
343 * elements. This is because a vertex array can be a 2 element,
344 * normalized, unsigned short, but the "closest" immediate mode
345 * protocol is for a 4Nus. Since the sizes are small, the
346 * performance impact on modern processors should be negligible.
348 (void) memset(dst
, 0, arrays
->arrays
[i
].header
[0]);
350 (void) memcpy(dst
, arrays
->arrays
[i
].header
, 4);
354 if (arrays
->arrays
[i
].key
== GL_TEXTURE_COORD_ARRAY
&&
355 arrays
->arrays
[i
].index
> 0) {
356 /* Multi-texture coordinate arrays require the texture target
357 * to be sent. For doubles it is after the data, for everything
360 GLenum texture
= arrays
->arrays
[i
].index
+ GL_TEXTURE0
;
361 if (arrays
->arrays
[i
].data_type
== GL_DOUBLE
) {
362 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
363 arrays
->arrays
[i
].element_size
);
364 dst
+= arrays
->arrays
[i
].element_size
;
365 (void) memcpy(dst
, &texture
, 4);
368 (void) memcpy(dst
, &texture
, 4);
370 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
371 arrays
->arrays
[i
].element_size
);
372 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
374 } else if (arrays
->arrays
[i
].key
== GL_VERTEX_ATTRIB_ARRAY_POINTER
) {
375 /* Vertex attribute data requires the index sent first.
377 (void) memcpy(dst
, &arrays
->arrays
[i
].index
, 4);
379 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
380 arrays
->arrays
[i
].element_size
);
381 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
383 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
384 arrays
->arrays
[i
].element_size
);
385 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
395 * Emit a single element using "old" DrawArrays protocol from
396 * EXT_vertex_arrays / OpenGL 1.1.
399 emit_element_old(GLubyte
* dst
,
400 const struct array_state_vector
* arrays
, unsigned index
)
405 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
406 if (arrays
->arrays
[i
].enabled
) {
407 const size_t offset
= index
* arrays
->arrays
[i
].true_stride
;
409 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
410 arrays
->arrays
[i
].element_size
);
412 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
421 get_array_entry(const struct array_state_vector
*arrays
,
422 GLenum key
, unsigned index
)
426 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
427 if ((arrays
->arrays
[i
].key
== key
)
428 && (arrays
->arrays
[i
].index
== index
)) {
429 return &arrays
->arrays
[i
];
438 allocate_array_info_cache(struct array_state_vector
*arrays
,
439 size_t required_size
)
441 #define MAX_HEADER_SIZE 20
442 if (arrays
->array_info_cache_buffer_size
< required_size
) {
443 GLubyte
*temp
= realloc(arrays
->array_info_cache_base
,
444 required_size
+ MAX_HEADER_SIZE
);
450 arrays
->array_info_cache_base
= temp
;
451 arrays
->array_info_cache
= temp
+ MAX_HEADER_SIZE
;
452 arrays
->array_info_cache_buffer_size
= required_size
;
455 arrays
->array_info_cache_size
= required_size
;
463 fill_array_info_cache(struct array_state_vector
*arrays
)
465 GLboolean old_DrawArrays_possible
;
469 /* Determine how many arrays are enabled.
472 arrays
->enabled_client_array_count
= 0;
473 old_DrawArrays_possible
= arrays
->old_DrawArrays_possible
;
474 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
475 if (arrays
->arrays
[i
].enabled
) {
476 arrays
->enabled_client_array_count
++;
477 old_DrawArrays_possible
&= arrays
->arrays
[i
].old_DrawArrays_possible
;
481 if (arrays
->new_DrawArrays_possible
) {
482 assert(!arrays
->new_DrawArrays_possible
);
484 else if (old_DrawArrays_possible
) {
485 const size_t required_size
= arrays
->enabled_client_array_count
* 12;
489 if (!allocate_array_info_cache(arrays
, required_size
)) {
494 info
= (uint32_t *) arrays
->array_info_cache
;
495 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
496 if (arrays
->arrays
[i
].enabled
) {
497 *(info
++) = arrays
->arrays
[i
].data_type
;
498 *(info
++) = arrays
->arrays
[i
].count
;
499 *(info
++) = arrays
->arrays
[i
].key
;
503 arrays
->DrawArrays
= emit_DrawArrays_old
;
504 arrays
->DrawElements
= emit_DrawElements_old
;
507 arrays
->DrawArrays
= emit_DrawArrays_none
;
508 arrays
->DrawElements
= emit_DrawElements_none
;
511 arrays
->array_info_cache_valid
= GL_TRUE
;
516 * Emit a \c glDrawArrays command using the "none" protocol. That is,
517 * emit immediate-mode commands that are equivalent to the requiested
518 * \c glDrawArrays command. This is used with servers that don't support
519 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
520 * vertex state is enabled that is not compatible with that protocol.
523 emit_DrawArrays_none(GLenum mode
, GLint first
, GLsizei count
)
525 struct glx_context
*gc
= __glXGetCurrentContext();
526 const __GLXattribute
*state
=
527 (const __GLXattribute
*) (gc
->client_state_private
);
528 struct array_state_vector
*arrays
= state
->array_state
;
530 size_t single_vertex_size
;
533 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
534 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
537 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
541 (void) memcpy(pc
, begin_cmd
, 4);
542 *(int *) (pc
+ 4) = mode
;
546 for (i
= 0; i
< count
; i
++) {
547 if ((pc
+ single_vertex_size
) >= gc
->bufEnd
) {
548 pc
= __glXFlushRenderBuffer(gc
, pc
);
551 pc
= emit_element_none(pc
, arrays
, first
+ i
);
554 if ((pc
+ 4) >= gc
->bufEnd
) {
555 pc
= __glXFlushRenderBuffer(gc
, pc
);
558 (void) memcpy(pc
, end_cmd
, 4);
562 if (gc
->pc
> gc
->limit
) {
563 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
569 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
572 * \param gc GLX context.
573 * \param arrays Array state.
574 * \param elements_per_request Location to store the number of elements that
575 * can fit in a single Render / RenderLarge
577 * \param total_request Total number of requests for a RenderLarge
578 * command. If a Render command is used, this
580 * \param mode Drawing mode.
581 * \param count Number of vertices.
584 * A pointer to the buffer for array data.
587 emit_DrawArrays_header_old(struct glx_context
* gc
,
588 struct array_state_vector
*arrays
,
589 size_t * elements_per_request
,
590 unsigned int *total_requests
,
591 GLenum mode
, GLsizei count
)
594 size_t single_vertex_size
;
595 const unsigned header_size
= 16;
600 /* Determine the size of the whole command. This includes the header,
601 * the ARRAY_INFO data and the array data. Once this size is calculated,
602 * it will be known whether a Render or RenderLarge command is needed.
605 single_vertex_size
= 0;
606 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
607 if (arrays
->arrays
[i
].enabled
) {
608 single_vertex_size
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
612 command_size
= arrays
->array_info_cache_size
+ header_size
613 + (single_vertex_size
* count
);
616 /* Write the header for either a Render command or a RenderLarge
617 * command. After the header is written, write the ARRAY_INFO data.
620 if (command_size
> gc
->maxSmallRenderCommandSize
) {
621 /* maxSize is the maximum amount of data can be stuffed into a single
622 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
623 * packet size minus sz_xGLXRenderReq.
625 const size_t maxSize
= (gc
->bufSize
+ sz_xGLXRenderReq
)
626 - sz_xGLXRenderLargeReq
;
627 unsigned vertex_requests
;
630 /* Calculate the number of data packets that will be required to send
631 * the whole command. To do this, the number of verticies that
632 * will fit in a single buffer must be calculated.
634 * The important value here is elements_per_request. This is the
635 * number of complete array elements that will fit in a single
636 * buffer. There may be some wasted space at the end of the buffer,
637 * but splitting elements across buffer boundries would be painful.
640 elements_per_request
[0] = maxSize
/ single_vertex_size
;
642 vertex_requests
= (count
+ elements_per_request
[0] - 1)
643 / elements_per_request
[0];
645 *total_requests
= vertex_requests
+ 1;
648 __glXFlushRenderBuffer(gc
, gc
->pc
);
652 pc
= ((GLubyte
*) arrays
->array_info_cache
) - (header_size
+ 4);
653 *(uint32_t *) (pc
+ 0) = command_size
;
654 *(uint32_t *) (pc
+ 4) = X_GLrop_DrawArrays
;
655 *(uint32_t *) (pc
+ 8) = count
;
656 *(uint32_t *) (pc
+ 12) = arrays
->enabled_client_array_count
;
657 *(uint32_t *) (pc
+ 16) = mode
;
659 __glXSendLargeChunk(gc
, 1, *total_requests
, pc
,
660 header_size
+ 4 + arrays
->array_info_cache_size
);
665 if ((gc
->pc
+ command_size
) >= gc
->bufEnd
) {
666 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
670 *(uint16_t *) (pc
+ 0) = command_size
;
671 *(uint16_t *) (pc
+ 2) = X_GLrop_DrawArrays
;
672 *(uint32_t *) (pc
+ 4) = count
;
673 *(uint32_t *) (pc
+ 8) = arrays
->enabled_client_array_count
;
674 *(uint32_t *) (pc
+ 12) = mode
;
678 (void) memcpy(pc
, arrays
->array_info_cache
,
679 arrays
->array_info_cache_size
);
680 pc
+= arrays
->array_info_cache_size
;
682 *elements_per_request
= count
;
694 emit_DrawArrays_old(GLenum mode
, GLint first
, GLsizei count
)
696 struct glx_context
*gc
= __glXGetCurrentContext();
697 const __GLXattribute
*state
=
698 (const __GLXattribute
*) (gc
->client_state_private
);
699 struct array_state_vector
*arrays
= state
->array_state
;
702 size_t elements_per_request
;
703 unsigned total_requests
= 0;
705 size_t total_sent
= 0;
708 pc
= emit_DrawArrays_header_old(gc
, arrays
, &elements_per_request
,
709 &total_requests
, mode
, count
);
715 if (total_requests
== 0) {
716 assert(elements_per_request
>= count
);
718 for (i
= 0; i
< count
; i
++) {
719 pc
= emit_element_old(pc
, arrays
, i
+ first
);
722 assert(pc
<= gc
->bufEnd
);
725 if (gc
->pc
> gc
->limit
) {
726 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
733 for (req
= 2; req
<= total_requests
; req
++) {
734 if (count
< elements_per_request
) {
735 elements_per_request
= count
;
739 for (i
= 0; i
< elements_per_request
; i
++) {
740 pc
= emit_element_old(pc
, arrays
, i
+ first
);
743 first
+= elements_per_request
;
745 total_sent
+= (size_t) (pc
- gc
->pc
);
746 __glXSendLargeChunk(gc
, req
, total_requests
, gc
->pc
, pc
- gc
->pc
);
748 count
-= elements_per_request
;
755 emit_DrawElements_none(GLenum mode
, GLsizei count
, GLenum type
,
756 const GLvoid
* indices
)
758 struct glx_context
*gc
= __glXGetCurrentContext();
759 const __GLXattribute
*state
=
760 (const __GLXattribute
*) (gc
->client_state_private
);
761 struct array_state_vector
*arrays
= state
->array_state
;
762 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
763 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
766 size_t single_vertex_size
;
770 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
773 if ((gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
774 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
779 (void) memcpy(pc
, begin_cmd
, 4);
780 *(int *) (pc
+ 4) = mode
;
784 for (i
= 0; i
< count
; i
++) {
787 if ((pc
+ single_vertex_size
) >= gc
->bufEnd
) {
788 pc
= __glXFlushRenderBuffer(gc
, pc
);
792 case GL_UNSIGNED_INT
:
793 index
= (unsigned) (((GLuint
*) indices
)[i
]);
795 case GL_UNSIGNED_SHORT
:
796 index
= (unsigned) (((GLushort
*) indices
)[i
]);
798 case GL_UNSIGNED_BYTE
:
799 index
= (unsigned) (((GLubyte
*) indices
)[i
]);
802 pc
= emit_element_none(pc
, arrays
, index
);
805 if ((pc
+ 4) >= gc
->bufEnd
) {
806 pc
= __glXFlushRenderBuffer(gc
, pc
);
809 (void) memcpy(pc
, end_cmd
, 4);
813 if (gc
->pc
> gc
->limit
) {
814 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
822 emit_DrawElements_old(GLenum mode
, GLsizei count
, GLenum type
,
823 const GLvoid
* indices
)
825 struct glx_context
*gc
= __glXGetCurrentContext();
826 const __GLXattribute
*state
=
827 (const __GLXattribute
*) (gc
->client_state_private
);
828 struct array_state_vector
*arrays
= state
->array_state
;
831 size_t elements_per_request
;
832 unsigned total_requests
= 0;
835 unsigned req_element
= 0;
838 pc
= emit_DrawArrays_header_old(gc
, arrays
, &elements_per_request
,
839 &total_requests
, mode
, count
);
847 if (count
< elements_per_request
) {
848 elements_per_request
= count
;
852 case GL_UNSIGNED_INT
:{
853 const GLuint
*ui_ptr
= (const GLuint
*) indices
+ req_element
;
855 for (i
= 0; i
< elements_per_request
; i
++) {
856 const GLint index
= (GLint
) * (ui_ptr
++);
857 pc
= emit_element_old(pc
, arrays
, index
);
861 case GL_UNSIGNED_SHORT
:{
862 const GLushort
*us_ptr
= (const GLushort
*) indices
+ req_element
;
864 for (i
= 0; i
< elements_per_request
; i
++) {
865 const GLint index
= (GLint
) * (us_ptr
++);
866 pc
= emit_element_old(pc
, arrays
, index
);
870 case GL_UNSIGNED_BYTE
:{
871 const GLubyte
*ub_ptr
= (const GLubyte
*) indices
+ req_element
;
873 for (i
= 0; i
< elements_per_request
; i
++) {
874 const GLint index
= (GLint
) * (ub_ptr
++);
875 pc
= emit_element_old(pc
, arrays
, index
);
881 if (total_requests
!= 0) {
882 __glXSendLargeChunk(gc
, req
, total_requests
, gc
->pc
, pc
- gc
->pc
);
887 count
-= elements_per_request
;
888 req_element
+= elements_per_request
;
892 assert((total_requests
== 0) || ((req
- 1) == total_requests
));
894 if (total_requests
== 0) {
895 assert(pc
<= gc
->bufEnd
);
898 if (gc
->pc
> gc
->limit
) {
899 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
906 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
907 * If it is not valid, then an error code is set in the GLX context.
910 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
913 validate_mode(struct glx_context
* gc
, GLenum mode
)
920 case GL_TRIANGLE_STRIP
:
921 case GL_TRIANGLE_FAN
:
928 __glXSetError(gc
, GL_INVALID_ENUM
);
937 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
938 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
939 * being set. A value of zero will not result in an error being set, but
940 * will result in \c GL_FALSE being returned.
943 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
946 validate_count(struct glx_context
* gc
, GLsizei count
)
949 __glXSetError(gc
, GL_INVALID_VALUE
);
957 * Validate that the \c type parameter to \c glDrawElements, et. al. is
958 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
959 * \c GL_UNSIGNED_INT are valid.
962 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
965 validate_type(struct glx_context
* gc
, GLenum type
)
968 case GL_UNSIGNED_INT
:
969 case GL_UNSIGNED_SHORT
:
970 case GL_UNSIGNED_BYTE
:
973 __glXSetError(gc
, GL_INVALID_ENUM
);
980 __indirect_glDrawArrays(GLenum mode
, GLint first
, GLsizei count
)
982 struct glx_context
*gc
= __glXGetCurrentContext();
983 const __GLXattribute
*state
=
984 (const __GLXattribute
*) (gc
->client_state_private
);
985 struct array_state_vector
*arrays
= state
->array_state
;
988 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)) {
989 if (!arrays
->array_info_cache_valid
) {
990 fill_array_info_cache(arrays
);
993 arrays
->DrawArrays(mode
, first
, count
);
999 __indirect_glArrayElement(GLint index
)
1001 struct glx_context
*gc
= __glXGetCurrentContext();
1002 const __GLXattribute
*state
=
1003 (const __GLXattribute
*) (gc
->client_state_private
);
1004 struct array_state_vector
*arrays
= state
->array_state
;
1006 size_t single_vertex_size
;
1009 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
1011 if ((gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
1012 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
1015 gc
->pc
= emit_element_none(gc
->pc
, arrays
, index
);
1017 if (gc
->pc
> gc
->limit
) {
1018 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
1024 __indirect_glDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
1025 const GLvoid
* indices
)
1027 struct glx_context
*gc
= __glXGetCurrentContext();
1028 const __GLXattribute
*state
=
1029 (const __GLXattribute
*) (gc
->client_state_private
);
1030 struct array_state_vector
*arrays
= state
->array_state
;
1033 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)
1034 && validate_type(gc
, type
)) {
1035 if (!arrays
->array_info_cache_valid
) {
1036 fill_array_info_cache(arrays
);
1039 arrays
->DrawElements(mode
, count
, type
, indices
);
1045 __indirect_glDrawRangeElements(GLenum mode
, GLuint start
, GLuint end
,
1046 GLsizei count
, GLenum type
,
1047 const GLvoid
* indices
)
1049 struct glx_context
*gc
= __glXGetCurrentContext();
1050 const __GLXattribute
*state
=
1051 (const __GLXattribute
*) (gc
->client_state_private
);
1052 struct array_state_vector
*arrays
= state
->array_state
;
1055 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)
1056 && validate_type(gc
, type
)) {
1058 __glXSetError(gc
, GL_INVALID_VALUE
);
1062 if (!arrays
->array_info_cache_valid
) {
1063 fill_array_info_cache(arrays
);
1066 arrays
->DrawElements(mode
, count
, type
, indices
);
1072 __indirect_glMultiDrawArrays(GLenum mode
, const GLint
*first
,
1073 const GLsizei
*count
, GLsizei primcount
)
1075 struct glx_context
*gc
= __glXGetCurrentContext();
1076 const __GLXattribute
*state
=
1077 (const __GLXattribute
*) (gc
->client_state_private
);
1078 struct array_state_vector
*arrays
= state
->array_state
;
1082 if (validate_mode(gc
, mode
)) {
1083 if (!arrays
->array_info_cache_valid
) {
1084 fill_array_info_cache(arrays
);
1087 for (i
= 0; i
< primcount
; i
++) {
1088 if (validate_count(gc
, count
[i
])) {
1089 arrays
->DrawArrays(mode
, first
[i
], count
[i
]);
1097 __indirect_glMultiDrawElementsEXT(GLenum mode
, const GLsizei
* count
,
1098 GLenum type
, const GLvoid
* const * indices
,
1101 struct glx_context
*gc
= __glXGetCurrentContext();
1102 const __GLXattribute
*state
=
1103 (const __GLXattribute
*) (gc
->client_state_private
);
1104 struct array_state_vector
*arrays
= state
->array_state
;
1108 if (validate_mode(gc
, mode
) && validate_type(gc
, type
)) {
1109 if (!arrays
->array_info_cache_valid
) {
1110 fill_array_info_cache(arrays
);
1113 for (i
= 0; i
< primcount
; i
++) {
1114 if (validate_count(gc
, count
[i
])) {
1115 arrays
->DrawElements(mode
, count
[i
], type
, indices
[i
]);
1122 /* The HDR_SIZE macro argument is the command header size (4 bytes)
1123 * plus any additional index word e.g. for texture units or vertex
1126 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1129 (a)->data_type = TYPE; \
1130 (a)->user_stride = STRIDE; \
1131 (a)->count = COUNT; \
1132 (a)->normalized = NORMALIZED; \
1134 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1135 (a)->true_stride = (STRIDE == 0) \
1136 ? (a)->element_size : STRIDE; \
1138 (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size); \
1139 (a)->header[1] = OPCODE; \
1144 __indirect_glVertexPointer(GLint size
, GLenum type
, GLsizei stride
,
1145 const GLvoid
* pointer
)
1147 static const uint16_t short_ops
[5] = {
1148 0, 0, X_GLrop_Vertex2sv
, X_GLrop_Vertex3sv
, X_GLrop_Vertex4sv
1150 static const uint16_t int_ops
[5] = {
1151 0, 0, X_GLrop_Vertex2iv
, X_GLrop_Vertex3iv
, X_GLrop_Vertex4iv
1153 static const uint16_t float_ops
[5] = {
1154 0, 0, X_GLrop_Vertex2fv
, X_GLrop_Vertex3fv
, X_GLrop_Vertex4fv
1156 static const uint16_t double_ops
[5] = {
1157 0, 0, X_GLrop_Vertex2dv
, X_GLrop_Vertex3dv
, X_GLrop_Vertex4dv
1160 struct glx_context
*gc
= __glXGetCurrentContext();
1161 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1162 struct array_state_vector
*arrays
= state
->array_state
;
1163 struct array_state
*a
;
1166 if (size
< 2 || size
> 4 || stride
< 0) {
1167 __glXSetError(gc
, GL_INVALID_VALUE
);
1173 opcode
= short_ops
[size
];
1176 opcode
= int_ops
[size
];
1179 opcode
= float_ops
[size
];
1182 opcode
= double_ops
[size
];
1185 __glXSetError(gc
, GL_INVALID_ENUM
);
1189 a
= get_array_entry(arrays
, GL_VERTEX_ARRAY
, 0);
1191 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_FALSE
, 4,
1195 arrays
->array_info_cache_valid
= GL_FALSE
;
1201 __indirect_glNormalPointer(GLenum type
, GLsizei stride
,
1202 const GLvoid
* pointer
)
1205 struct glx_context
*gc
= __glXGetCurrentContext();
1206 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1207 struct array_state_vector
*arrays
= state
->array_state
;
1208 struct array_state
*a
;
1212 __glXSetError(gc
, GL_INVALID_VALUE
);
1218 opcode
= X_GLrop_Normal3bv
;
1221 opcode
= X_GLrop_Normal3sv
;
1224 opcode
= X_GLrop_Normal3iv
;
1227 opcode
= X_GLrop_Normal3fv
;
1230 opcode
= X_GLrop_Normal3dv
;
1233 __glXSetError(gc
, GL_INVALID_ENUM
);
1237 a
= get_array_entry(arrays
, GL_NORMAL_ARRAY
, 0);
1239 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 3, GL_TRUE
, 4, opcode
);
1242 arrays
->array_info_cache_valid
= GL_FALSE
;
1248 __indirect_glColorPointer(GLint size
, GLenum type
, GLsizei stride
,
1249 const GLvoid
* pointer
)
1251 static const uint16_t byte_ops
[5] = {
1252 0, 0, 0, X_GLrop_Color3bv
, X_GLrop_Color4bv
1254 static const uint16_t ubyte_ops
[5] = {
1255 0, 0, 0, X_GLrop_Color3ubv
, X_GLrop_Color4ubv
1257 static const uint16_t short_ops
[5] = {
1258 0, 0, 0, X_GLrop_Color3sv
, X_GLrop_Color4sv
1260 static const uint16_t ushort_ops
[5] = {
1261 0, 0, 0, X_GLrop_Color3usv
, X_GLrop_Color4usv
1263 static const uint16_t int_ops
[5] = {
1264 0, 0, 0, X_GLrop_Color3iv
, X_GLrop_Color4iv
1266 static const uint16_t uint_ops
[5] = {
1267 0, 0, 0, X_GLrop_Color3uiv
, X_GLrop_Color4uiv
1269 static const uint16_t float_ops
[5] = {
1270 0, 0, 0, X_GLrop_Color3fv
, X_GLrop_Color4fv
1272 static const uint16_t double_ops
[5] = {
1273 0, 0, 0, X_GLrop_Color3dv
, X_GLrop_Color4dv
1276 struct glx_context
*gc
= __glXGetCurrentContext();
1277 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1278 struct array_state_vector
*arrays
= state
->array_state
;
1279 struct array_state
*a
;
1282 if (size
< 3 || size
> 4 || stride
< 0) {
1283 __glXSetError(gc
, GL_INVALID_VALUE
);
1289 opcode
= byte_ops
[size
];
1291 case GL_UNSIGNED_BYTE
:
1292 opcode
= ubyte_ops
[size
];
1295 opcode
= short_ops
[size
];
1297 case GL_UNSIGNED_SHORT
:
1298 opcode
= ushort_ops
[size
];
1301 opcode
= int_ops
[size
];
1303 case GL_UNSIGNED_INT
:
1304 opcode
= uint_ops
[size
];
1307 opcode
= float_ops
[size
];
1310 opcode
= double_ops
[size
];
1313 __glXSetError(gc
, GL_INVALID_ENUM
);
1317 a
= get_array_entry(arrays
, GL_COLOR_ARRAY
, 0);
1319 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_TRUE
, 4, opcode
);
1322 arrays
->array_info_cache_valid
= GL_FALSE
;
1328 __indirect_glIndexPointer(GLenum type
, GLsizei stride
, const GLvoid
* pointer
)
1331 struct glx_context
*gc
= __glXGetCurrentContext();
1332 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1333 struct array_state_vector
*arrays
= state
->array_state
;
1334 struct array_state
*a
;
1338 __glXSetError(gc
, GL_INVALID_VALUE
);
1343 case GL_UNSIGNED_BYTE
:
1344 opcode
= X_GLrop_Indexubv
;
1347 opcode
= X_GLrop_Indexsv
;
1350 opcode
= X_GLrop_Indexiv
;
1353 opcode
= X_GLrop_Indexfv
;
1356 opcode
= X_GLrop_Indexdv
;
1359 __glXSetError(gc
, GL_INVALID_ENUM
);
1363 a
= get_array_entry(arrays
, GL_INDEX_ARRAY
, 0);
1365 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 1, GL_FALSE
, 4, opcode
);
1368 arrays
->array_info_cache_valid
= GL_FALSE
;
1374 __indirect_glEdgeFlagPointer(GLsizei stride
, const GLvoid
* pointer
)
1376 struct glx_context
*gc
= __glXGetCurrentContext();
1377 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1378 struct array_state_vector
*arrays
= state
->array_state
;
1379 struct array_state
*a
;
1383 __glXSetError(gc
, GL_INVALID_VALUE
);
1388 a
= get_array_entry(arrays
, GL_EDGE_FLAG_ARRAY
, 0);
1390 COMMON_ARRAY_DATA_INIT(a
, pointer
, GL_UNSIGNED_BYTE
, stride
, 1, GL_FALSE
,
1391 4, X_GLrop_EdgeFlagv
);
1394 arrays
->array_info_cache_valid
= GL_FALSE
;
1400 __indirect_glTexCoordPointer(GLint size
, GLenum type
, GLsizei stride
,
1401 const GLvoid
* pointer
)
1403 static const uint16_t short_ops
[5] = {
1404 0, X_GLrop_TexCoord1sv
, X_GLrop_TexCoord2sv
, X_GLrop_TexCoord3sv
,
1407 static const uint16_t int_ops
[5] = {
1408 0, X_GLrop_TexCoord1iv
, X_GLrop_TexCoord2iv
, X_GLrop_TexCoord3iv
,
1411 static const uint16_t float_ops
[5] = {
1412 0, X_GLrop_TexCoord1fv
, X_GLrop_TexCoord2fv
, X_GLrop_TexCoord3fv
,
1415 static const uint16_t double_ops
[5] = {
1416 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2dv
, X_GLrop_TexCoord3dv
,
1420 static const uint16_t mshort_ops
[5] = {
1421 0, X_GLrop_MultiTexCoord1svARB
, X_GLrop_MultiTexCoord2svARB
,
1422 X_GLrop_MultiTexCoord3svARB
, X_GLrop_MultiTexCoord4svARB
1424 static const uint16_t mint_ops
[5] = {
1425 0, X_GLrop_MultiTexCoord1ivARB
, X_GLrop_MultiTexCoord2ivARB
,
1426 X_GLrop_MultiTexCoord3ivARB
, X_GLrop_MultiTexCoord4ivARB
1428 static const uint16_t mfloat_ops
[5] = {
1429 0, X_GLrop_MultiTexCoord1fvARB
, X_GLrop_MultiTexCoord2fvARB
,
1430 X_GLrop_MultiTexCoord3fvARB
, X_GLrop_MultiTexCoord4fvARB
1432 static const uint16_t mdouble_ops
[5] = {
1433 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2dvARB
,
1434 X_GLrop_MultiTexCoord3dvARB
, X_GLrop_MultiTexCoord4dvARB
1438 struct glx_context
*gc
= __glXGetCurrentContext();
1439 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1440 struct array_state_vector
*arrays
= state
->array_state
;
1441 struct array_state
*a
;
1442 unsigned header_size
;
1446 if (size
< 1 || size
> 4 || stride
< 0) {
1447 __glXSetError(gc
, GL_INVALID_VALUE
);
1451 index
= arrays
->active_texture_unit
;
1455 opcode
= short_ops
[size
];
1458 opcode
= int_ops
[size
];
1461 opcode
= float_ops
[size
];
1464 opcode
= double_ops
[size
];
1467 __glXSetError(gc
, GL_INVALID_ENUM
);
1476 opcode
= mshort_ops
[size
];
1479 opcode
= mint_ops
[size
];
1482 opcode
= mfloat_ops
[size
];
1485 opcode
= mdouble_ops
[size
];
1488 __glXSetError(gc
, GL_INVALID_ENUM
);
1495 a
= get_array_entry(arrays
, GL_TEXTURE_COORD_ARRAY
, index
);
1497 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_FALSE
,
1498 header_size
, opcode
);
1501 arrays
->array_info_cache_valid
= GL_FALSE
;
1507 __indirect_glSecondaryColorPointer(GLint size
, GLenum type
, GLsizei stride
,
1508 const GLvoid
* pointer
)
1511 struct glx_context
*gc
= __glXGetCurrentContext();
1512 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1513 struct array_state_vector
*arrays
= state
->array_state
;
1514 struct array_state
*a
;
1517 if (size
!= 3 || stride
< 0) {
1518 __glXSetError(gc
, GL_INVALID_VALUE
);
1526 case GL_UNSIGNED_BYTE
:
1532 case GL_UNSIGNED_SHORT
:
1538 case GL_UNSIGNED_INT
:
1548 __glXSetError(gc
, GL_INVALID_ENUM
);
1552 a
= get_array_entry(arrays
, GL_SECONDARY_COLOR_ARRAY
, 0);
1554 __glXSetError(gc
, GL_INVALID_OPERATION
);
1558 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_TRUE
, 4, opcode
);
1561 arrays
->array_info_cache_valid
= GL_FALSE
;
1567 __indirect_glFogCoordPointer(GLenum type
, GLsizei stride
,
1568 const GLvoid
* pointer
)
1571 struct glx_context
*gc
= __glXGetCurrentContext();
1572 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1573 struct array_state_vector
*arrays
= state
->array_state
;
1574 struct array_state
*a
;
1578 __glXSetError(gc
, GL_INVALID_VALUE
);
1590 __glXSetError(gc
, GL_INVALID_ENUM
);
1594 a
= get_array_entry(arrays
, GL_FOG_COORD_ARRAY
, 0);
1596 __glXSetError(gc
, GL_INVALID_OPERATION
);
1600 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 1, GL_FALSE
, 4, opcode
);
1603 arrays
->array_info_cache_valid
= GL_FALSE
;
1609 __indirect_glVertexAttribPointer(GLuint index
, GLint size
,
1610 GLenum type
, GLboolean normalized
,
1611 GLsizei stride
, const GLvoid
* pointer
)
1613 static const uint16_t short_ops
[5] = {
1614 0, X_GLrop_VertexAttrib1svARB
, X_GLrop_VertexAttrib2svARB
,
1615 X_GLrop_VertexAttrib3svARB
, X_GLrop_VertexAttrib4svARB
1617 static const uint16_t float_ops
[5] = {
1618 0, X_GLrop_VertexAttrib1fvARB
, X_GLrop_VertexAttrib2fvARB
,
1619 X_GLrop_VertexAttrib3fvARB
, X_GLrop_VertexAttrib4fvARB
1621 static const uint16_t double_ops
[5] = {
1622 0, X_GLrop_VertexAttrib1dvARB
, X_GLrop_VertexAttrib2dvARB
,
1623 X_GLrop_VertexAttrib3dvARB
, X_GLrop_VertexAttrib4dvARB
1627 struct glx_context
*gc
= __glXGetCurrentContext();
1628 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1629 struct array_state_vector
*arrays
= state
->array_state
;
1630 struct array_state
*a
;
1631 unsigned true_immediate_count
;
1632 unsigned true_immediate_size
;
1635 if ((size
< 1) || (size
> 4) || (stride
< 0)
1636 || (index
> arrays
->num_vertex_program_attribs
)) {
1637 __glXSetError(gc
, GL_INVALID_VALUE
);
1641 if (normalized
&& (type
!= GL_FLOAT
) && (type
!= GL_DOUBLE
)) {
1644 opcode
= X_GLrop_VertexAttrib4NbvARB
;
1646 case GL_UNSIGNED_BYTE
:
1647 opcode
= X_GLrop_VertexAttrib4NubvARB
;
1650 opcode
= X_GLrop_VertexAttrib4NsvARB
;
1652 case GL_UNSIGNED_SHORT
:
1653 opcode
= X_GLrop_VertexAttrib4NusvARB
;
1656 opcode
= X_GLrop_VertexAttrib4NivARB
;
1658 case GL_UNSIGNED_INT
:
1659 opcode
= X_GLrop_VertexAttrib4NuivARB
;
1662 __glXSetError(gc
, GL_INVALID_ENUM
);
1666 true_immediate_count
= 4;
1669 true_immediate_count
= size
;
1673 opcode
= X_GLrop_VertexAttrib4bvARB
;
1674 true_immediate_count
= 4;
1676 case GL_UNSIGNED_BYTE
:
1677 opcode
= X_GLrop_VertexAttrib4ubvARB
;
1678 true_immediate_count
= 4;
1681 opcode
= short_ops
[size
];
1683 case GL_UNSIGNED_SHORT
:
1684 opcode
= X_GLrop_VertexAttrib4usvARB
;
1685 true_immediate_count
= 4;
1688 opcode
= X_GLrop_VertexAttrib4ivARB
;
1689 true_immediate_count
= 4;
1691 case GL_UNSIGNED_INT
:
1692 opcode
= X_GLrop_VertexAttrib4uivARB
;
1693 true_immediate_count
= 4;
1696 opcode
= float_ops
[size
];
1699 opcode
= double_ops
[size
];
1702 __glXSetError(gc
, GL_INVALID_ENUM
);
1707 a
= get_array_entry(arrays
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, index
);
1709 __glXSetError(gc
, GL_INVALID_OPERATION
);
1713 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, normalized
, 8,
1716 true_immediate_size
= __glXTypeSize(type
) * true_immediate_count
;
1717 a
->header
[0] = __GLX_PAD(8 + true_immediate_size
);
1720 arrays
->array_info_cache_valid
= GL_FALSE
;
1726 * I don't have 100% confidence that this is correct. The different rules
1727 * about whether or not generic vertex attributes alias "classic" vertex
1728 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1729 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1730 * feeling is that the client-side doesn't have to worry about it. The
1731 * client just sends all the data to the server and lets the server deal
1735 __indirect_glVertexAttribPointerNV(GLuint index
, GLint size
,
1736 GLenum type
, GLsizei stride
,
1737 const GLvoid
* pointer
)
1739 struct glx_context
*gc
= __glXGetCurrentContext();
1740 GLboolean normalized
= GL_FALSE
;
1744 case GL_UNSIGNED_BYTE
:
1746 __glXSetError(gc
, GL_INVALID_VALUE
);
1749 normalized
= GL_TRUE
;
1754 __indirect_glVertexAttribPointer(index
, size
, type
,
1755 normalized
, stride
, pointer
);
1758 __glXSetError(gc
, GL_INVALID_ENUM
);
1765 __indirect_glClientActiveTexture(GLenum texture
)
1767 struct glx_context
*const gc
= __glXGetCurrentContext();
1768 __GLXattribute
*const state
=
1769 (__GLXattribute
*) (gc
->client_state_private
);
1770 struct array_state_vector
*const arrays
= state
->array_state
;
1771 const GLint unit
= (GLint
) texture
- GL_TEXTURE0
;
1774 if ((unit
< 0) || (unit
>= arrays
->num_texture_units
)) {
1775 __glXSetError(gc
, GL_INVALID_ENUM
);
1779 arrays
->active_texture_unit
= unit
;
1784 * Modify the enable state for the selected array
1787 __glXSetArrayEnable(__GLXattribute
* state
, GLenum key
, unsigned index
,
1790 struct array_state_vector
*arrays
= state
->array_state
;
1791 struct array_state
*a
;
1794 /* Texture coordinate arrays have an implict index set when the
1795 * application calls glClientActiveTexture.
1797 if (key
== GL_TEXTURE_COORD_ARRAY
) {
1798 index
= arrays
->active_texture_unit
;
1801 a
= get_array_entry(arrays
, key
, index
);
1803 if ((a
!= NULL
) && (a
->enabled
!= enable
)) {
1804 a
->enabled
= enable
;
1805 arrays
->array_info_cache_valid
= GL_FALSE
;
1813 __glXArrayDisableAll(__GLXattribute
* state
)
1815 struct array_state_vector
*arrays
= state
->array_state
;
1819 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1820 arrays
->arrays
[i
].enabled
= GL_FALSE
;
1823 arrays
->array_info_cache_valid
= GL_FALSE
;
1830 __glXGetArrayEnable(const __GLXattribute
* const state
,
1831 GLenum key
, unsigned index
, GLintptr
* dest
)
1833 const struct array_state_vector
*arrays
= state
->array_state
;
1834 const struct array_state
*a
=
1835 get_array_entry((struct array_state_vector
*) arrays
,
1839 *dest
= (GLintptr
) a
->enabled
;
1849 __glXGetArrayType(const __GLXattribute
* const state
,
1850 GLenum key
, unsigned index
, GLintptr
* dest
)
1852 const struct array_state_vector
*arrays
= state
->array_state
;
1853 const struct array_state
*a
=
1854 get_array_entry((struct array_state_vector
*) arrays
,
1858 *dest
= (GLintptr
) a
->data_type
;
1868 __glXGetArraySize(const __GLXattribute
* const state
,
1869 GLenum key
, unsigned index
, GLintptr
* dest
)
1871 const struct array_state_vector
*arrays
= state
->array_state
;
1872 const struct array_state
*a
=
1873 get_array_entry((struct array_state_vector
*) arrays
,
1877 *dest
= (GLintptr
) a
->count
;
1887 __glXGetArrayStride(const __GLXattribute
* const state
,
1888 GLenum key
, unsigned index
, GLintptr
* dest
)
1890 const struct array_state_vector
*arrays
= state
->array_state
;
1891 const struct array_state
*a
=
1892 get_array_entry((struct array_state_vector
*) arrays
,
1896 *dest
= (GLintptr
) a
->user_stride
;
1906 __glXGetArrayPointer(const __GLXattribute
* const state
,
1907 GLenum key
, unsigned index
, void **dest
)
1909 const struct array_state_vector
*arrays
= state
->array_state
;
1910 const struct array_state
*a
=
1911 get_array_entry((struct array_state_vector
*) arrays
,
1916 *dest
= (void *) (a
->data
);
1926 __glXGetArrayNormalized(const __GLXattribute
* const state
,
1927 GLenum key
, unsigned index
, GLintptr
* dest
)
1929 const struct array_state_vector
*arrays
= state
->array_state
;
1930 const struct array_state
*a
=
1931 get_array_entry((struct array_state_vector
*) arrays
,
1936 *dest
= (GLintptr
) a
->normalized
;
1946 __glXGetActiveTextureUnit(const __GLXattribute
* const state
)
1948 return state
->array_state
->active_texture_unit
;
1953 __glXPushArrayState(__GLXattribute
* state
)
1955 struct array_state_vector
*arrays
= state
->array_state
;
1956 struct array_stack_state
*stack
=
1957 &arrays
->stack
[(arrays
->stack_index
* arrays
->num_arrays
)];
1960 /* XXX are we pushing _all_ the necessary fields? */
1961 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1962 stack
[i
].data
= arrays
->arrays
[i
].data
;
1963 stack
[i
].data_type
= arrays
->arrays
[i
].data_type
;
1964 stack
[i
].user_stride
= arrays
->arrays
[i
].user_stride
;
1965 stack
[i
].count
= arrays
->arrays
[i
].count
;
1966 stack
[i
].key
= arrays
->arrays
[i
].key
;
1967 stack
[i
].index
= arrays
->arrays
[i
].index
;
1968 stack
[i
].enabled
= arrays
->arrays
[i
].enabled
;
1971 arrays
->active_texture_unit_stack
[arrays
->stack_index
] =
1972 arrays
->active_texture_unit
;
1974 arrays
->stack_index
++;
1979 __glXPopArrayState(__GLXattribute
* state
)
1981 struct array_state_vector
*arrays
= state
->array_state
;
1982 struct array_stack_state
*stack
;
1986 arrays
->stack_index
--;
1987 stack
= &arrays
->stack
[(arrays
->stack_index
* arrays
->num_arrays
)];
1989 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1990 switch (stack
[i
].key
) {
1991 case GL_NORMAL_ARRAY
:
1992 __indirect_glNormalPointer(stack
[i
].data_type
,
1993 stack
[i
].user_stride
, stack
[i
].data
);
1995 case GL_COLOR_ARRAY
:
1996 __indirect_glColorPointer(stack
[i
].count
,
1998 stack
[i
].user_stride
, stack
[i
].data
);
2000 case GL_INDEX_ARRAY
:
2001 __indirect_glIndexPointer(stack
[i
].data_type
,
2002 stack
[i
].user_stride
, stack
[i
].data
);
2004 case GL_EDGE_FLAG_ARRAY
:
2005 __indirect_glEdgeFlagPointer(stack
[i
].user_stride
, stack
[i
].data
);
2007 case GL_TEXTURE_COORD_ARRAY
:
2008 arrays
->active_texture_unit
= stack
[i
].index
;
2009 __indirect_glTexCoordPointer(stack
[i
].count
,
2011 stack
[i
].user_stride
, stack
[i
].data
);
2013 case GL_SECONDARY_COLOR_ARRAY
:
2014 __indirect_glSecondaryColorPointer(stack
[i
].count
,
2016 stack
[i
].user_stride
,
2019 case GL_FOG_COORDINATE_ARRAY
:
2020 __indirect_glFogCoordPointer(stack
[i
].data_type
,
2021 stack
[i
].user_stride
, stack
[i
].data
);
2026 __glXSetArrayEnable(state
, stack
[i
].key
, stack
[i
].index
,
2030 arrays
->active_texture_unit
=
2031 arrays
->active_texture_unit_stack
[arrays
->stack_index
];