1/*
2 * (C) Copyright IBM Corporation 2004, 2005
3 * All Rights Reserved.
4 *
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:
11 *
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
14 * Software.
15 *
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
19 * IBM,
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
23 * SOFTWARE.
24 */
25
26#include <inttypes.h>
27#include <assert.h>
28#include <string.h>
29
30#include "util/compiler.h"
31
32#include "glxclient.h"
33#include "indirect.h"
34#include <GL/glxproto.h>
35#include "glxextensions.h"
36#include "indirect_vertex_array.h"
37#include "indirect_vertex_array_priv.h"
38
39#define __GLX_PAD(n) (((n)+3) & ~3)
40
41/**
42 * \file indirect_vertex_array.c
43 * Implement GLX protocol for vertex arrays and vertex buffer objects.
44 *
45 * The most important function in this fill is \c fill_array_info_cache.
46 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
47 * in the DrawArrays protocol.  Certain operations, such as enabling or
48 * disabling an array, can invalidate this cache.  \c fill_array_info_cache
49 * fills-in this data.  Additionally, it examines the enabled state and
50 * other factors to determine what "version" of DrawArrays protocoal can be
51 * used.
52 *
53 * Current, only two versions of DrawArrays protocol are implemented.  The
54 * first version is the "none" protocol.  This is the fallback when the
55 * server does not support GL 1.1 / EXT_vertex_arrays.  It is implemented
56 * by sending batches of immediate mode commands that are equivalent to the
57 * DrawArrays protocol.
58 *
59 * The other protocol that is currently implemented is the "old" protocol.
60 * This is the GL 1.1 DrawArrays protocol.  The only difference between GL
61 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
62 * This protocol is called "old" because the ARB is in the process of
63 * defining a new protocol, which will probably be called wither "new" or
64 * "vbo", to support multiple texture coordinate arrays, generic attributes,
65 * and vertex buffer objects.
66 *
67 * \author Ian Romanick <ian.d.romanick@intel.com>
68 */
69
70static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count);
71static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count);
72
73static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
74                                   const GLvoid * indices);
75static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
76                                  const GLvoid * indices);
77
78
79static GLubyte *emit_element_none(GLubyte * dst,
80                                  const struct array_state_vector *arrays,
81                                  unsigned index);
82static GLubyte *emit_element_old(GLubyte * dst,
83                                 const struct array_state_vector *arrays,
84                                 unsigned index);
85static struct array_state *get_array_entry(const struct array_state_vector
86                                           *arrays, GLenum key,
87                                           unsigned index);
88static void fill_array_info_cache(struct array_state_vector *arrays);
89static GLboolean validate_mode(struct glx_context * gc, GLenum mode);
90static GLboolean validate_count(struct glx_context * gc, GLsizei count);
91static GLboolean validate_type(struct glx_context * gc, GLenum type);
92
93
94/**
95 * Table of sizes, in bytes, of a GL types.  All of the type enums are be in
96 * the range 0x1400 - 0x140F.  That includes types added by extensions (i.e.,
97 * \c GL_HALF_FLOAT_NV).  This elements of this table correspond to the
98 * type enums masked with 0x0f.
99 *
100 * \notes
101 * \c GL_HALF_FLOAT_NV is not included.  Neither are \c GL_2_BYTES,
102 * \c GL_3_BYTES, or \c GL_4_BYTES.
103 */
104const GLuint __glXTypeSize_table[16] = {
105   1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
106};
107
108
109/**
110 * Free the per-context array state that was allocated with
111 * __glXInitVertexArrayState().
112 */
113void
114__glXFreeVertexArrayState(struct glx_context * gc)
115{
116   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
117   struct array_state_vector *arrays = state->array_state;
118
119   if (arrays) {
120      free(arrays->stack);
121      arrays->stack = NULL;
122      free(arrays->arrays);
123      arrays->arrays = NULL;
124      free(arrays);
125      state->array_state = NULL;
126   }
127}
128
129
130/**
131 * Initialize vertex array state of a GLX context.
132 *
133 * \param gc  GLX context whose vertex array state is to be initialized.
134 *
135 * \warning
136 * This function may only be called after struct glx_context::gl_extension_bits,
137 * struct glx_context::server_minor, and __GLXcontext::server_major have been
138 * initialized.  These values are used to determine what vertex arrays are
139 * supported.
140 */
141void
142__glXInitVertexArrayState(struct glx_context * gc)
143{
144   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
145   struct array_state_vector *arrays;
146
147   unsigned array_count;
148   int texture_units = 1, vertex_program_attribs = 0;
149   unsigned i, j;
150
151   GLboolean got_fog = GL_FALSE;
152   GLboolean got_secondary_color = GL_FALSE;
153
154
155   arrays = calloc(1, sizeof(struct array_state_vector));
156   state->array_state = arrays;
157
158   if (arrays == NULL) {
159      __glXSetError(gc, GL_OUT_OF_MEMORY);
160      return;
161   }
162
163   arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
164   arrays->new_DrawArrays_possible = GL_FALSE;
165   arrays->DrawArrays = NULL;
166
167   arrays->active_texture_unit = 0;
168
169
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
173    * are created.
174    *
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.
178    */
179
180   array_count = 5;
181
182   if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
183       || (gc->server_major > 1) || (gc->server_minor >= 4)) {
184      got_fog = GL_TRUE;
185      array_count++;
186   }
187
188   if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
189       || (gc->server_major > 1) || (gc->server_minor >= 4)) {
190      got_secondary_color = GL_TRUE;
191      array_count++;
192   }
193
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);
197   }
198
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);
203   }
204
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));
210
211   if (arrays->arrays == NULL) {
212      state->array_state = NULL;
213      free(arrays);
214      __glXSetError(gc, GL_OUT_OF_MEMORY);
215      return;
216   }
217
218   arrays->arrays[0].data_type = GL_FLOAT;
219   arrays->arrays[0].count = 3;
220   arrays->arrays[0].key = GL_NORMAL_ARRAY;
221   arrays->arrays[0].normalized = GL_TRUE;
222   arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;
223
224   arrays->arrays[1].data_type = GL_FLOAT;
225   arrays->arrays[1].count = 4;
226   arrays->arrays[1].key = GL_COLOR_ARRAY;
227   arrays->arrays[1].normalized = GL_TRUE;
228   arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;
229
230   arrays->arrays[2].data_type = GL_FLOAT;
231   arrays->arrays[2].count = 1;
232   arrays->arrays[2].key = GL_INDEX_ARRAY;
233   arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;
234
235   arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
236   arrays->arrays[3].count = 1;
237   arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
238   arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;
239
240   for (i = 0; i < texture_units; i++) {
241      arrays->arrays[4 + i].data_type = GL_FLOAT;
242      arrays->arrays[4 + i].count = 4;
243      arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;
244
245      arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
246      arrays->arrays[4 + i].index = i;
247   }
248
249   i = 4 + texture_units;
250
251   if (got_fog) {
252      arrays->arrays[i].data_type = GL_FLOAT;
253      arrays->arrays[i].count = 1;
254      arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
255      arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
256      i++;
257   }
258
259   if (got_secondary_color) {
260      arrays->arrays[i].data_type = GL_FLOAT;
261      arrays->arrays[i].count = 3;
262      arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
263      arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
264      arrays->arrays[i].normalized = GL_TRUE;
265      i++;
266   }
267
268
269   for (j = 0; j < vertex_program_attribs; j++) {
270      const unsigned idx = (vertex_program_attribs - (j + 1));
271
272
273      arrays->arrays[idx + i].data_type = GL_FLOAT;
274      arrays->arrays[idx + i].count = 4;
275      arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;
276
277      arrays->arrays[idx + i].old_DrawArrays_possible = 0;
278      arrays->arrays[idx + i].index = idx;
279   }
280
281   i += vertex_program_attribs;
282
283
284   /* Vertex array *must* be last because of the way that
285    * emit_DrawArrays_none works.
286    */
287
288   arrays->arrays[i].data_type = GL_FLOAT;
289   arrays->arrays[i].count = 4;
290   arrays->arrays[i].key = GL_VERTEX_ARRAY;
291   arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
292
293   assert((i + 1) == arrays->num_arrays);
294
295   arrays->stack_index = 0;
296   arrays->stack = malloc(sizeof(struct array_stack_state)
297                          * arrays->num_arrays
298                          * __GL_CLIENT_ATTRIB_STACK_DEPTH);
299
300   if (arrays->stack == NULL) {
301      state->array_state = NULL;
302      free(arrays->arrays);
303      free(arrays);
304      __glXSetError(gc, GL_OUT_OF_MEMORY);
305      return;
306   }
307}
308
309
310/**
311 * Calculate the size of a single vertex for the "none" protocol.  This is
312 * essentially the size of all the immediate-mode commands required to
313 * implement the enabled vertex arrays.
314 */
315static size_t
316calculate_single_vertex_size_none(const struct array_state_vector *arrays)
317{
318   size_t single_vertex_size = 0;
319   unsigned i;
320
321
322   for (i = 0; i < arrays->num_arrays; i++) {
323      if (arrays->arrays[i].enabled) {
324         single_vertex_size += arrays->arrays[i].header[0];
325      }
326   }
327
328   return single_vertex_size;
329}
330
331
332/**
333 * Emit a single element using non-DrawArrays protocol.
334 */
335GLubyte *
336emit_element_none(GLubyte * dst,
337                  const struct array_state_vector * arrays, unsigned index)
338{
339   unsigned i;
340
341
342   for (i = 0; i < arrays->num_arrays; i++) {
343      if (arrays->arrays[i].enabled) {
344         const size_t offset = index * arrays->arrays[i].true_stride;
345
346         /* The generic attributes can have more data than is in the
347          * elements.  This is because a vertex array can be a 2 element,
348          * normalized, unsigned short, but the "closest" immediate mode
349          * protocol is for a 4Nus.  Since the sizes are small, the
350          * performance impact on modern processors should be negligible.
351          */
352         (void) memset(dst, 0, arrays->arrays[i].header[0]);
353
354         (void) memcpy(dst, arrays->arrays[i].header, 4);
355
356         dst += 4;
357
358         if (arrays->arrays[i].key == GL_TEXTURE_COORD_ARRAY &&
359             arrays->arrays[i].index > 0) {
360            /* Multi-texture coordinate arrays require the texture target
361             * to be sent.  For doubles it is after the data, for everything
362             * else it is before.
363             */
364            GLenum texture = arrays->arrays[i].index + GL_TEXTURE0;
365            if (arrays->arrays[i].data_type == GL_DOUBLE) {
366               (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
367                             arrays->arrays[i].element_size);
368               dst += arrays->arrays[i].element_size;
369               (void) memcpy(dst, &texture, 4);
370               dst += 4;
371            } else {
372               (void) memcpy(dst, &texture, 4);
373               dst += 4;
374               (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
375                             arrays->arrays[i].element_size);
376               dst += __GLX_PAD(arrays->arrays[i].element_size);
377            }
378         } else if (arrays->arrays[i].key == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
379            /* Vertex attribute data requires the index sent first.
380             */
381            (void) memcpy(dst, &arrays->arrays[i].index, 4);
382            dst += 4;
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);
386         } else {
387            (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
388                          arrays->arrays[i].element_size);
389            dst += __GLX_PAD(arrays->arrays[i].element_size);
390         }
391      }
392   }
393
394   return dst;
395}
396
397
398/**
399 * Emit a single element using "old" DrawArrays protocol from
400 * EXT_vertex_arrays / OpenGL 1.1.
401 */
402GLubyte *
403emit_element_old(GLubyte * dst,
404                 const struct array_state_vector * arrays, unsigned index)
405{
406   unsigned i;
407
408
409   for (i = 0; i < arrays->num_arrays; i++) {
410      if (arrays->arrays[i].enabled) {
411         const size_t offset = index * arrays->arrays[i].true_stride;
412
413         (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
414                       arrays->arrays[i].element_size);
415
416         dst += __GLX_PAD(arrays->arrays[i].element_size);
417      }
418   }
419
420   return dst;
421}
422
423
424struct array_state *
425get_array_entry(const struct array_state_vector *arrays,
426                GLenum key, unsigned index)
427{
428   unsigned i;
429
430   for (i = 0; i < arrays->num_arrays; i++) {
431      if ((arrays->arrays[i].key == key)
432          && (arrays->arrays[i].index == index)) {
433         return &arrays->arrays[i];
434      }
435   }
436
437   return NULL;
438}
439
440
441static GLboolean
442allocate_array_info_cache(struct array_state_vector *arrays,
443                          size_t required_size)
444{
445#define MAX_HEADER_SIZE 20
446   if (arrays->array_info_cache_buffer_size < required_size) {
447      GLubyte *temp = realloc(arrays->array_info_cache_base,
448                              required_size + MAX_HEADER_SIZE);
449
450      if (temp == NULL) {
451         return GL_FALSE;
452      }
453
454      arrays->array_info_cache_base = temp;
455      arrays->array_info_cache = temp + MAX_HEADER_SIZE;
456      arrays->array_info_cache_buffer_size = required_size;
457   }
458
459   arrays->array_info_cache_size = required_size;
460   return GL_TRUE;
461}
462
463
464/**
465 */
466void
467fill_array_info_cache(struct array_state_vector *arrays)
468{
469   GLboolean old_DrawArrays_possible;
470   unsigned i;
471
472
473   /* Determine how many arrays are enabled.
474    */
475
476   arrays->enabled_client_array_count = 0;
477   old_DrawArrays_possible = arrays->old_DrawArrays_possible;
478   for (i = 0; i < arrays->num_arrays; i++) {
479      if (arrays->arrays[i].enabled) {
480         arrays->enabled_client_array_count++;
481         old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
482      }
483   }
484
485   if (arrays->new_DrawArrays_possible) {
486      assert(!arrays->new_DrawArrays_possible);
487   }
488   else if (old_DrawArrays_possible) {
489      const size_t required_size = arrays->enabled_client_array_count * 12;
490      uint32_t *info;
491
492
493      if (!allocate_array_info_cache(arrays, required_size)) {
494         return;
495      }
496
497
498      info = (uint32_t *) arrays->array_info_cache;
499      for (i = 0; i < arrays->num_arrays; i++) {
500         if (arrays->arrays[i].enabled) {
501            *(info++) = arrays->arrays[i].data_type;
502            *(info++) = arrays->arrays[i].count;
503            *(info++) = arrays->arrays[i].key;
504         }
505      }
506
507      arrays->DrawArrays = emit_DrawArrays_old;
508      arrays->DrawElements = emit_DrawElements_old;
509   }
510   else {
511      arrays->DrawArrays = emit_DrawArrays_none;
512      arrays->DrawElements = emit_DrawElements_none;
513   }
514
515   arrays->array_info_cache_valid = GL_TRUE;
516}
517
518
519/**
520 * Emit a \c glDrawArrays command using the "none" protocol.  That is,
521 * emit immediate-mode commands that are equivalent to the requiested
522 * \c glDrawArrays command.  This is used with servers that don't support
523 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
524 * vertex state is enabled that is not compatible with that protocol.
525 */
526void
527emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
528{
529   struct glx_context *gc = __glXGetCurrentContext();
530   const __GLXattribute *state =
531      (const __GLXattribute *) (gc->client_state_private);
532   struct array_state_vector *arrays = state->array_state;
533
534   size_t single_vertex_size;
535   GLubyte *pc;
536   unsigned i;
537   static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
538   static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
539
540
541   single_vertex_size = calculate_single_vertex_size_none(arrays);
542
543   pc = gc->pc;
544
545   (void) memcpy(pc, begin_cmd, 4);
546   *(int *) (pc + 4) = mode;
547
548   pc += 8;
549
550   for (i = 0; i < count; i++) {
551      if ((pc + single_vertex_size) >= gc->bufEnd) {
552         pc = __glXFlushRenderBuffer(gc, pc);
553      }
554
555      pc = emit_element_none(pc, arrays, first + i);
556   }
557
558   if ((pc + 4) >= gc->bufEnd) {
559      pc = __glXFlushRenderBuffer(gc, pc);
560   }
561
562   (void) memcpy(pc, end_cmd, 4);
563   pc += 4;
564
565   gc->pc = pc;
566   if (gc->pc > gc->limit) {
567      (void) __glXFlushRenderBuffer(gc, gc->pc);
568   }
569}
570
571
572/**
573 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
574 * protocol.
575 *
576 * \param gc                    GLX context.
577 * \param arrays                Array state.
578 * \param elements_per_request  Location to store the number of elements that
579 *                              can fit in a single Render / RenderLarge
580 *                              command.
581 * \param total_request         Total number of requests for a RenderLarge
582 *                              command.  If a Render command is used, this
583 *                              will be zero.
584 * \param mode                  Drawing mode.
585 * \param count                 Number of vertices.
586 *
587 * \returns
588 * A pointer to the buffer for array data.
589 */
590static GLubyte *
591emit_DrawArrays_header_old(struct glx_context * gc,
592                           struct array_state_vector *arrays,
593                           size_t * elements_per_request,
594                           unsigned int *total_requests,
595                           GLenum mode, GLsizei count)
596{
597   size_t command_size;
598   size_t single_vertex_size;
599   const unsigned header_size = 16;
600   unsigned i;
601   GLubyte *pc;
602
603
604   /* Determine the size of the whole command.  This includes the header,
605    * the ARRAY_INFO data and the array data.  Once this size is calculated,
606    * it will be known whether a Render or RenderLarge command is needed.
607    */
608
609   single_vertex_size = 0;
610   for (i = 0; i < arrays->num_arrays; i++) {
611      if (arrays->arrays[i].enabled) {
612         single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
613      }
614   }
615
616   command_size = arrays->array_info_cache_size + header_size
617      + (single_vertex_size * count);
618
619
620   /* Write the header for either a Render command or a RenderLarge
621    * command.  After the header is written, write the ARRAY_INFO data.
622    */
623
624   if (command_size > gc->maxSmallRenderCommandSize) {
625      /* maxSize is the maximum amount of data can be stuffed into a single
626       * packet.  sz_xGLXRenderReq is added because bufSize is the maximum
627       * packet size minus sz_xGLXRenderReq.
628       */
629      const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
630         - sz_xGLXRenderLargeReq;
631      unsigned vertex_requests;
632
633
634      /* Calculate the number of data packets that will be required to send
635       * the whole command.  To do this, the number of verticies that
636       * will fit in a single buffer must be calculated.
637       *
638       * The important value here is elements_per_request.  This is the
639       * number of complete array elements that will fit in a single
640       * buffer.  There may be some wasted space at the end of the buffer,
641       * but splitting elements across buffer boundries would be painful.
642       */
643
644      elements_per_request[0] = maxSize / single_vertex_size;
645
646      vertex_requests = (count + elements_per_request[0] - 1)
647         / elements_per_request[0];
648
649      *total_requests = vertex_requests + 1;
650
651
652      __glXFlushRenderBuffer(gc, gc->pc);
653
654      command_size += 4;
655
656      pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
657      *(uint32_t *) (pc + 0) = command_size;
658      *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
659      *(uint32_t *) (pc + 8) = count;
660      *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
661      *(uint32_t *) (pc + 16) = mode;
662
663      __glXSendLargeChunk(gc, 1, *total_requests, pc,
664                          header_size + 4 + arrays->array_info_cache_size);
665
666      pc = gc->pc;
667   }
668   else {
669      if ((gc->pc + command_size) >= gc->bufEnd) {
670         (void) __glXFlushRenderBuffer(gc, gc->pc);
671      }
672
673      pc = gc->pc;
674      *(uint16_t *) (pc + 0) = command_size;
675      *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
676      *(uint32_t *) (pc + 4) = count;
677      *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
678      *(uint32_t *) (pc + 12) = mode;
679
680      pc += header_size;
681
682      (void) memcpy(pc, arrays->array_info_cache,
683                    arrays->array_info_cache_size);
684      pc += arrays->array_info_cache_size;
685
686      *elements_per_request = count;
687      *total_requests = 0;
688   }
689
690
691   return pc;
692}
693
694
695/**
696 */
697void
698emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
699{
700   struct glx_context *gc = __glXGetCurrentContext();
701   const __GLXattribute *state =
702      (const __GLXattribute *) (gc->client_state_private);
703   struct array_state_vector *arrays = state->array_state;
704
705   GLubyte *pc;
706   size_t elements_per_request;
707   unsigned total_requests = 0;
708   unsigned i;
709   size_t total_sent = 0;
710
711
712   pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
713                                   &total_requests, mode, count);
714
715
716   /* Write the arrays.
717    */
718
719   if (total_requests == 0) {
720      assert(elements_per_request >= count);
721
722      for (i = 0; i < count; i++) {
723         pc = emit_element_old(pc, arrays, i + first);
724      }
725
726      assert(pc <= gc->bufEnd);
727
728      gc->pc = pc;
729      if (gc->pc > gc->limit) {
730         (void) __glXFlushRenderBuffer(gc, gc->pc);
731      }
732   }
733   else {
734      unsigned req;
735
736
737      for (req = 2; req <= total_requests; req++) {
738         if (count < elements_per_request) {
739            elements_per_request = count;
740         }
741
742         pc = gc->pc;
743         for (i = 0; i < elements_per_request; i++) {
744            pc = emit_element_old(pc, arrays, i + first);
745         }
746
747         first += elements_per_request;
748
749         total_sent += (size_t) (pc - gc->pc);
750         __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
751
752         count -= elements_per_request;
753      }
754   }
755}
756
757
758void
759emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
760                       const GLvoid * indices)
761{
762   struct glx_context *gc = __glXGetCurrentContext();
763   const __GLXattribute *state =
764      (const __GLXattribute *) (gc->client_state_private);
765   struct array_state_vector *arrays = state->array_state;
766   static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
767   static const uint16_t end_cmd[2] = { 4, X_GLrop_End };
768
769   GLubyte *pc;
770   size_t single_vertex_size;
771   unsigned i;
772
773
774   single_vertex_size = calculate_single_vertex_size_none(arrays);
775
776
777   if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
778      gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
779   }
780
781   pc = gc->pc;
782
783   (void) memcpy(pc, begin_cmd, 4);
784   *(int *) (pc + 4) = mode;
785
786   pc += 8;
787
788   for (i = 0; i < count; i++) {
789      unsigned index = 0;
790
791      if ((pc + single_vertex_size) >= gc->bufEnd) {
792         pc = __glXFlushRenderBuffer(gc, pc);
793      }
794
795      switch (type) {
796      case GL_UNSIGNED_INT:
797         index = (unsigned) (((GLuint *) indices)[i]);
798         break;
799      case GL_UNSIGNED_SHORT:
800         index = (unsigned) (((GLushort *) indices)[i]);
801         break;
802      case GL_UNSIGNED_BYTE:
803         index = (unsigned) (((GLubyte *) indices)[i]);
804         break;
805      }
806      pc = emit_element_none(pc, arrays, index);
807   }
808
809   if ((pc + 4) >= gc->bufEnd) {
810      pc = __glXFlushRenderBuffer(gc, pc);
811   }
812
813   (void) memcpy(pc, end_cmd, 4);
814   pc += 4;
815
816   gc->pc = pc;
817   if (gc->pc > gc->limit) {
818      (void) __glXFlushRenderBuffer(gc, gc->pc);
819   }
820}
821
822
823/**
824 */
825void
826emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
827                      const GLvoid * indices)
828{
829   struct glx_context *gc = __glXGetCurrentContext();
830   const __GLXattribute *state =
831      (const __GLXattribute *) (gc->client_state_private);
832   struct array_state_vector *arrays = state->array_state;
833
834   GLubyte *pc;
835   size_t elements_per_request;
836   unsigned total_requests = 0;
837   unsigned i;
838   unsigned req;
839   unsigned req_element = 0;
840
841
842   pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
843                                   &total_requests, mode, count);
844
845
846   /* Write the arrays.
847    */
848
849   req = 2;
850   while (count > 0) {
851      if (count < elements_per_request) {
852         elements_per_request = count;
853      }
854
855      switch (type) {
856      case GL_UNSIGNED_INT:{
857            const GLuint *ui_ptr = (const GLuint *) indices + req_element;
858
859            for (i = 0; i < elements_per_request; i++) {
860               const GLint index = (GLint) * (ui_ptr++);
861               pc = emit_element_old(pc, arrays, index);
862            }
863            break;
864         }
865      case GL_UNSIGNED_SHORT:{
866            const GLushort *us_ptr = (const GLushort *) indices + req_element;
867
868            for (i = 0; i < elements_per_request; i++) {
869               const GLint index = (GLint) * (us_ptr++);
870               pc = emit_element_old(pc, arrays, index);
871            }
872            break;
873         }
874      case GL_UNSIGNED_BYTE:{
875            const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;
876
877            for (i = 0; i < elements_per_request; i++) {
878               const GLint index = (GLint) * (ub_ptr++);
879               pc = emit_element_old(pc, arrays, index);
880            }
881            break;
882         }
883      }
884
885      if (total_requests != 0) {
886         __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
887         pc = gc->pc;
888         req++;
889      }
890
891      count -= elements_per_request;
892      req_element += elements_per_request;
893   }
894
895
896   assert((total_requests == 0) || ((req - 1) == total_requests));
897
898   if (total_requests == 0) {
899      assert(pc <= gc->bufEnd);
900
901      gc->pc = pc;
902      if (gc->pc > gc->limit) {
903         (void) __glXFlushRenderBuffer(gc, gc->pc);
904      }
905   }
906}
907
908
909/**
910 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
911 * If it is not valid, then an error code is set in the GLX context.
912 *
913 * \returns
914 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
915 */
916static GLboolean
917validate_mode(struct glx_context * gc, GLenum mode)
918{
919   switch (mode) {
920   case GL_POINTS:
921   case GL_LINE_STRIP:
922   case GL_LINE_LOOP:
923   case GL_LINES:
924   case GL_TRIANGLE_STRIP:
925   case GL_TRIANGLE_FAN:
926   case GL_TRIANGLES:
927   case GL_QUAD_STRIP:
928   case GL_QUADS:
929   case GL_POLYGON:
930      break;
931   default:
932      __glXSetError(gc, GL_INVALID_ENUM);
933      return GL_FALSE;
934   }
935
936   return GL_TRUE;
937}
938
939
940/**
941 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
942 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
943 * being set.  A value of zero will not result in an error being set, but
944 * will result in \c GL_FALSE being returned.
945 *
946 * \returns
947 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
948 */
949static GLboolean
950validate_count(struct glx_context * gc, GLsizei count)
951{
952   if (count < 0) {
953      __glXSetError(gc, GL_INVALID_VALUE);
954   }
955
956   return (count > 0);
957}
958
959
960/**
961 * Validate that the \c type parameter to \c glDrawElements, et. al. is
962 * valid.  Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
963 * \c GL_UNSIGNED_INT are valid.
964 *
965 * \returns
966 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
967 */
968static GLboolean
969validate_type(struct glx_context * gc, GLenum type)
970{
971   switch (type) {
972   case GL_UNSIGNED_INT:
973   case GL_UNSIGNED_SHORT:
974   case GL_UNSIGNED_BYTE:
975      return GL_TRUE;
976   default:
977      __glXSetError(gc, GL_INVALID_ENUM);
978      return GL_FALSE;
979   }
980}
981
982
983void
984__indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
985{
986   struct glx_context *gc = __glXGetCurrentContext();
987   const __GLXattribute *state =
988      (const __GLXattribute *) (gc->client_state_private);
989   struct array_state_vector *arrays = state->array_state;
990
991
992   if (validate_mode(gc, mode) && validate_count(gc, count)) {
993      if (!arrays->array_info_cache_valid) {
994         fill_array_info_cache(arrays);
995      }
996
997      arrays->DrawArrays(mode, first, count);
998   }
999}
1000
1001
1002void
1003__indirect_glArrayElement(GLint index)
1004{
1005   struct glx_context *gc = __glXGetCurrentContext();
1006   const __GLXattribute *state =
1007      (const __GLXattribute *) (gc->client_state_private);
1008   struct array_state_vector *arrays = state->array_state;
1009
1010   size_t single_vertex_size;
1011
1012
1013   single_vertex_size = calculate_single_vertex_size_none(arrays);
1014
1015   if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
1016      gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
1017   }
1018
1019   gc->pc = emit_element_none(gc->pc, arrays, index);
1020
1021   if (gc->pc > gc->limit) {
1022      (void) __glXFlushRenderBuffer(gc, gc->pc);
1023   }
1024}
1025
1026
1027void
1028__indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
1029                          const GLvoid * indices)
1030{
1031   struct glx_context *gc = __glXGetCurrentContext();
1032   const __GLXattribute *state =
1033      (const __GLXattribute *) (gc->client_state_private);
1034   struct array_state_vector *arrays = state->array_state;
1035
1036
1037   if (validate_mode(gc, mode) && validate_count(gc, count)
1038       && validate_type(gc, type)) {
1039      if (!arrays->array_info_cache_valid) {
1040         fill_array_info_cache(arrays);
1041      }
1042
1043      arrays->DrawElements(mode, count, type, indices);
1044   }
1045}
1046
1047
1048void
1049__indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
1050                               GLsizei count, GLenum type,
1051                               const GLvoid * indices)
1052{
1053   struct glx_context *gc = __glXGetCurrentContext();
1054   const __GLXattribute *state =
1055      (const __GLXattribute *) (gc->client_state_private);
1056   struct array_state_vector *arrays = state->array_state;
1057
1058
1059   if (validate_mode(gc, mode) && validate_count(gc, count)
1060       && validate_type(gc, type)) {
1061      if (end < start) {
1062         __glXSetError(gc, GL_INVALID_VALUE);
1063         return;
1064      }
1065
1066      if (!arrays->array_info_cache_valid) {
1067         fill_array_info_cache(arrays);
1068      }
1069
1070      arrays->DrawElements(mode, count, type, indices);
1071   }
1072}
1073
1074
1075void
1076__indirect_glMultiDrawArrays(GLenum mode, const GLint *first,
1077                                const GLsizei *count, GLsizei primcount)
1078{
1079   struct glx_context *gc = __glXGetCurrentContext();
1080   const __GLXattribute *state =
1081      (const __GLXattribute *) (gc->client_state_private);
1082   struct array_state_vector *arrays = state->array_state;
1083   GLsizei i;
1084
1085
1086   if (validate_mode(gc, mode)) {
1087      if (!arrays->array_info_cache_valid) {
1088         fill_array_info_cache(arrays);
1089      }
1090
1091      for (i = 0; i < primcount; i++) {
1092         if (validate_count(gc, count[i])) {
1093            arrays->DrawArrays(mode, first[i], count[i]);
1094         }
1095      }
1096   }
1097}
1098
1099
1100void
1101__indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
1102                                  GLenum type, const GLvoid * const * indices,
1103                                  GLsizei primcount)
1104{
1105   struct glx_context *gc = __glXGetCurrentContext();
1106   const __GLXattribute *state =
1107      (const __GLXattribute *) (gc->client_state_private);
1108   struct array_state_vector *arrays = state->array_state;
1109   GLsizei i;
1110
1111
1112   if (validate_mode(gc, mode) && validate_type(gc, type)) {
1113      if (!arrays->array_info_cache_valid) {
1114         fill_array_info_cache(arrays);
1115      }
1116
1117      for (i = 0; i < primcount; i++) {
1118         if (validate_count(gc, count[i])) {
1119            arrays->DrawElements(mode, count[i], type, indices[i]);
1120         }
1121      }
1122   }
1123}
1124
1125
1126/* The HDR_SIZE macro argument is the command header size (4 bytes)
1127 * plus any additional index word e.g. for texture units or vertex
1128 * attributes.
1129 */
1130#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
1131  do {                                                                  \
1132    (a)->data = PTR;                                                    \
1133    (a)->data_type = TYPE;                                              \
1134    (a)->user_stride = STRIDE;                                          \
1135    (a)->count = COUNT;                                                 \
1136    (a)->normalized = NORMALIZED;                                       \
1137                                                                        \
1138    (a)->element_size = __glXTypeSize( TYPE ) * COUNT;                  \
1139    (a)->true_stride = (STRIDE == 0)                                    \
1140      ? (a)->element_size : STRIDE;                                     \
1141                                                                        \
1142    (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size);           \
1143    (a)->header[1] = OPCODE;                                            \
1144  } while(0)
1145
1146
1147void
1148__indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
1149                           const GLvoid * pointer)
1150{
1151   static const uint16_t short_ops[5] = {
1152      0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
1153   };
1154   static const uint16_t int_ops[5] = {
1155      0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
1156   };
1157   static const uint16_t float_ops[5] = {
1158      0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
1159   };
1160   static const uint16_t double_ops[5] = {
1161      0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
1162   };
1163   uint16_t opcode;
1164   struct glx_context *gc = __glXGetCurrentContext();
1165   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1166   struct array_state_vector *arrays = state->array_state;
1167   struct array_state *a;
1168
1169
1170   if (size < 2 || size > 4 || stride < 0) {
1171      __glXSetError(gc, GL_INVALID_VALUE);
1172      return;
1173   }
1174
1175   switch (type) {
1176   case GL_SHORT:
1177      opcode = short_ops[size];
1178      break;
1179   case GL_INT:
1180      opcode = int_ops[size];
1181      break;
1182   case GL_FLOAT:
1183      opcode = float_ops[size];
1184      break;
1185   case GL_DOUBLE:
1186      opcode = double_ops[size];
1187      break;
1188   default:
1189      __glXSetError(gc, GL_INVALID_ENUM);
1190      return;
1191   }
1192
1193   a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
1194   assert(a != NULL);
1195   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
1196                          opcode);
1197
1198   if (a->enabled) {
1199      arrays->array_info_cache_valid = GL_FALSE;
1200   }
1201}
1202
1203
1204void
1205__indirect_glNormalPointer(GLenum type, GLsizei stride,
1206                           const GLvoid * pointer)
1207{
1208   uint16_t opcode;
1209   struct glx_context *gc = __glXGetCurrentContext();
1210   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1211   struct array_state_vector *arrays = state->array_state;
1212   struct array_state *a;
1213
1214
1215   if (stride < 0) {
1216      __glXSetError(gc, GL_INVALID_VALUE);
1217      return;
1218   }
1219
1220   switch (type) {
1221   case GL_BYTE:
1222      opcode = X_GLrop_Normal3bv;
1223      break;
1224   case GL_SHORT:
1225      opcode = X_GLrop_Normal3sv;
1226      break;
1227   case GL_INT:
1228      opcode = X_GLrop_Normal3iv;
1229      break;
1230   case GL_FLOAT:
1231      opcode = X_GLrop_Normal3fv;
1232      break;
1233   case GL_DOUBLE:
1234      opcode = X_GLrop_Normal3dv;
1235      break;
1236   default:
1237      __glXSetError(gc, GL_INVALID_ENUM);
1238      return;
1239   }
1240
1241   a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
1242   assert(a != NULL);
1243   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);
1244
1245   if (a->enabled) {
1246      arrays->array_info_cache_valid = GL_FALSE;
1247   }
1248}
1249
1250
1251void
1252__indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
1253                          const GLvoid * pointer)
1254{
1255   static const uint16_t byte_ops[5] = {
1256      0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
1257   };
1258   static const uint16_t ubyte_ops[5] = {
1259      0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
1260   };
1261   static const uint16_t short_ops[5] = {
1262      0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
1263   };
1264   static const uint16_t ushort_ops[5] = {
1265      0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
1266   };
1267   static const uint16_t int_ops[5] = {
1268      0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
1269   };
1270   static const uint16_t uint_ops[5] = {
1271      0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
1272   };
1273   static const uint16_t float_ops[5] = {
1274      0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
1275   };
1276   static const uint16_t double_ops[5] = {
1277      0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
1278   };
1279   uint16_t opcode;
1280   struct glx_context *gc = __glXGetCurrentContext();
1281   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1282   struct array_state_vector *arrays = state->array_state;
1283   struct array_state *a;
1284
1285
1286   if (size < 3 || size > 4 || stride < 0) {
1287      __glXSetError(gc, GL_INVALID_VALUE);
1288      return;
1289   }
1290
1291   switch (type) {
1292   case GL_BYTE:
1293      opcode = byte_ops[size];
1294      break;
1295   case GL_UNSIGNED_BYTE:
1296      opcode = ubyte_ops[size];
1297      break;
1298   case GL_SHORT:
1299      opcode = short_ops[size];
1300      break;
1301   case GL_UNSIGNED_SHORT:
1302      opcode = ushort_ops[size];
1303      break;
1304   case GL_INT:
1305      opcode = int_ops[size];
1306      break;
1307   case GL_UNSIGNED_INT:
1308      opcode = uint_ops[size];
1309      break;
1310   case GL_FLOAT:
1311      opcode = float_ops[size];
1312      break;
1313   case GL_DOUBLE:
1314      opcode = double_ops[size];
1315      break;
1316   default:
1317      __glXSetError(gc, GL_INVALID_ENUM);
1318      return;
1319   }
1320
1321   a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
1322   assert(a != NULL);
1323   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1324
1325   if (a->enabled) {
1326      arrays->array_info_cache_valid = GL_FALSE;
1327   }
1328}
1329
1330
1331void
1332__indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
1333{
1334   uint16_t opcode;
1335   struct glx_context *gc = __glXGetCurrentContext();
1336   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1337   struct array_state_vector *arrays = state->array_state;
1338   struct array_state *a;
1339
1340
1341   if (stride < 0) {
1342      __glXSetError(gc, GL_INVALID_VALUE);
1343      return;
1344   }
1345
1346   switch (type) {
1347   case GL_UNSIGNED_BYTE:
1348      opcode = X_GLrop_Indexubv;
1349      break;
1350   case GL_SHORT:
1351      opcode = X_GLrop_Indexsv;
1352      break;
1353   case GL_INT:
1354      opcode = X_GLrop_Indexiv;
1355      break;
1356   case GL_FLOAT:
1357      opcode = X_GLrop_Indexfv;
1358      break;
1359   case GL_DOUBLE:
1360      opcode = X_GLrop_Indexdv;
1361      break;
1362   default:
1363      __glXSetError(gc, GL_INVALID_ENUM);
1364      return;
1365   }
1366
1367   a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
1368   assert(a != NULL);
1369   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1370
1371   if (a->enabled) {
1372      arrays->array_info_cache_valid = GL_FALSE;
1373   }
1374}
1375
1376
1377void
1378__indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
1379{
1380   struct glx_context *gc = __glXGetCurrentContext();
1381   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1382   struct array_state_vector *arrays = state->array_state;
1383   struct array_state *a;
1384
1385
1386   if (stride < 0) {
1387      __glXSetError(gc, GL_INVALID_VALUE);
1388      return;
1389   }
1390
1391
1392   a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
1393   assert(a != NULL);
1394   COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
1395                          4, X_GLrop_EdgeFlagv);
1396
1397   if (a->enabled) {
1398      arrays->array_info_cache_valid = GL_FALSE;
1399   }
1400}
1401
1402
1403void
1404__indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
1405                             const GLvoid * pointer)
1406{
1407   static const uint16_t short_ops[5] = {
1408      0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
1409      X_GLrop_TexCoord4sv
1410   };
1411   static const uint16_t int_ops[5] = {
1412      0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
1413      X_GLrop_TexCoord4iv
1414   };
1415   static const uint16_t float_ops[5] = {
1416      0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
1417      X_GLrop_TexCoord4fv
1418   };
1419   static const uint16_t double_ops[5] = {
1420      0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
1421      X_GLrop_TexCoord4dv
1422   };
1423
1424   static const uint16_t mshort_ops[5] = {
1425      0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
1426      X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
1427   };
1428   static const uint16_t mint_ops[5] = {
1429      0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
1430      X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
1431   };
1432   static const uint16_t mfloat_ops[5] = {
1433      0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB,
1434      X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
1435   };
1436   static const uint16_t mdouble_ops[5] = {
1437      0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
1438      X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
1439   };
1440
1441   uint16_t opcode;
1442   struct glx_context *gc = __glXGetCurrentContext();
1443   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1444   struct array_state_vector *arrays = state->array_state;
1445   struct array_state *a;
1446   unsigned header_size;
1447   unsigned index;
1448
1449
1450   if (size < 1 || size > 4 || stride < 0) {
1451      __glXSetError(gc, GL_INVALID_VALUE);
1452      return;
1453   }
1454
1455   index = arrays->active_texture_unit;
1456   if (index == 0) {
1457      switch (type) {
1458      case GL_SHORT:
1459         opcode = short_ops[size];
1460         break;
1461      case GL_INT:
1462         opcode = int_ops[size];
1463         break;
1464      case GL_FLOAT:
1465         opcode = float_ops[size];
1466         break;
1467      case GL_DOUBLE:
1468         opcode = double_ops[size];
1469         break;
1470      default:
1471         __glXSetError(gc, GL_INVALID_ENUM);
1472         return;
1473      }
1474
1475      header_size = 4;
1476   }
1477   else {
1478      switch (type) {
1479      case GL_SHORT:
1480         opcode = mshort_ops[size];
1481         break;
1482      case GL_INT:
1483         opcode = mint_ops[size];
1484         break;
1485      case GL_FLOAT:
1486         opcode = mfloat_ops[size];
1487         break;
1488      case GL_DOUBLE:
1489         opcode = mdouble_ops[size];
1490         break;
1491      default:
1492         __glXSetError(gc, GL_INVALID_ENUM);
1493         return;
1494      }
1495
1496      header_size = 8;
1497   }
1498
1499   a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
1500   assert(a != NULL);
1501   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
1502                          header_size, opcode);
1503
1504   if (a->enabled) {
1505      arrays->array_info_cache_valid = GL_FALSE;
1506   }
1507}
1508
1509
1510void
1511__indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,
1512                                      const GLvoid * pointer)
1513{
1514   uint16_t opcode;
1515   struct glx_context *gc = __glXGetCurrentContext();
1516   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1517   struct array_state_vector *arrays = state->array_state;
1518   struct array_state *a;
1519
1520
1521   if (size != 3 || stride < 0) {
1522      __glXSetError(gc, GL_INVALID_VALUE);
1523      return;
1524   }
1525
1526   switch (type) {
1527   case GL_BYTE:
1528      opcode = 4126;
1529      break;
1530   case GL_UNSIGNED_BYTE:
1531      opcode = 4131;
1532      break;
1533   case GL_SHORT:
1534      opcode = 4127;
1535      break;
1536   case GL_UNSIGNED_SHORT:
1537      opcode = 4132;
1538      break;
1539   case GL_INT:
1540      opcode = 4128;
1541      break;
1542   case GL_UNSIGNED_INT:
1543      opcode = 4133;
1544      break;
1545   case GL_FLOAT:
1546      opcode = 4129;
1547      break;
1548   case GL_DOUBLE:
1549      opcode = 4130;
1550      break;
1551   default:
1552      __glXSetError(gc, GL_INVALID_ENUM);
1553      return;
1554   }
1555
1556   a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
1557   if (a == NULL) {
1558      __glXSetError(gc, GL_INVALID_OPERATION);
1559      return;
1560   }
1561
1562   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);
1563
1564   if (a->enabled) {
1565      arrays->array_info_cache_valid = GL_FALSE;
1566   }
1567}
1568
1569
1570void
1571__indirect_glFogCoordPointer(GLenum type, GLsizei stride,
1572                                const GLvoid * pointer)
1573{
1574   uint16_t opcode;
1575   struct glx_context *gc = __glXGetCurrentContext();
1576   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1577   struct array_state_vector *arrays = state->array_state;
1578   struct array_state *a;
1579
1580
1581   if (stride < 0) {
1582      __glXSetError(gc, GL_INVALID_VALUE);
1583      return;
1584   }
1585
1586   switch (type) {
1587   case GL_FLOAT:
1588      opcode = 4124;
1589      break;
1590   case GL_DOUBLE:
1591      opcode = 4125;
1592      break;
1593   default:
1594      __glXSetError(gc, GL_INVALID_ENUM);
1595      return;
1596   }
1597
1598   a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
1599   if (a == NULL) {
1600      __glXSetError(gc, GL_INVALID_OPERATION);
1601      return;
1602   }
1603
1604   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);
1605
1606   if (a->enabled) {
1607      arrays->array_info_cache_valid = GL_FALSE;
1608   }
1609}
1610
1611
1612void
1613__indirect_glVertexAttribPointer(GLuint index, GLint size,
1614                                    GLenum type, GLboolean normalized,
1615                                    GLsizei stride, const GLvoid * pointer)
1616{
1617   static const uint16_t short_ops[5] = {
1618        0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB,
1619        X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB
1620   };
1621   static const uint16_t float_ops[5] = {
1622        0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB,
1623        X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB
1624   };
1625   static const uint16_t double_ops[5] = {
1626        0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB,
1627        X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB
1628   };
1629
1630   uint16_t opcode;
1631   struct glx_context *gc = __glXGetCurrentContext();
1632   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
1633   struct array_state_vector *arrays = state->array_state;
1634   struct array_state *a;
1635   unsigned true_immediate_count;
1636   unsigned true_immediate_size;
1637
1638
1639   if ((size < 1) || (size > 4) || (stride < 0)
1640       || (index > arrays->num_vertex_program_attribs)) {
1641      __glXSetError(gc, GL_INVALID_VALUE);
1642      return;
1643   }
1644
1645   if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
1646      switch (type) {
1647      case GL_BYTE:
1648         opcode = X_GLrop_VertexAttrib4NbvARB;
1649         break;
1650      case GL_UNSIGNED_BYTE:
1651         opcode = X_GLrop_VertexAttrib4NubvARB;
1652         break;
1653      case GL_SHORT:
1654         opcode = X_GLrop_VertexAttrib4NsvARB;
1655         break;
1656      case GL_UNSIGNED_SHORT:
1657         opcode = X_GLrop_VertexAttrib4NusvARB;
1658         break;
1659      case GL_INT:
1660         opcode = X_GLrop_VertexAttrib4NivARB;
1661         break;
1662      case GL_UNSIGNED_INT:
1663         opcode = X_GLrop_VertexAttrib4NuivARB;
1664         break;
1665      default:
1666         __glXSetError(gc, GL_INVALID_ENUM);
1667         return;
1668      }
1669
1670      true_immediate_count = 4;
1671   }
1672   else {
1673      true_immediate_count = size;
1674
1675      switch (type) {
1676      case GL_BYTE:
1677         opcode = X_GLrop_VertexAttrib4bvARB;
1678         true_immediate_count = 4;
1679         break;
1680      case GL_UNSIGNED_BYTE:
1681         opcode = X_GLrop_VertexAttrib4ubvARB;
1682         true_immediate_count = 4;
1683         break;
1684      case GL_SHORT:
1685         opcode = short_ops[size];
1686         break;
1687      case GL_UNSIGNED_SHORT:
1688         opcode = X_GLrop_VertexAttrib4usvARB;
1689         true_immediate_count = 4;
1690         break;
1691      case GL_INT:
1692         opcode = X_GLrop_VertexAttrib4ivARB;
1693         true_immediate_count = 4;
1694         break;
1695      case GL_UNSIGNED_INT:
1696         opcode = X_GLrop_VertexAttrib4uivARB;
1697         true_immediate_count = 4;
1698         break;
1699      case GL_FLOAT:
1700         opcode = float_ops[size];
1701         break;
1702      case GL_DOUBLE:
1703         opcode = double_ops[size];
1704         break;
1705      default:
1706         __glXSetError(gc, GL_INVALID_ENUM);
1707         return;
1708      }
1709   }
1710
1711   a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
1712   if (a == NULL) {
1713      __glXSetError(gc, GL_INVALID_OPERATION);
1714      return;
1715   }
1716
1717   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
1718                          opcode);
1719
1720   true_immediate_size = __glXTypeSize(type) * true_immediate_count;
1721   a->header[0] = __GLX_PAD(8 + true_immediate_size);
1722
1723   if (a->enabled) {
1724      arrays->array_info_cache_valid = GL_FALSE;
1725   }
1726}
1727
1728
1729/**
1730 * I don't have 100% confidence that this is correct.  The different rules
1731 * about whether or not generic vertex attributes alias "classic" vertex
1732 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
1733 * ARB_vertex_shader, and NV_vertex_program are a bit confusing.  My
1734 * feeling is that the client-side doesn't have to worry about it.  The
1735 * client just sends all the data to the server and lets the server deal
1736 * with it.
1737 */
1738void
1739__indirect_glVertexAttribPointerNV(GLuint index, GLint size,
1740                                   GLenum type, GLsizei stride,
1741                                   const GLvoid * pointer)
1742{
1743   struct glx_context *gc = __glXGetCurrentContext();
1744   GLboolean normalized = GL_FALSE;
1745
1746
1747   switch (type) {
1748   case GL_UNSIGNED_BYTE:
1749      if (size != 4) {
1750         __glXSetError(gc, GL_INVALID_VALUE);
1751         return;
1752      }
1753      normalized = GL_TRUE;
1754      FALLTHROUGH;
1755   case GL_SHORT:
1756   case GL_FLOAT:
1757   case GL_DOUBLE:
1758      __indirect_glVertexAttribPointer(index, size, type,
1759                                          normalized, stride, pointer);
1760      return;
1761   default:
1762      __glXSetError(gc, GL_INVALID_ENUM);
1763      return;
1764   }
1765}
1766
1767
1768void
1769__indirect_glClientActiveTexture(GLenum texture)
1770{
1771   struct glx_context *const gc = __glXGetCurrentContext();
1772   __GLXattribute *const state =
1773      (__GLXattribute *) (gc->client_state_private);
1774   struct array_state_vector *const arrays = state->array_state;
1775   const GLint unit = (GLint) texture - GL_TEXTURE0;
1776
1777
1778   if ((unit < 0) || (unit >= arrays->num_texture_units)) {
1779      __glXSetError(gc, GL_INVALID_ENUM);
1780      return;
1781   }
1782
1783   arrays->active_texture_unit = unit;
1784}
1785
1786
1787/**
1788 * Modify the enable state for the selected array
1789 */
1790GLboolean
1791__glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
1792                    GLboolean enable)
1793{
1794   struct array_state_vector *arrays = state->array_state;
1795   struct array_state *a;
1796
1797
1798   /* Texture coordinate arrays have an implict index set when the
1799    * application calls glClientActiveTexture.
1800    */
1801   if (key == GL_TEXTURE_COORD_ARRAY) {
1802      index = arrays->active_texture_unit;
1803   }
1804
1805   a = get_array_entry(arrays, key, index);
1806
1807   if ((a != NULL) && (a->enabled != enable)) {
1808      a->enabled = enable;
1809      arrays->array_info_cache_valid = GL_FALSE;
1810   }
1811
1812   return (a != NULL);
1813}
1814
1815
1816void
1817__glXArrayDisableAll(__GLXattribute * state)
1818{
1819   struct array_state_vector *arrays = state->array_state;
1820   unsigned i;
1821
1822
1823   for (i = 0; i < arrays->num_arrays; i++) {
1824      arrays->arrays[i].enabled = GL_FALSE;
1825   }
1826
1827   arrays->array_info_cache_valid = GL_FALSE;
1828}
1829
1830
1831/**
1832 */
1833GLboolean
1834__glXGetArrayEnable(const __GLXattribute * const state,
1835                    GLenum key, unsigned index, GLintptr * dest)
1836{
1837   const struct array_state_vector *arrays = state->array_state;
1838   const struct array_state *a =
1839      get_array_entry((struct array_state_vector *) arrays,
1840                      key, index);
1841
1842   if (a != NULL) {
1843      *dest = (GLintptr) a->enabled;
1844   }
1845
1846   return (a != NULL);
1847}
1848
1849
1850/**
1851 */
1852GLboolean
1853__glXGetArrayType(const __GLXattribute * const state,
1854                  GLenum key, unsigned index, GLintptr * dest)
1855{
1856   const struct array_state_vector *arrays = state->array_state;
1857   const struct array_state *a =
1858      get_array_entry((struct array_state_vector *) arrays,
1859                      key, index);
1860
1861   if (a != NULL) {
1862      *dest = (GLintptr) a->data_type;
1863   }
1864
1865   return (a != NULL);
1866}
1867
1868
1869/**
1870 */
1871GLboolean
1872__glXGetArraySize(const __GLXattribute * const state,
1873                  GLenum key, unsigned index, GLintptr * dest)
1874{
1875   const struct array_state_vector *arrays = state->array_state;
1876   const struct array_state *a =
1877      get_array_entry((struct array_state_vector *) arrays,
1878                      key, index);
1879
1880   if (a != NULL) {
1881      *dest = (GLintptr) a->count;
1882   }
1883
1884   return (a != NULL);
1885}
1886
1887
1888/**
1889 */
1890GLboolean
1891__glXGetArrayStride(const __GLXattribute * const state,
1892                    GLenum key, unsigned index, GLintptr * dest)
1893{
1894   const struct array_state_vector *arrays = state->array_state;
1895   const struct array_state *a =
1896      get_array_entry((struct array_state_vector *) arrays,
1897                      key, index);
1898
1899   if (a != NULL) {
1900      *dest = (GLintptr) a->user_stride;
1901   }
1902
1903   return (a != NULL);
1904}
1905
1906
1907/**
1908 */
1909GLboolean
1910__glXGetArrayPointer(const __GLXattribute * const state,
1911                     GLenum key, unsigned index, void **dest)
1912{
1913   const struct array_state_vector *arrays = state->array_state;
1914   const struct array_state *a =
1915      get_array_entry((struct array_state_vector *) arrays,
1916                      key, index);
1917
1918
1919   if (a != NULL) {
1920      *dest = (void *) (a->data);
1921   }
1922
1923   return (a != NULL);
1924}
1925
1926
1927/**
1928 */
1929GLboolean
1930__glXGetArrayNormalized(const __GLXattribute * const state,
1931                        GLenum key, unsigned index, GLintptr * dest)
1932{
1933   const struct array_state_vector *arrays = state->array_state;
1934   const struct array_state *a =
1935      get_array_entry((struct array_state_vector *) arrays,
1936                      key, index);
1937
1938
1939   if (a != NULL) {
1940      *dest = (GLintptr) a->normalized;
1941   }
1942
1943   return (a != NULL);
1944}
1945
1946
1947/**
1948 */
1949GLuint
1950__glXGetActiveTextureUnit(const __GLXattribute * const state)
1951{
1952   return state->array_state->active_texture_unit;
1953}
1954
1955
1956void
1957__glXPushArrayState(__GLXattribute * state)
1958{
1959   struct array_state_vector *arrays = state->array_state;
1960   struct array_stack_state *stack =
1961      &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1962   unsigned i;
1963
1964   /* XXX are we pushing _all_ the necessary fields? */
1965   for (i = 0; i < arrays->num_arrays; i++) {
1966      stack[i].data = arrays->arrays[i].data;
1967      stack[i].data_type = arrays->arrays[i].data_type;
1968      stack[i].user_stride = arrays->arrays[i].user_stride;
1969      stack[i].count = arrays->arrays[i].count;
1970      stack[i].key = arrays->arrays[i].key;
1971      stack[i].index = arrays->arrays[i].index;
1972      stack[i].enabled = arrays->arrays[i].enabled;
1973   }
1974
1975   arrays->active_texture_unit_stack[arrays->stack_index] =
1976      arrays->active_texture_unit;
1977
1978   arrays->stack_index++;
1979}
1980
1981
1982void
1983__glXPopArrayState(__GLXattribute * state)
1984{
1985   struct array_state_vector *arrays = state->array_state;
1986   struct array_stack_state *stack;
1987   unsigned i;
1988
1989
1990   arrays->stack_index--;
1991   stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
1992
1993   for (i = 0; i < arrays->num_arrays; i++) {
1994      switch (stack[i].key) {
1995      case GL_NORMAL_ARRAY:
1996         __indirect_glNormalPointer(stack[i].data_type,
1997                                    stack[i].user_stride, stack[i].data);
1998         break;
1999      case GL_COLOR_ARRAY:
2000         __indirect_glColorPointer(stack[i].count,
2001                                   stack[i].data_type,
2002                                   stack[i].user_stride, stack[i].data);
2003         break;
2004      case GL_INDEX_ARRAY:
2005         __indirect_glIndexPointer(stack[i].data_type,
2006                                   stack[i].user_stride, stack[i].data);
2007         break;
2008      case GL_EDGE_FLAG_ARRAY:
2009         __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
2010         break;
2011      case GL_TEXTURE_COORD_ARRAY:
2012         arrays->active_texture_unit = stack[i].index;
2013         __indirect_glTexCoordPointer(stack[i].count,
2014                                      stack[i].data_type,
2015                                      stack[i].user_stride, stack[i].data);
2016         break;
2017      case GL_SECONDARY_COLOR_ARRAY:
2018         __indirect_glSecondaryColorPointer(stack[i].count,
2019                                               stack[i].data_type,
2020                                               stack[i].user_stride,
2021                                               stack[i].data);
2022         break;
2023      case GL_FOG_COORDINATE_ARRAY:
2024         __indirect_glFogCoordPointer(stack[i].data_type,
2025                                         stack[i].user_stride, stack[i].data);
2026         break;
2027
2028      }
2029
2030      __glXSetArrayEnable(state, stack[i].key, stack[i].index,
2031                          stack[i].enabled);
2032   }
2033
2034   arrays->active_texture_unit =
2035      arrays->active_texture_unit_stack[arrays->stack_index];
2036}
2037