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(__GLXcontext
* gc
, GLenum mode
);
88 static GLboolean
validate_count(__GLXcontext
* gc
, GLsizei count
);
89 static GLboolean
validate_type(__GLXcontext
* 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(__GLXcontext
* gc
)
114 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
115 struct array_state_vector
*arrays
= state
->array_state
;
120 arrays
->stack
= NULL
;
122 if (arrays
->arrays
) {
123 free(arrays
->arrays
);
124 arrays
->arrays
= NULL
;
127 state
->array_state
= NULL
;
133 * Initialize vertex array state of a GLX context.
135 * \param gc GLX context whose vertex array state is to be initialized.
138 * This function may only be called after __GLXcontext::gl_extension_bits,
139 * __GLXcontext::server_minor, and __GLXcontext::server_major have been
140 * initialized. These values are used to determine what vertex arrays are
144 * Return values from malloc are not properly tested.
147 __glXInitVertexArrayState(__GLXcontext
* gc
)
149 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
150 struct array_state_vector
*arrays
;
152 unsigned array_count
;
153 int texture_units
= 1, vertex_program_attribs
= 0;
156 GLboolean got_fog
= GL_FALSE
;
157 GLboolean got_secondary_color
= GL_FALSE
;
160 arrays
= calloc(1, sizeof(struct array_state_vector
));
161 state
->array_state
= arrays
;
163 arrays
->old_DrawArrays_possible
= !state
->NoDrawArraysProtocol
;
164 arrays
->new_DrawArrays_possible
= GL_FALSE
;
165 arrays
->DrawArrays
= NULL
;
167 arrays
->active_texture_unit
= 0;
170 /* Determine how many arrays are actually needed. Only arrays that
171 * are supported by the server are create. For example, if the server
172 * supports only 2 texture units, then only 2 texture coordinate arrays
175 * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
176 * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
177 * GL_EDGE_FLAG_ARRAY are supported.
182 if (__glExtensionBitIsEnabled(gc
, GL_EXT_fog_coord_bit
)
183 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4)) {
188 if (__glExtensionBitIsEnabled(gc
, GL_EXT_secondary_color_bit
)
189 || (gc
->server_major
> 1) || (gc
->server_minor
>= 4)) {
190 got_secondary_color
= GL_TRUE
;
194 if (__glExtensionBitIsEnabled(gc
, GL_ARB_multitexture_bit
)
195 || (gc
->server_major
> 1) || (gc
->server_minor
>= 3)) {
196 __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS
, &texture_units
);
199 if (__glExtensionBitIsEnabled(gc
, GL_ARB_vertex_program_bit
)) {
200 __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB
,
201 GL_MAX_PROGRAM_ATTRIBS_ARB
,
202 &vertex_program_attribs
);
205 arrays
->num_texture_units
= texture_units
;
206 arrays
->num_vertex_program_attribs
= vertex_program_attribs
;
207 array_count
+= texture_units
+ vertex_program_attribs
;
208 arrays
->num_arrays
= array_count
;
209 arrays
->arrays
= calloc(array_count
, sizeof(struct array_state
));
211 arrays
->arrays
[0].data_type
= GL_FLOAT
;
212 arrays
->arrays
[0].count
= 3;
213 arrays
->arrays
[0].key
= GL_NORMAL_ARRAY
;
214 arrays
->arrays
[0].normalized
= GL_TRUE
;
215 arrays
->arrays
[0].old_DrawArrays_possible
= GL_TRUE
;
217 arrays
->arrays
[1].data_type
= GL_FLOAT
;
218 arrays
->arrays
[1].count
= 4;
219 arrays
->arrays
[1].key
= GL_COLOR_ARRAY
;
220 arrays
->arrays
[1].normalized
= GL_TRUE
;
221 arrays
->arrays
[1].old_DrawArrays_possible
= GL_TRUE
;
223 arrays
->arrays
[2].data_type
= GL_FLOAT
;
224 arrays
->arrays
[2].count
= 1;
225 arrays
->arrays
[2].key
= GL_INDEX_ARRAY
;
226 arrays
->arrays
[2].old_DrawArrays_possible
= GL_TRUE
;
228 arrays
->arrays
[3].data_type
= GL_UNSIGNED_BYTE
;
229 arrays
->arrays
[3].count
= 1;
230 arrays
->arrays
[3].key
= GL_EDGE_FLAG_ARRAY
;
231 arrays
->arrays
[3].old_DrawArrays_possible
= GL_TRUE
;
233 for (i
= 0; i
< texture_units
; i
++) {
234 arrays
->arrays
[4 + i
].data_type
= GL_FLOAT
;
235 arrays
->arrays
[4 + i
].count
= 4;
236 arrays
->arrays
[4 + i
].key
= GL_TEXTURE_COORD_ARRAY
;
238 arrays
->arrays
[4 + i
].old_DrawArrays_possible
= (i
== 0);
239 arrays
->arrays
[4 + i
].index
= i
;
241 arrays
->arrays
[4 + i
].header
[1] = i
+ GL_TEXTURE0
;
244 i
= 4 + texture_units
;
247 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
248 arrays
->arrays
[i
].count
= 1;
249 arrays
->arrays
[i
].key
= GL_FOG_COORDINATE_ARRAY
;
250 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
254 if (got_secondary_color
) {
255 arrays
->arrays
[i
].data_type
= GL_FLOAT
;
256 arrays
->arrays
[i
].count
= 3;
257 arrays
->arrays
[i
].key
= GL_SECONDARY_COLOR_ARRAY
;
258 arrays
->arrays
[i
].old_DrawArrays_possible
= GL_TRUE
;
259 arrays
->arrays
[i
].normalized
= GL_TRUE
;
264 for (j
= 0; j
< vertex_program_attribs
; j
++) {
265 const unsigned idx
= (vertex_program_attribs
- (j
+ 1));
268 arrays
->arrays
[idx
+ i
].data_type
= GL_FLOAT
;
269 arrays
->arrays
[idx
+ i
].count
= 4;
270 arrays
->arrays
[idx
+ i
].key
= GL_VERTEX_ATTRIB_ARRAY_POINTER
;
272 arrays
->arrays
[idx
+ i
].old_DrawArrays_possible
= 0;
273 arrays
->arrays
[idx
+ i
].index
= idx
;
275 arrays
->arrays
[idx
+ i
].header
[1] = idx
;
278 i
+= vertex_program_attribs
;
281 /* Vertex array *must* be last becuase 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
)
294 * arrays
->num_arrays
);
299 * Calculate the size of a single vertex for the "none" protocol. This is
300 * essentially the size of all the immediate-mode commands required to
301 * implement the enabled vertex arrays.
304 calculate_single_vertex_size_none(const struct array_state_vector
*arrays
)
306 size_t single_vertex_size
= 0;
310 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
311 if (arrays
->arrays
[i
].enabled
) {
312 single_vertex_size
+= ((uint16_t *) arrays
->arrays
[i
].header
)[0];
316 return single_vertex_size
;
321 * Emit a single element using non-DrawArrays protocol.
324 emit_element_none(GLubyte
* dst
,
325 const struct array_state_vector
* arrays
, unsigned index
)
330 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
331 if (arrays
->arrays
[i
].enabled
) {
332 const size_t offset
= index
* arrays
->arrays
[i
].true_stride
;
334 /* The generic attributes can have more data than is in the
335 * elements. This is because a vertex array can be a 2 element,
336 * normalized, unsigned short, but the "closest" immediate mode
337 * protocol is for a 4Nus. Since the sizes are small, the
338 * performance impact on modern processors should be negligible.
340 (void) memset(dst
, 0, ((uint16_t *) arrays
->arrays
[i
].header
)[0]);
342 (void) memcpy(dst
, arrays
->arrays
[i
].header
,
343 arrays
->arrays
[i
].header_size
);
345 dst
+= arrays
->arrays
[i
].header_size
;
347 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
348 arrays
->arrays
[i
].element_size
);
350 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
359 * Emit a single element using "old" DrawArrays protocol from
360 * EXT_vertex_arrays / OpenGL 1.1.
363 emit_element_old(GLubyte
* dst
,
364 const struct array_state_vector
* arrays
, unsigned index
)
369 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
370 if (arrays
->arrays
[i
].enabled
) {
371 const size_t offset
= index
* arrays
->arrays
[i
].true_stride
;
373 (void) memcpy(dst
, ((GLubyte
*) arrays
->arrays
[i
].data
) + offset
,
374 arrays
->arrays
[i
].element_size
);
376 dst
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
385 get_array_entry(const struct array_state_vector
*arrays
,
386 GLenum key
, unsigned index
)
390 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
391 if ((arrays
->arrays
[i
].key
== key
)
392 && (arrays
->arrays
[i
].index
== index
)) {
393 return &arrays
->arrays
[i
];
402 allocate_array_info_cache(struct array_state_vector
*arrays
,
403 size_t required_size
)
405 #define MAX_HEADER_SIZE 20
406 if (arrays
->array_info_cache_buffer_size
< required_size
) {
407 GLubyte
*temp
= realloc(arrays
->array_info_cache_base
,
408 required_size
+ MAX_HEADER_SIZE
);
414 arrays
->array_info_cache_base
= temp
;
415 arrays
->array_info_cache
= temp
+ MAX_HEADER_SIZE
;
416 arrays
->array_info_cache_buffer_size
= required_size
;
419 arrays
->array_info_cache_size
= required_size
;
427 fill_array_info_cache(struct array_state_vector
*arrays
)
429 GLboolean old_DrawArrays_possible
;
433 /* Determine how many arrays are enabled.
436 arrays
->enabled_client_array_count
= 0;
437 old_DrawArrays_possible
= arrays
->old_DrawArrays_possible
;
438 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
439 if (arrays
->arrays
[i
].enabled
) {
440 arrays
->enabled_client_array_count
++;
441 old_DrawArrays_possible
&= arrays
->arrays
[i
].old_DrawArrays_possible
;
445 if (arrays
->new_DrawArrays_possible
) {
446 assert(!arrays
->new_DrawArrays_possible
);
448 else if (old_DrawArrays_possible
) {
449 const size_t required_size
= arrays
->enabled_client_array_count
* 12;
453 if (!allocate_array_info_cache(arrays
, required_size
)) {
458 info
= (uint32_t *) arrays
->array_info_cache
;
459 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
460 if (arrays
->arrays
[i
].enabled
) {
461 *(info
++) = arrays
->arrays
[i
].data_type
;
462 *(info
++) = arrays
->arrays
[i
].count
;
463 *(info
++) = arrays
->arrays
[i
].key
;
467 arrays
->DrawArrays
= emit_DrawArrays_old
;
468 arrays
->DrawElements
= emit_DrawElements_old
;
471 arrays
->DrawArrays
= emit_DrawArrays_none
;
472 arrays
->DrawElements
= emit_DrawElements_none
;
475 arrays
->array_info_cache_valid
= GL_TRUE
;
480 * Emit a \c glDrawArrays command using the "none" protocol. That is,
481 * emit immediate-mode commands that are equivalent to the requiested
482 * \c glDrawArrays command. This is used with servers that don't support
483 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
484 * vertex state is enabled that is not compatible with that protocol.
487 emit_DrawArrays_none(GLenum mode
, GLint first
, GLsizei count
)
489 __GLXcontext
*gc
= __glXGetCurrentContext();
490 const __GLXattribute
*state
=
491 (const __GLXattribute
*) (gc
->client_state_private
);
492 struct array_state_vector
*arrays
= state
->array_state
;
494 size_t single_vertex_size
;
497 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
498 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
501 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
505 (void) memcpy(pc
, begin_cmd
, 4);
506 *(int *) (pc
+ 4) = mode
;
510 for (i
= 0; i
< count
; i
++) {
511 if ((pc
+ single_vertex_size
) >= gc
->bufEnd
) {
512 pc
= __glXFlushRenderBuffer(gc
, pc
);
515 pc
= emit_element_none(pc
, arrays
, first
+ i
);
518 if ((pc
+ 4) >= gc
->bufEnd
) {
519 pc
= __glXFlushRenderBuffer(gc
, pc
);
522 (void) memcpy(pc
, end_cmd
, 4);
526 if (gc
->pc
> gc
->limit
) {
527 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
533 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
536 * \param gc GLX context.
537 * \param arrays Array state.
538 * \param elements_per_request Location to store the number of elements that
539 * can fit in a single Render / RenderLarge
541 * \param total_request Total number of requests for a RenderLarge
542 * command. If a Render command is used, this
544 * \param mode Drawing mode.
545 * \param count Number of vertices.
548 * A pointer to the buffer for array data.
551 emit_DrawArrays_header_old(__GLXcontext
* gc
,
552 struct array_state_vector
*arrays
,
553 size_t * elements_per_request
,
554 unsigned int *total_requests
,
555 GLenum mode
, GLsizei count
)
558 size_t single_vertex_size
;
559 const unsigned header_size
= 16;
564 /* Determine the size of the whole command. This includes the header,
565 * the ARRAY_INFO data and the array data. Once this size is calculated,
566 * it will be known whether a Render or RenderLarge command is needed.
569 single_vertex_size
= 0;
570 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
571 if (arrays
->arrays
[i
].enabled
) {
572 single_vertex_size
+= __GLX_PAD(arrays
->arrays
[i
].element_size
);
576 command_size
= arrays
->array_info_cache_size
+ header_size
577 + (single_vertex_size
* count
);
580 /* Write the header for either a Render command or a RenderLarge
581 * command. After the header is written, write the ARRAY_INFO data.
584 if (command_size
> gc
->maxSmallRenderCommandSize
) {
585 /* maxSize is the maximum amount of data can be stuffed into a single
586 * packet. sz_xGLXRenderReq is added because bufSize is the maximum
587 * packet size minus sz_xGLXRenderReq.
589 const size_t maxSize
= (gc
->bufSize
+ sz_xGLXRenderReq
)
590 - sz_xGLXRenderLargeReq
;
591 unsigned vertex_requests
;
594 /* Calculate the number of data packets that will be required to send
595 * the whole command. To do this, the number of verticies that
596 * will fit in a single buffer must be calculated.
598 * The important value here is elements_per_request. This is the
599 * number of complete array elements that will fit in a single
600 * buffer. There may be some wasted space at the end of the buffer,
601 * but splitting elements across buffer boundries would be painful.
604 elements_per_request
[0] = maxSize
/ single_vertex_size
;
606 vertex_requests
= (count
+ elements_per_request
[0] - 1)
607 / elements_per_request
[0];
609 *total_requests
= vertex_requests
+ 1;
612 __glXFlushRenderBuffer(gc
, gc
->pc
);
616 pc
= ((GLubyte
*) arrays
->array_info_cache
) - (header_size
+ 4);
617 *(uint32_t *) (pc
+ 0) = command_size
;
618 *(uint32_t *) (pc
+ 4) = X_GLrop_DrawArrays
;
619 *(uint32_t *) (pc
+ 8) = count
;
620 *(uint32_t *) (pc
+ 12) = arrays
->enabled_client_array_count
;
621 *(uint32_t *) (pc
+ 16) = mode
;
623 __glXSendLargeChunk(gc
, 1, *total_requests
, pc
,
624 header_size
+ 4 + arrays
->array_info_cache_size
);
629 if ((gc
->pc
+ command_size
) >= gc
->bufEnd
) {
630 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
634 *(uint16_t *) (pc
+ 0) = command_size
;
635 *(uint16_t *) (pc
+ 2) = X_GLrop_DrawArrays
;
636 *(uint32_t *) (pc
+ 4) = count
;
637 *(uint32_t *) (pc
+ 8) = arrays
->enabled_client_array_count
;
638 *(uint32_t *) (pc
+ 12) = mode
;
642 (void) memcpy(pc
, arrays
->array_info_cache
,
643 arrays
->array_info_cache_size
);
644 pc
+= arrays
->array_info_cache_size
;
646 *elements_per_request
= count
;
658 emit_DrawArrays_old(GLenum mode
, GLint first
, GLsizei count
)
660 __GLXcontext
*gc
= __glXGetCurrentContext();
661 const __GLXattribute
*state
=
662 (const __GLXattribute
*) (gc
->client_state_private
);
663 struct array_state_vector
*arrays
= state
->array_state
;
666 size_t elements_per_request
;
667 unsigned total_requests
= 0;
669 size_t total_sent
= 0;
672 pc
= emit_DrawArrays_header_old(gc
, arrays
, &elements_per_request
,
673 &total_requests
, mode
, count
);
679 if (total_requests
== 0) {
680 assert(elements_per_request
>= count
);
682 for (i
= 0; i
< count
; i
++) {
683 pc
= emit_element_old(pc
, arrays
, i
+ first
);
686 assert(pc
<= gc
->bufEnd
);
689 if (gc
->pc
> gc
->limit
) {
690 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
697 for (req
= 2; req
<= total_requests
; req
++) {
698 if (count
< elements_per_request
) {
699 elements_per_request
= count
;
703 for (i
= 0; i
< elements_per_request
; i
++) {
704 pc
= emit_element_old(pc
, arrays
, i
+ first
);
707 first
+= elements_per_request
;
709 total_sent
+= (size_t) (pc
- gc
->pc
);
710 __glXSendLargeChunk(gc
, req
, total_requests
, gc
->pc
, pc
- gc
->pc
);
712 count
-= elements_per_request
;
719 emit_DrawElements_none(GLenum mode
, GLsizei count
, GLenum type
,
720 const GLvoid
* indices
)
722 __GLXcontext
*gc
= __glXGetCurrentContext();
723 const __GLXattribute
*state
=
724 (const __GLXattribute
*) (gc
->client_state_private
);
725 struct array_state_vector
*arrays
= state
->array_state
;
726 static const uint16_t begin_cmd
[2] = { 8, X_GLrop_Begin
};
727 static const uint16_t end_cmd
[2] = { 4, X_GLrop_End
};
730 size_t single_vertex_size
;
734 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
737 if ((gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
738 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
743 (void) memcpy(pc
, begin_cmd
, 4);
744 *(int *) (pc
+ 4) = mode
;
748 for (i
= 0; i
< count
; i
++) {
751 if ((pc
+ single_vertex_size
) >= gc
->bufEnd
) {
752 pc
= __glXFlushRenderBuffer(gc
, pc
);
756 case GL_UNSIGNED_INT
:
757 index
= (unsigned) (((GLuint
*) indices
)[i
]);
759 case GL_UNSIGNED_SHORT
:
760 index
= (unsigned) (((GLushort
*) indices
)[i
]);
762 case GL_UNSIGNED_BYTE
:
763 index
= (unsigned) (((GLubyte
*) indices
)[i
]);
766 pc
= emit_element_none(pc
, arrays
, index
);
769 if ((pc
+ 4) >= gc
->bufEnd
) {
770 pc
= __glXFlushRenderBuffer(gc
, pc
);
773 (void) memcpy(pc
, end_cmd
, 4);
777 if (gc
->pc
> gc
->limit
) {
778 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
786 emit_DrawElements_old(GLenum mode
, GLsizei count
, GLenum type
,
787 const GLvoid
* indices
)
789 __GLXcontext
*gc
= __glXGetCurrentContext();
790 const __GLXattribute
*state
=
791 (const __GLXattribute
*) (gc
->client_state_private
);
792 struct array_state_vector
*arrays
= state
->array_state
;
795 size_t elements_per_request
;
796 unsigned total_requests
= 0;
799 unsigned req_element
= 0;
802 pc
= emit_DrawArrays_header_old(gc
, arrays
, &elements_per_request
,
803 &total_requests
, mode
, count
);
811 if (count
< elements_per_request
) {
812 elements_per_request
= count
;
816 case GL_UNSIGNED_INT
:{
817 const GLuint
*ui_ptr
= (const GLuint
*) indices
+ req_element
;
819 for (i
= 0; i
< elements_per_request
; i
++) {
820 const GLint index
= (GLint
) * (ui_ptr
++);
821 pc
= emit_element_old(pc
, arrays
, index
);
825 case GL_UNSIGNED_SHORT
:{
826 const GLushort
*us_ptr
= (const GLushort
*) indices
+ req_element
;
828 for (i
= 0; i
< elements_per_request
; i
++) {
829 const GLint index
= (GLint
) * (us_ptr
++);
830 pc
= emit_element_old(pc
, arrays
, index
);
834 case GL_UNSIGNED_BYTE
:{
835 const GLubyte
*ub_ptr
= (const GLubyte
*) indices
+ req_element
;
837 for (i
= 0; i
< elements_per_request
; i
++) {
838 const GLint index
= (GLint
) * (ub_ptr
++);
839 pc
= emit_element_old(pc
, arrays
, index
);
845 if (total_requests
!= 0) {
846 __glXSendLargeChunk(gc
, req
, total_requests
, gc
->pc
, pc
- gc
->pc
);
851 count
-= elements_per_request
;
852 req_element
+= elements_per_request
;
856 assert((total_requests
== 0) || ((req
- 1) == total_requests
));
858 if (total_requests
== 0) {
859 assert(pc
<= gc
->bufEnd
);
862 if (gc
->pc
> gc
->limit
) {
863 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
870 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
871 * If it is not valid, then an error code is set in the GLX context.
874 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
877 validate_mode(__GLXcontext
* gc
, GLenum mode
)
884 case GL_TRIANGLE_STRIP
:
885 case GL_TRIANGLE_FAN
:
892 __glXSetError(gc
, GL_INVALID_ENUM
);
901 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
902 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
903 * being set. A value of zero will not result in an error being set, but
904 * will result in \c GL_FALSE being returned.
907 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
910 validate_count(__GLXcontext
* gc
, GLsizei count
)
913 __glXSetError(gc
, GL_INVALID_VALUE
);
921 * Validate that the \c type parameter to \c glDrawElements, et. al. is
922 * valid. Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
923 * \c GL_UNSIGNED_INT are valid.
926 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
929 validate_type(__GLXcontext
* gc
, GLenum type
)
932 case GL_UNSIGNED_INT
:
933 case GL_UNSIGNED_SHORT
:
934 case GL_UNSIGNED_BYTE
:
937 __glXSetError(gc
, GL_INVALID_ENUM
);
944 __indirect_glDrawArrays(GLenum mode
, GLint first
, GLsizei count
)
946 __GLXcontext
*gc
= __glXGetCurrentContext();
947 const __GLXattribute
*state
=
948 (const __GLXattribute
*) (gc
->client_state_private
);
949 struct array_state_vector
*arrays
= state
->array_state
;
952 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)) {
953 if (!arrays
->array_info_cache_valid
) {
954 fill_array_info_cache(arrays
);
957 arrays
->DrawArrays(mode
, first
, count
);
963 __indirect_glArrayElement(GLint index
)
965 __GLXcontext
*gc
= __glXGetCurrentContext();
966 const __GLXattribute
*state
=
967 (const __GLXattribute
*) (gc
->client_state_private
);
968 struct array_state_vector
*arrays
= state
->array_state
;
970 size_t single_vertex_size
;
973 single_vertex_size
= calculate_single_vertex_size_none(arrays
);
975 if ((gc
->pc
+ single_vertex_size
) >= gc
->bufEnd
) {
976 gc
->pc
= __glXFlushRenderBuffer(gc
, gc
->pc
);
979 gc
->pc
= emit_element_none(gc
->pc
, arrays
, index
);
981 if (gc
->pc
> gc
->limit
) {
982 (void) __glXFlushRenderBuffer(gc
, gc
->pc
);
988 __indirect_glDrawElements(GLenum mode
, GLsizei count
, GLenum type
,
989 const GLvoid
* indices
)
991 __GLXcontext
*gc
= __glXGetCurrentContext();
992 const __GLXattribute
*state
=
993 (const __GLXattribute
*) (gc
->client_state_private
);
994 struct array_state_vector
*arrays
= state
->array_state
;
997 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)
998 && validate_type(gc
, type
)) {
999 if (!arrays
->array_info_cache_valid
) {
1000 fill_array_info_cache(arrays
);
1003 arrays
->DrawElements(mode
, count
, type
, indices
);
1009 __indirect_glDrawRangeElements(GLenum mode
, GLuint start
, GLuint end
,
1010 GLsizei count
, GLenum type
,
1011 const GLvoid
* indices
)
1013 __GLXcontext
*gc
= __glXGetCurrentContext();
1014 const __GLXattribute
*state
=
1015 (const __GLXattribute
*) (gc
->client_state_private
);
1016 struct array_state_vector
*arrays
= state
->array_state
;
1019 if (validate_mode(gc
, mode
) && validate_count(gc
, count
)
1020 && validate_type(gc
, type
)) {
1022 __glXSetError(gc
, GL_INVALID_VALUE
);
1026 if (!arrays
->array_info_cache_valid
) {
1027 fill_array_info_cache(arrays
);
1030 arrays
->DrawElements(mode
, count
, type
, indices
);
1036 __indirect_glMultiDrawArraysEXT(GLenum mode
, GLint
* first
, GLsizei
* count
,
1039 __GLXcontext
*gc
= __glXGetCurrentContext();
1040 const __GLXattribute
*state
=
1041 (const __GLXattribute
*) (gc
->client_state_private
);
1042 struct array_state_vector
*arrays
= state
->array_state
;
1046 if (validate_mode(gc
, mode
)) {
1047 if (!arrays
->array_info_cache_valid
) {
1048 fill_array_info_cache(arrays
);
1051 for (i
= 0; i
< primcount
; i
++) {
1052 if (validate_count(gc
, count
[i
])) {
1053 arrays
->DrawArrays(mode
, first
[i
], count
[i
]);
1061 __indirect_glMultiDrawElementsEXT(GLenum mode
, const GLsizei
* count
,
1062 GLenum type
, const GLvoid
** indices
,
1065 __GLXcontext
*gc
= __glXGetCurrentContext();
1066 const __GLXattribute
*state
=
1067 (const __GLXattribute
*) (gc
->client_state_private
);
1068 struct array_state_vector
*arrays
= state
->array_state
;
1072 if (validate_mode(gc
, mode
) && validate_type(gc
, type
)) {
1073 if (!arrays
->array_info_cache_valid
) {
1074 fill_array_info_cache(arrays
);
1077 for (i
= 0; i
< primcount
; i
++) {
1078 if (validate_count(gc
, count
[i
])) {
1079 arrays
->DrawElements(mode
, count
[i
], type
, indices
[i
]);
1086 #define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1089 (a)->data_type = TYPE; \
1090 (a)->user_stride = STRIDE; \
1091 (a)->count = COUNT; \
1092 (a)->normalized = NORMALIZED; \
1094 (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
1095 (a)->true_stride = (STRIDE == 0) \
1096 ? (a)->element_size : STRIDE; \
1098 (a)->header_size = HDR_SIZE; \
1099 ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
1100 ((uint16_t *) (a)->header)[1] = OPCODE; \
1105 __indirect_glVertexPointer(GLint size
, GLenum type
, GLsizei stride
,
1106 const GLvoid
* pointer
)
1108 static const uint16_t short_ops
[5] = {
1109 0, 0, X_GLrop_Vertex2sv
, X_GLrop_Vertex3sv
, X_GLrop_Vertex4sv
1111 static const uint16_t int_ops
[5] = {
1112 0, 0, X_GLrop_Vertex2iv
, X_GLrop_Vertex3iv
, X_GLrop_Vertex4iv
1114 static const uint16_t float_ops
[5] = {
1115 0, 0, X_GLrop_Vertex2fv
, X_GLrop_Vertex3fv
, X_GLrop_Vertex4fv
1117 static const uint16_t double_ops
[5] = {
1118 0, 0, X_GLrop_Vertex2dv
, X_GLrop_Vertex3dv
, X_GLrop_Vertex4dv
1121 __GLXcontext
*gc
= __glXGetCurrentContext();
1122 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1123 struct array_state_vector
*arrays
= state
->array_state
;
1124 struct array_state
*a
;
1127 if (size
< 2 || size
> 4 || stride
< 0) {
1128 __glXSetError(gc
, GL_INVALID_VALUE
);
1134 opcode
= short_ops
[size
];
1137 opcode
= int_ops
[size
];
1140 opcode
= float_ops
[size
];
1143 opcode
= double_ops
[size
];
1146 __glXSetError(gc
, GL_INVALID_ENUM
);
1150 a
= get_array_entry(arrays
, GL_VERTEX_ARRAY
, 0);
1152 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_FALSE
, 4,
1156 arrays
->array_info_cache_valid
= GL_FALSE
;
1162 __indirect_glNormalPointer(GLenum type
, GLsizei stride
,
1163 const GLvoid
* pointer
)
1166 __GLXcontext
*gc
= __glXGetCurrentContext();
1167 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1168 struct array_state_vector
*arrays
= state
->array_state
;
1169 struct array_state
*a
;
1173 __glXSetError(gc
, GL_INVALID_VALUE
);
1179 opcode
= X_GLrop_Normal3bv
;
1182 opcode
= X_GLrop_Normal3sv
;
1185 opcode
= X_GLrop_Normal3iv
;
1188 opcode
= X_GLrop_Normal3fv
;
1191 opcode
= X_GLrop_Normal3dv
;
1194 __glXSetError(gc
, GL_INVALID_ENUM
);
1198 a
= get_array_entry(arrays
, GL_NORMAL_ARRAY
, 0);
1200 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 3, GL_TRUE
, 4, opcode
);
1203 arrays
->array_info_cache_valid
= GL_FALSE
;
1209 __indirect_glColorPointer(GLint size
, GLenum type
, GLsizei stride
,
1210 const GLvoid
* pointer
)
1212 static const uint16_t byte_ops
[5] = {
1213 0, 0, 0, X_GLrop_Color3bv
, X_GLrop_Color4bv
1215 static const uint16_t ubyte_ops
[5] = {
1216 0, 0, 0, X_GLrop_Color3ubv
, X_GLrop_Color4ubv
1218 static const uint16_t short_ops
[5] = {
1219 0, 0, 0, X_GLrop_Color3sv
, X_GLrop_Color4sv
1221 static const uint16_t ushort_ops
[5] = {
1222 0, 0, 0, X_GLrop_Color3usv
, X_GLrop_Color4usv
1224 static const uint16_t int_ops
[5] = {
1225 0, 0, 0, X_GLrop_Color3iv
, X_GLrop_Color4iv
1227 static const uint16_t uint_ops
[5] = {
1228 0, 0, 0, X_GLrop_Color3uiv
, X_GLrop_Color4uiv
1230 static const uint16_t float_ops
[5] = {
1231 0, 0, 0, X_GLrop_Color3fv
, X_GLrop_Color4fv
1233 static const uint16_t double_ops
[5] = {
1234 0, 0, 0, X_GLrop_Color3dv
, X_GLrop_Color4dv
1237 __GLXcontext
*gc
= __glXGetCurrentContext();
1238 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1239 struct array_state_vector
*arrays
= state
->array_state
;
1240 struct array_state
*a
;
1243 if (size
< 3 || size
> 4 || stride
< 0) {
1244 __glXSetError(gc
, GL_INVALID_VALUE
);
1250 opcode
= byte_ops
[size
];
1252 case GL_UNSIGNED_BYTE
:
1253 opcode
= ubyte_ops
[size
];
1256 opcode
= short_ops
[size
];
1258 case GL_UNSIGNED_SHORT
:
1259 opcode
= ushort_ops
[size
];
1262 opcode
= int_ops
[size
];
1264 case GL_UNSIGNED_INT
:
1265 opcode
= uint_ops
[size
];
1268 opcode
= float_ops
[size
];
1271 opcode
= double_ops
[size
];
1274 __glXSetError(gc
, GL_INVALID_ENUM
);
1278 a
= get_array_entry(arrays
, GL_COLOR_ARRAY
, 0);
1280 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_TRUE
, 4, opcode
);
1283 arrays
->array_info_cache_valid
= GL_FALSE
;
1289 __indirect_glIndexPointer(GLenum type
, GLsizei stride
, const GLvoid
* pointer
)
1292 __GLXcontext
*gc
= __glXGetCurrentContext();
1293 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1294 struct array_state_vector
*arrays
= state
->array_state
;
1295 struct array_state
*a
;
1299 __glXSetError(gc
, GL_INVALID_VALUE
);
1304 case GL_UNSIGNED_BYTE
:
1305 opcode
= X_GLrop_Indexubv
;
1308 opcode
= X_GLrop_Indexsv
;
1311 opcode
= X_GLrop_Indexiv
;
1314 opcode
= X_GLrop_Indexfv
;
1317 opcode
= X_GLrop_Indexdv
;
1320 __glXSetError(gc
, GL_INVALID_ENUM
);
1324 a
= get_array_entry(arrays
, GL_INDEX_ARRAY
, 0);
1326 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 1, GL_FALSE
, 4, opcode
);
1329 arrays
->array_info_cache_valid
= GL_FALSE
;
1335 __indirect_glEdgeFlagPointer(GLsizei stride
, const GLvoid
* pointer
)
1337 __GLXcontext
*gc
= __glXGetCurrentContext();
1338 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1339 struct array_state_vector
*arrays
= state
->array_state
;
1340 struct array_state
*a
;
1344 __glXSetError(gc
, GL_INVALID_VALUE
);
1349 a
= get_array_entry(arrays
, GL_EDGE_FLAG_ARRAY
, 0);
1351 COMMON_ARRAY_DATA_INIT(a
, pointer
, GL_UNSIGNED_BYTE
, stride
, 1, GL_FALSE
,
1352 4, X_GLrop_EdgeFlagv
);
1355 arrays
->array_info_cache_valid
= GL_FALSE
;
1361 __indirect_glTexCoordPointer(GLint size
, GLenum type
, GLsizei stride
,
1362 const GLvoid
* pointer
)
1364 static const uint16_t short_ops
[5] = {
1365 0, X_GLrop_TexCoord1sv
, X_GLrop_TexCoord2sv
, X_GLrop_TexCoord3sv
,
1368 static const uint16_t int_ops
[5] = {
1369 0, X_GLrop_TexCoord1iv
, X_GLrop_TexCoord2iv
, X_GLrop_TexCoord3iv
,
1372 static const uint16_t float_ops
[5] = {
1373 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2fv
, X_GLrop_TexCoord3fv
,
1376 static const uint16_t double_ops
[5] = {
1377 0, X_GLrop_TexCoord1dv
, X_GLrop_TexCoord2dv
, X_GLrop_TexCoord3dv
,
1381 static const uint16_t mshort_ops
[5] = {
1382 0, X_GLrop_MultiTexCoord1svARB
, X_GLrop_MultiTexCoord2svARB
,
1383 X_GLrop_MultiTexCoord3svARB
, X_GLrop_MultiTexCoord4svARB
1385 static const uint16_t mint_ops
[5] = {
1386 0, X_GLrop_MultiTexCoord1ivARB
, X_GLrop_MultiTexCoord2ivARB
,
1387 X_GLrop_MultiTexCoord3ivARB
, X_GLrop_MultiTexCoord4ivARB
1389 static const uint16_t mfloat_ops
[5] = {
1390 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2fvARB
,
1391 X_GLrop_MultiTexCoord3fvARB
, X_GLrop_MultiTexCoord4fvARB
1393 static const uint16_t mdouble_ops
[5] = {
1394 0, X_GLrop_MultiTexCoord1dvARB
, X_GLrop_MultiTexCoord2dvARB
,
1395 X_GLrop_MultiTexCoord3dvARB
, X_GLrop_MultiTexCoord4dvARB
1399 __GLXcontext
*gc
= __glXGetCurrentContext();
1400 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1401 struct array_state_vector
*arrays
= state
->array_state
;
1402 struct array_state
*a
;
1403 unsigned header_size
;
1407 if (size
< 1 || size
> 4 || stride
< 0) {
1408 __glXSetError(gc
, GL_INVALID_VALUE
);
1412 index
= arrays
->active_texture_unit
;
1416 opcode
= short_ops
[size
];
1419 opcode
= int_ops
[size
];
1422 opcode
= float_ops
[size
];
1425 opcode
= double_ops
[size
];
1428 __glXSetError(gc
, GL_INVALID_ENUM
);
1437 opcode
= mshort_ops
[size
];
1440 opcode
= mint_ops
[size
];
1443 opcode
= mfloat_ops
[size
];
1446 opcode
= mdouble_ops
[size
];
1449 __glXSetError(gc
, GL_INVALID_ENUM
);
1456 a
= get_array_entry(arrays
, GL_TEXTURE_COORD_ARRAY
, index
);
1458 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_FALSE
,
1459 header_size
, opcode
);
1462 arrays
->array_info_cache_valid
= GL_FALSE
;
1468 __indirect_glSecondaryColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
,
1469 const GLvoid
* pointer
)
1472 __GLXcontext
*gc
= __glXGetCurrentContext();
1473 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1474 struct array_state_vector
*arrays
= state
->array_state
;
1475 struct array_state
*a
;
1478 if (size
!= 3 || stride
< 0) {
1479 __glXSetError(gc
, GL_INVALID_VALUE
);
1487 case GL_UNSIGNED_BYTE
:
1493 case GL_UNSIGNED_SHORT
:
1499 case GL_UNSIGNED_INT
:
1509 __glXSetError(gc
, GL_INVALID_ENUM
);
1513 a
= get_array_entry(arrays
, GL_SECONDARY_COLOR_ARRAY
, 0);
1515 __glXSetError(gc
, GL_INVALID_OPERATION
);
1519 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, GL_TRUE
, 4, opcode
);
1522 arrays
->array_info_cache_valid
= GL_FALSE
;
1528 __indirect_glFogCoordPointerEXT(GLenum type
, GLsizei stride
,
1529 const GLvoid
* pointer
)
1532 __GLXcontext
*gc
= __glXGetCurrentContext();
1533 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1534 struct array_state_vector
*arrays
= state
->array_state
;
1535 struct array_state
*a
;
1539 __glXSetError(gc
, GL_INVALID_VALUE
);
1551 __glXSetError(gc
, GL_INVALID_ENUM
);
1555 a
= get_array_entry(arrays
, GL_FOG_COORD_ARRAY
, 0);
1557 __glXSetError(gc
, GL_INVALID_OPERATION
);
1561 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, 1, GL_FALSE
, 4, opcode
);
1564 arrays
->array_info_cache_valid
= GL_FALSE
;
1570 __indirect_glVertexAttribPointerARB(GLuint index
, GLint size
,
1571 GLenum type
, GLboolean normalized
,
1572 GLsizei stride
, const GLvoid
* pointer
)
1574 static const uint16_t short_ops
[5] = { 0, 4189, 4190, 4191, 4192 };
1575 static const uint16_t float_ops
[5] = { 0, 4193, 4194, 4195, 4196 };
1576 static const uint16_t double_ops
[5] = { 0, 4197, 4198, 4199, 4200 };
1579 __GLXcontext
*gc
= __glXGetCurrentContext();
1580 __GLXattribute
*state
= (__GLXattribute
*) (gc
->client_state_private
);
1581 struct array_state_vector
*arrays
= state
->array_state
;
1582 struct array_state
*a
;
1583 unsigned true_immediate_count
;
1584 unsigned true_immediate_size
;
1587 if ((size
< 1) || (size
> 4) || (stride
< 0)
1588 || (index
> arrays
->num_vertex_program_attribs
)) {
1589 __glXSetError(gc
, GL_INVALID_VALUE
);
1593 if (normalized
&& (type
!= GL_FLOAT
) && (type
!= GL_DOUBLE
)) {
1596 opcode
= X_GLrop_VertexAttrib4NbvARB
;
1598 case GL_UNSIGNED_BYTE
:
1599 opcode
= X_GLrop_VertexAttrib4NubvARB
;
1602 opcode
= X_GLrop_VertexAttrib4NsvARB
;
1604 case GL_UNSIGNED_SHORT
:
1605 opcode
= X_GLrop_VertexAttrib4NusvARB
;
1608 opcode
= X_GLrop_VertexAttrib4NivARB
;
1610 case GL_UNSIGNED_INT
:
1611 opcode
= X_GLrop_VertexAttrib4NuivARB
;
1614 __glXSetError(gc
, GL_INVALID_ENUM
);
1618 true_immediate_count
= 4;
1621 true_immediate_count
= size
;
1625 opcode
= X_GLrop_VertexAttrib4bvARB
;
1626 true_immediate_count
= 4;
1628 case GL_UNSIGNED_BYTE
:
1629 opcode
= X_GLrop_VertexAttrib4ubvARB
;
1630 true_immediate_count
= 4;
1633 opcode
= short_ops
[size
];
1635 case GL_UNSIGNED_SHORT
:
1636 opcode
= X_GLrop_VertexAttrib4usvARB
;
1637 true_immediate_count
= 4;
1640 opcode
= X_GLrop_VertexAttrib4ivARB
;
1641 true_immediate_count
= 4;
1643 case GL_UNSIGNED_INT
:
1644 opcode
= X_GLrop_VertexAttrib4uivARB
;
1645 true_immediate_count
= 4;
1648 opcode
= float_ops
[size
];
1651 opcode
= double_ops
[size
];
1654 __glXSetError(gc
, GL_INVALID_ENUM
);
1659 a
= get_array_entry(arrays
, GL_VERTEX_ATTRIB_ARRAY_POINTER
, index
);
1661 __glXSetError(gc
, GL_INVALID_OPERATION
);
1665 COMMON_ARRAY_DATA_INIT(a
, pointer
, type
, stride
, size
, normalized
, 8,
1668 true_immediate_size
= __glXTypeSize(type
) * true_immediate_count
;
1669 ((uint16_t *) (a
)->header
)[0] = __GLX_PAD(a
->header_size
1670 + true_immediate_size
);
1673 arrays
->array_info_cache_valid
= GL_FALSE
;
1679 * I don't have 100% confidence that this is correct. The different rules
1680 * about whether or not generic vertex attributes alias "classic" vertex
1681 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1682 * ARB_vertex_shader, and NV_vertex_program are a bit confusing. My
1683 * feeling is that the client-side doesn't have to worry about it. The
1684 * client just sends all the data to the server and lets the server deal
1688 __indirect_glVertexAttribPointerNV(GLuint index
, GLint size
,
1689 GLenum type
, GLsizei stride
,
1690 const GLvoid
* pointer
)
1692 __GLXcontext
*gc
= __glXGetCurrentContext();
1693 GLboolean normalized
= GL_FALSE
;
1697 case GL_UNSIGNED_BYTE
:
1699 __glXSetError(gc
, GL_INVALID_VALUE
);
1702 normalized
= GL_TRUE
;
1707 __indirect_glVertexAttribPointerARB(index
, size
, type
,
1708 normalized
, stride
, pointer
);
1711 __glXSetError(gc
, GL_INVALID_ENUM
);
1718 __indirect_glClientActiveTextureARB(GLenum texture
)
1720 __GLXcontext
*const gc
= __glXGetCurrentContext();
1721 __GLXattribute
*const state
=
1722 (__GLXattribute
*) (gc
->client_state_private
);
1723 struct array_state_vector
*const arrays
= state
->array_state
;
1724 const GLint unit
= (GLint
) texture
- GL_TEXTURE0
;
1727 if ((unit
< 0) || (unit
>= arrays
->num_texture_units
)) {
1728 __glXSetError(gc
, GL_INVALID_ENUM
);
1732 arrays
->active_texture_unit
= unit
;
1737 * Modify the enable state for the selected array
1740 __glXSetArrayEnable(__GLXattribute
* state
, GLenum key
, unsigned index
,
1743 struct array_state_vector
*arrays
= state
->array_state
;
1744 struct array_state
*a
;
1747 /* Texture coordinate arrays have an implict index set when the
1748 * application calls glClientActiveTexture.
1750 if (key
== GL_TEXTURE_COORD_ARRAY
) {
1751 index
= arrays
->active_texture_unit
;
1754 a
= get_array_entry(arrays
, key
, index
);
1756 if ((a
!= NULL
) && (a
->enabled
!= enable
)) {
1757 a
->enabled
= enable
;
1758 arrays
->array_info_cache_valid
= GL_FALSE
;
1766 __glXArrayDisableAll(__GLXattribute
* state
)
1768 struct array_state_vector
*arrays
= state
->array_state
;
1772 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1773 arrays
->arrays
[i
].enabled
= GL_FALSE
;
1776 arrays
->array_info_cache_valid
= GL_FALSE
;
1783 __glXGetArrayEnable(const __GLXattribute
* const state
,
1784 GLenum key
, unsigned index
, GLintptr
* dest
)
1786 const struct array_state_vector
*arrays
= state
->array_state
;
1787 const struct array_state
*a
=
1788 get_array_entry((struct array_state_vector
*) arrays
,
1792 *dest
= (GLintptr
) a
->enabled
;
1802 __glXGetArrayType(const __GLXattribute
* const state
,
1803 GLenum key
, unsigned index
, GLintptr
* dest
)
1805 const struct array_state_vector
*arrays
= state
->array_state
;
1806 const struct array_state
*a
=
1807 get_array_entry((struct array_state_vector
*) arrays
,
1811 *dest
= (GLintptr
) a
->data_type
;
1821 __glXGetArraySize(const __GLXattribute
* const state
,
1822 GLenum key
, unsigned index
, GLintptr
* dest
)
1824 const struct array_state_vector
*arrays
= state
->array_state
;
1825 const struct array_state
*a
=
1826 get_array_entry((struct array_state_vector
*) arrays
,
1830 *dest
= (GLintptr
) a
->count
;
1840 __glXGetArrayStride(const __GLXattribute
* const state
,
1841 GLenum key
, unsigned index
, GLintptr
* dest
)
1843 const struct array_state_vector
*arrays
= state
->array_state
;
1844 const struct array_state
*a
=
1845 get_array_entry((struct array_state_vector
*) arrays
,
1849 *dest
= (GLintptr
) a
->user_stride
;
1859 __glXGetArrayPointer(const __GLXattribute
* const state
,
1860 GLenum key
, unsigned index
, void **dest
)
1862 const struct array_state_vector
*arrays
= state
->array_state
;
1863 const struct array_state
*a
=
1864 get_array_entry((struct array_state_vector
*) arrays
,
1869 *dest
= (void *) (a
->data
);
1879 __glXGetArrayNormalized(const __GLXattribute
* const state
,
1880 GLenum key
, unsigned index
, GLintptr
* dest
)
1882 const struct array_state_vector
*arrays
= state
->array_state
;
1883 const struct array_state
*a
=
1884 get_array_entry((struct array_state_vector
*) arrays
,
1889 *dest
= (GLintptr
) a
->normalized
;
1899 __glXGetActiveTextureUnit(const __GLXattribute
* const state
)
1901 return state
->array_state
->active_texture_unit
;
1906 __glXPushArrayState(__GLXattribute
* state
)
1908 struct array_state_vector
*arrays
= state
->array_state
;
1909 struct array_stack_state
*stack
=
1910 &arrays
->stack
[(arrays
->stack_index
* arrays
->num_arrays
)];
1913 /* XXX are we pushing _all_ the necessary fields? */
1914 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1915 stack
[i
].data
= arrays
->arrays
[i
].data
;
1916 stack
[i
].data_type
= arrays
->arrays
[i
].data_type
;
1917 stack
[i
].user_stride
= arrays
->arrays
[i
].user_stride
;
1918 stack
[i
].count
= arrays
->arrays
[i
].count
;
1919 stack
[i
].key
= arrays
->arrays
[i
].key
;
1920 stack
[i
].index
= arrays
->arrays
[i
].index
;
1921 stack
[i
].enabled
= arrays
->arrays
[i
].enabled
;
1924 arrays
->active_texture_unit_stack
[arrays
->stack_index
] =
1925 arrays
->active_texture_unit
;
1927 arrays
->stack_index
++;
1932 __glXPopArrayState(__GLXattribute
* state
)
1934 struct array_state_vector
*arrays
= state
->array_state
;
1935 struct array_stack_state
*stack
;
1939 arrays
->stack_index
--;
1940 stack
= &arrays
->stack
[(arrays
->stack_index
* arrays
->num_arrays
)];
1942 for (i
= 0; i
< arrays
->num_arrays
; i
++) {
1943 switch (stack
[i
].key
) {
1944 case GL_NORMAL_ARRAY
:
1945 __indirect_glNormalPointer(stack
[i
].data_type
,
1946 stack
[i
].user_stride
, stack
[i
].data
);
1948 case GL_COLOR_ARRAY
:
1949 __indirect_glColorPointer(stack
[i
].count
,
1951 stack
[i
].user_stride
, stack
[i
].data
);
1953 case GL_INDEX_ARRAY
:
1954 __indirect_glIndexPointer(stack
[i
].data_type
,
1955 stack
[i
].user_stride
, stack
[i
].data
);
1957 case GL_EDGE_FLAG_ARRAY
:
1958 __indirect_glEdgeFlagPointer(stack
[i
].user_stride
, stack
[i
].data
);
1960 case GL_TEXTURE_COORD_ARRAY
:
1961 arrays
->active_texture_unit
= stack
[i
].index
;
1962 __indirect_glTexCoordPointer(stack
[i
].count
,
1964 stack
[i
].user_stride
, stack
[i
].data
);
1966 case GL_SECONDARY_COLOR_ARRAY
:
1967 __indirect_glSecondaryColorPointerEXT(stack
[i
].count
,
1969 stack
[i
].user_stride
,
1972 case GL_FOG_COORDINATE_ARRAY
:
1973 __indirect_glFogCoordPointerEXT(stack
[i
].data_type
,
1974 stack
[i
].user_stride
, stack
[i
].data
);
1979 __glXSetArrayEnable(state
, stack
[i
].key
, stack
[i
].index
,
1983 arrays
->active_texture_unit
=
1984 arrays
->active_texture_unit_stack
[arrays
->stack_index
];