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];