/*
 * (C) Copyright IBM Corporation 2004, 2005
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sub license,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
 * IBM,
 * AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <inttypes.h>
#include <assert.h>
#include <string.h>

#include "glxclient.h"
#include "indirect.h"
#include <GL/glxproto.h>
#include "glxextensions.h"
#include "indirect_vertex_array.h"
#include "indirect_vertex_array_priv.h"

#define __GLX_PAD(n) (((n)+3) & ~3)

/**
 * \file indirect_vertex_array.c
 * Implement GLX protocol for vertex arrays and vertex buffer objects.
 *
 * The most important function in this fill is \c fill_array_info_cache.
 * The \c array_state_vector contains a cache of the ARRAY_INFO data sent
 * in the DrawArrays protocol.  Certain operations, such as enabling or
 * disabling an array, can invalidate this cache.  \c fill_array_info_cache
 * fills-in this data.  Additionally, it examines the enabled state and
 * other factors to determine what "version" of DrawArrays protocoal can be
 * used.
 *
 * Current, only two versions of DrawArrays protocol are implemented.  The
 * first version is the "none" protocol.  This is the fallback when the
 * server does not support GL 1.1 / EXT_vertex_arrays.  It is implemented
 * by sending batches of immediate mode commands that are equivalent to the
 * DrawArrays protocol.
 *
 * The other protocol that is currently implemented is the "old" protocol.
 * This is the GL 1.1 DrawArrays protocol.  The only difference between GL
 * 1.1 and EXT_vertex_arrays is the opcode used for the DrawArrays command.
 * This protocol is called "old" because the ARB is in the process of
 * defining a new protocol, which will probably be called wither "new" or
 * "vbo", to support multiple texture coordinate arrays, generic attributes,
 * and vertex buffer objects.
 *
 * \author Ian Romanick <ian.d.romanick@intel.com>
 */

static void emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count);
static void emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count);

static void emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
                                   const GLvoid * indices);
static void emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
                                  const GLvoid * indices);


static GLubyte *emit_element_none(GLubyte * dst,
                                  const struct array_state_vector *arrays,
                                  unsigned index);
static GLubyte *emit_element_old(GLubyte * dst,
                                 const struct array_state_vector *arrays,
                                 unsigned index);
static struct array_state *get_array_entry(const struct array_state_vector
                                           *arrays, GLenum key,
                                           unsigned index);
static void fill_array_info_cache(struct array_state_vector *arrays);
static GLboolean validate_mode(struct glx_context * gc, GLenum mode);
static GLboolean validate_count(struct glx_context * gc, GLsizei count);
static GLboolean validate_type(struct glx_context * gc, GLenum type);


/**
 * Table of sizes, in bytes, of a GL types.  All of the type enums are be in
 * the range 0x1400 - 0x140F.  That includes types added by extensions (i.e.,
 * \c GL_HALF_FLOAT_NV).  This elements of this table correspond to the
 * type enums masked with 0x0f.
 *
 * \notes
 * \c GL_HALF_FLOAT_NV is not included.  Neither are \c GL_2_BYTES,
 * \c GL_3_BYTES, or \c GL_4_BYTES.
 */
const GLuint __glXTypeSize_table[16] = {
   1, 1, 2, 2, 4, 4, 4, 0, 0, 0, 8, 0, 0, 0, 0, 0
};


/**
 * Free the per-context array state that was allocated with
 * __glXInitVertexArrayState().
 */
void
__glXFreeVertexArrayState(struct glx_context * gc)
{
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;

   if (arrays) {
      free(arrays->stack);
      arrays->stack = NULL;
      free(arrays->arrays);
      arrays->arrays = NULL;
      free(arrays);
      state->array_state = NULL;
   }
}


/**
 * Initialize vertex array state of a GLX context.
 *
 * \param gc  GLX context whose vertex array state is to be initialized.
 *
 * \warning
 * This function may only be called after struct glx_context::gl_extension_bits,
 * struct glx_context::server_minor, and __GLXcontext::server_major have been
 * initialized.  These values are used to determine what vertex arrays are
 * supported.
 */
void
__glXInitVertexArrayState(struct glx_context * gc)
{
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays;

   unsigned array_count;
   int texture_units = 1, vertex_program_attribs = 0;
   unsigned i, j;

   GLboolean got_fog = GL_FALSE;
   GLboolean got_secondary_color = GL_FALSE;


   arrays = calloc(1, sizeof(struct array_state_vector));
   state->array_state = arrays;

   if (arrays == NULL) {
      __glXSetError(gc, GL_OUT_OF_MEMORY);
      return;
   }

   arrays->old_DrawArrays_possible = !state->NoDrawArraysProtocol;
   arrays->new_DrawArrays_possible = GL_FALSE;
   arrays->DrawArrays = NULL;

   arrays->active_texture_unit = 0;


   /* Determine how many arrays are actually needed.  Only arrays that
    * are supported by the server are create.  For example, if the server
    * supports only 2 texture units, then only 2 texture coordinate arrays
    * are created.
    *
    * At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
    * GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
    * GL_EDGE_FLAG_ARRAY are supported.
    */

   array_count = 5;

   if (__glExtensionBitIsEnabled(gc, GL_EXT_fog_coord_bit)
       || (gc->server_major > 1) || (gc->server_minor >= 4)) {
      got_fog = GL_TRUE;
      array_count++;
   }

   if (__glExtensionBitIsEnabled(gc, GL_EXT_secondary_color_bit)
       || (gc->server_major > 1) || (gc->server_minor >= 4)) {
      got_secondary_color = GL_TRUE;
      array_count++;
   }

   if (__glExtensionBitIsEnabled(gc, GL_ARB_multitexture_bit)
       || (gc->server_major > 1) || (gc->server_minor >= 3)) {
      __indirect_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &texture_units);
   }

   if (__glExtensionBitIsEnabled(gc, GL_ARB_vertex_program_bit)) {
      __indirect_glGetProgramivARB(GL_VERTEX_PROGRAM_ARB,
                                   GL_MAX_PROGRAM_ATTRIBS_ARB,
                                   &vertex_program_attribs);
   }

   arrays->num_texture_units = texture_units;
   arrays->num_vertex_program_attribs = vertex_program_attribs;
   array_count += texture_units + vertex_program_attribs;
   arrays->num_arrays = array_count;
   arrays->arrays = calloc(array_count, sizeof(struct array_state));

   if (arrays->arrays == NULL) {
      state->array_state = NULL;
      free(arrays);
      __glXSetError(gc, GL_OUT_OF_MEMORY);
      return;
   }

   arrays->arrays[0].data_type = GL_FLOAT;
   arrays->arrays[0].count = 3;
   arrays->arrays[0].key = GL_NORMAL_ARRAY;
   arrays->arrays[0].normalized = GL_TRUE;
   arrays->arrays[0].old_DrawArrays_possible = GL_TRUE;

   arrays->arrays[1].data_type = GL_FLOAT;
   arrays->arrays[1].count = 4;
   arrays->arrays[1].key = GL_COLOR_ARRAY;
   arrays->arrays[1].normalized = GL_TRUE;
   arrays->arrays[1].old_DrawArrays_possible = GL_TRUE;

   arrays->arrays[2].data_type = GL_FLOAT;
   arrays->arrays[2].count = 1;
   arrays->arrays[2].key = GL_INDEX_ARRAY;
   arrays->arrays[2].old_DrawArrays_possible = GL_TRUE;

   arrays->arrays[3].data_type = GL_UNSIGNED_BYTE;
   arrays->arrays[3].count = 1;
   arrays->arrays[3].key = GL_EDGE_FLAG_ARRAY;
   arrays->arrays[3].old_DrawArrays_possible = GL_TRUE;

   for (i = 0; i < texture_units; i++) {
      arrays->arrays[4 + i].data_type = GL_FLOAT;
      arrays->arrays[4 + i].count = 4;
      arrays->arrays[4 + i].key = GL_TEXTURE_COORD_ARRAY;

      arrays->arrays[4 + i].old_DrawArrays_possible = (i == 0);
      arrays->arrays[4 + i].index = i;
   }

   i = 4 + texture_units;

   if (got_fog) {
      arrays->arrays[i].data_type = GL_FLOAT;
      arrays->arrays[i].count = 1;
      arrays->arrays[i].key = GL_FOG_COORDINATE_ARRAY;
      arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
      i++;
   }

   if (got_secondary_color) {
      arrays->arrays[i].data_type = GL_FLOAT;
      arrays->arrays[i].count = 3;
      arrays->arrays[i].key = GL_SECONDARY_COLOR_ARRAY;
      arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;
      arrays->arrays[i].normalized = GL_TRUE;
      i++;
   }


   for (j = 0; j < vertex_program_attribs; j++) {
      const unsigned idx = (vertex_program_attribs - (j + 1));


      arrays->arrays[idx + i].data_type = GL_FLOAT;
      arrays->arrays[idx + i].count = 4;
      arrays->arrays[idx + i].key = GL_VERTEX_ATTRIB_ARRAY_POINTER;

      arrays->arrays[idx + i].old_DrawArrays_possible = 0;
      arrays->arrays[idx + i].index = idx;
   }

   i += vertex_program_attribs;


   /* Vertex array *must* be last because of the way that
    * emit_DrawArrays_none works.
    */

   arrays->arrays[i].data_type = GL_FLOAT;
   arrays->arrays[i].count = 4;
   arrays->arrays[i].key = GL_VERTEX_ARRAY;
   arrays->arrays[i].old_DrawArrays_possible = GL_TRUE;

   assert((i + 1) == arrays->num_arrays);

   arrays->stack_index = 0;
   arrays->stack = malloc(sizeof(struct array_stack_state)
                          * arrays->num_arrays
                          * __GL_CLIENT_ATTRIB_STACK_DEPTH);

   if (arrays->stack == NULL) {
      state->array_state = NULL;
      free(arrays->arrays);
      free(arrays);
      __glXSetError(gc, GL_OUT_OF_MEMORY);
      return;
   }
}


/**
 * Calculate the size of a single vertex for the "none" protocol.  This is
 * essentially the size of all the immediate-mode commands required to
 * implement the enabled vertex arrays.
 */
static size_t
calculate_single_vertex_size_none(const struct array_state_vector *arrays)
{
   size_t single_vertex_size = 0;
   unsigned i;


   for (i = 0; i < arrays->num_arrays; i++) {
      if (arrays->arrays[i].enabled) {
         single_vertex_size += arrays->arrays[i].header[0];
      }
   }

   return single_vertex_size;
}


/**
 * Emit a single element using non-DrawArrays protocol.
 */
GLubyte *
emit_element_none(GLubyte * dst,
                  const struct array_state_vector * arrays, unsigned index)
{
   unsigned i;


   for (i = 0; i < arrays->num_arrays; i++) {
      if (arrays->arrays[i].enabled) {
         const size_t offset = index * arrays->arrays[i].true_stride;

         /* The generic attributes can have more data than is in the
          * elements.  This is because a vertex array can be a 2 element,
          * normalized, unsigned short, but the "closest" immediate mode
          * protocol is for a 4Nus.  Since the sizes are small, the
          * performance impact on modern processors should be negligible.
          */
         (void) memset(dst, 0, arrays->arrays[i].header[0]);

         (void) memcpy(dst, arrays->arrays[i].header, 4);

         dst += 4;

         if (arrays->arrays[i].key == GL_TEXTURE_COORD_ARRAY &&
             arrays->arrays[i].index > 0) {
            /* Multi-texture coordinate arrays require the texture target
             * to be sent.  For doubles it is after the data, for everything
             * else it is before.
             */
            GLenum texture = arrays->arrays[i].index + GL_TEXTURE0;
            if (arrays->arrays[i].data_type == GL_DOUBLE) {
               (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
                             arrays->arrays[i].element_size);
               dst += arrays->arrays[i].element_size;
               (void) memcpy(dst, &texture, 4);
               dst += 4;
            } else {
               (void) memcpy(dst, &texture, 4);
               dst += 4;
               (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
                             arrays->arrays[i].element_size);
               dst += __GLX_PAD(arrays->arrays[i].element_size);
            }
         } else if (arrays->arrays[i].key == GL_VERTEX_ATTRIB_ARRAY_POINTER) {
            /* Vertex attribute data requires the index sent first.
             */
            (void) memcpy(dst, &arrays->arrays[i].index, 4);
            dst += 4;
            (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
                          arrays->arrays[i].element_size);
            dst += __GLX_PAD(arrays->arrays[i].element_size);
         } else {
            (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
                          arrays->arrays[i].element_size);
            dst += __GLX_PAD(arrays->arrays[i].element_size);
         }
      }
   }

   return dst;
}


/**
 * Emit a single element using "old" DrawArrays protocol from
 * EXT_vertex_arrays / OpenGL 1.1.
 */
GLubyte *
emit_element_old(GLubyte * dst,
                 const struct array_state_vector * arrays, unsigned index)
{
   unsigned i;


   for (i = 0; i < arrays->num_arrays; i++) {
      if (arrays->arrays[i].enabled) {
         const size_t offset = index * arrays->arrays[i].true_stride;

         (void) memcpy(dst, ((GLubyte *) arrays->arrays[i].data) + offset,
                       arrays->arrays[i].element_size);

         dst += __GLX_PAD(arrays->arrays[i].element_size);
      }
   }

   return dst;
}


struct array_state *
get_array_entry(const struct array_state_vector *arrays,
                GLenum key, unsigned index)
{
   unsigned i;

   for (i = 0; i < arrays->num_arrays; i++) {
      if ((arrays->arrays[i].key == key)
          && (arrays->arrays[i].index == index)) {
         return &arrays->arrays[i];
      }
   }

   return NULL;
}


static GLboolean
allocate_array_info_cache(struct array_state_vector *arrays,
                          size_t required_size)
{
#define MAX_HEADER_SIZE 20
   if (arrays->array_info_cache_buffer_size < required_size) {
      GLubyte *temp = realloc(arrays->array_info_cache_base,
                              required_size + MAX_HEADER_SIZE);

      if (temp == NULL) {
         return GL_FALSE;
      }

      arrays->array_info_cache_base = temp;
      arrays->array_info_cache = temp + MAX_HEADER_SIZE;
      arrays->array_info_cache_buffer_size = required_size;
   }

   arrays->array_info_cache_size = required_size;
   return GL_TRUE;
}


/**
 */
void
fill_array_info_cache(struct array_state_vector *arrays)
{
   GLboolean old_DrawArrays_possible;
   unsigned i;


   /* Determine how many arrays are enabled.
    */

   arrays->enabled_client_array_count = 0;
   old_DrawArrays_possible = arrays->old_DrawArrays_possible;
   for (i = 0; i < arrays->num_arrays; i++) {
      if (arrays->arrays[i].enabled) {
         arrays->enabled_client_array_count++;
         old_DrawArrays_possible &= arrays->arrays[i].old_DrawArrays_possible;
      }
   }

   if (arrays->new_DrawArrays_possible) {
      assert(!arrays->new_DrawArrays_possible);
   }
   else if (old_DrawArrays_possible) {
      const size_t required_size = arrays->enabled_client_array_count * 12;
      uint32_t *info;


      if (!allocate_array_info_cache(arrays, required_size)) {
         return;
      }


      info = (uint32_t *) arrays->array_info_cache;
      for (i = 0; i < arrays->num_arrays; i++) {
         if (arrays->arrays[i].enabled) {
            *(info++) = arrays->arrays[i].data_type;
            *(info++) = arrays->arrays[i].count;
            *(info++) = arrays->arrays[i].key;
         }
      }

      arrays->DrawArrays = emit_DrawArrays_old;
      arrays->DrawElements = emit_DrawElements_old;
   }
   else {
      arrays->DrawArrays = emit_DrawArrays_none;
      arrays->DrawElements = emit_DrawElements_none;
   }

   arrays->array_info_cache_valid = GL_TRUE;
}


/**
 * Emit a \c glDrawArrays command using the "none" protocol.  That is,
 * emit immediate-mode commands that are equivalent to the requiested
 * \c glDrawArrays command.  This is used with servers that don't support
 * the OpenGL 1.1 / EXT_vertex_arrays DrawArrays protocol or in cases where
 * vertex state is enabled that is not compatible with that protocol.
 */
void
emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;

   size_t single_vertex_size;
   GLubyte *pc;
   unsigned i;
   static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
   static const uint16_t end_cmd[2] = { 4, X_GLrop_End };


   single_vertex_size = calculate_single_vertex_size_none(arrays);

   pc = gc->pc;

   (void) memcpy(pc, begin_cmd, 4);
   *(int *) (pc + 4) = mode;

   pc += 8;

   for (i = 0; i < count; i++) {
      if ((pc + single_vertex_size) >= gc->bufEnd) {
         pc = __glXFlushRenderBuffer(gc, pc);
      }

      pc = emit_element_none(pc, arrays, first + i);
   }

   if ((pc + 4) >= gc->bufEnd) {
      pc = __glXFlushRenderBuffer(gc, pc);
   }

   (void) memcpy(pc, end_cmd, 4);
   pc += 4;

   gc->pc = pc;
   if (gc->pc > gc->limit) {
      (void) __glXFlushRenderBuffer(gc, gc->pc);
   }
}


/**
 * Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
 * protocol.
 *
 * \param gc                    GLX context.
 * \param arrays                Array state.
 * \param elements_per_request  Location to store the number of elements that
 *                              can fit in a single Render / RenderLarge
 *                              command.
 * \param total_request         Total number of requests for a RenderLarge
 *                              command.  If a Render command is used, this
 *                              will be zero.
 * \param mode                  Drawing mode.
 * \param count                 Number of vertices.
 *
 * \returns
 * A pointer to the buffer for array data.
 */
static GLubyte *
emit_DrawArrays_header_old(struct glx_context * gc,
                           struct array_state_vector *arrays,
                           size_t * elements_per_request,
                           unsigned int *total_requests,
                           GLenum mode, GLsizei count)
{
   size_t command_size;
   size_t single_vertex_size;
   const unsigned header_size = 16;
   unsigned i;
   GLubyte *pc;


   /* Determine the size of the whole command.  This includes the header,
    * the ARRAY_INFO data and the array data.  Once this size is calculated,
    * it will be known whether a Render or RenderLarge command is needed.
    */

   single_vertex_size = 0;
   for (i = 0; i < arrays->num_arrays; i++) {
      if (arrays->arrays[i].enabled) {
         single_vertex_size += __GLX_PAD(arrays->arrays[i].element_size);
      }
   }

   command_size = arrays->array_info_cache_size + header_size
      + (single_vertex_size * count);


   /* Write the header for either a Render command or a RenderLarge
    * command.  After the header is written, write the ARRAY_INFO data.
    */

   if (command_size > gc->maxSmallRenderCommandSize) {
      /* maxSize is the maximum amount of data can be stuffed into a single
       * packet.  sz_xGLXRenderReq is added because bufSize is the maximum
       * packet size minus sz_xGLXRenderReq.
       */
      const size_t maxSize = (gc->bufSize + sz_xGLXRenderReq)
         - sz_xGLXRenderLargeReq;
      unsigned vertex_requests;


      /* Calculate the number of data packets that will be required to send
       * the whole command.  To do this, the number of verticies that
       * will fit in a single buffer must be calculated.
       *
       * The important value here is elements_per_request.  This is the
       * number of complete array elements that will fit in a single
       * buffer.  There may be some wasted space at the end of the buffer,
       * but splitting elements across buffer boundries would be painful.
       */

      elements_per_request[0] = maxSize / single_vertex_size;

      vertex_requests = (count + elements_per_request[0] - 1)
         / elements_per_request[0];

      *total_requests = vertex_requests + 1;


      __glXFlushRenderBuffer(gc, gc->pc);

      command_size += 4;

      pc = ((GLubyte *) arrays->array_info_cache) - (header_size + 4);
      *(uint32_t *) (pc + 0) = command_size;
      *(uint32_t *) (pc + 4) = X_GLrop_DrawArrays;
      *(uint32_t *) (pc + 8) = count;
      *(uint32_t *) (pc + 12) = arrays->enabled_client_array_count;
      *(uint32_t *) (pc + 16) = mode;

      __glXSendLargeChunk(gc, 1, *total_requests, pc,
                          header_size + 4 + arrays->array_info_cache_size);

      pc = gc->pc;
   }
   else {
      if ((gc->pc + command_size) >= gc->bufEnd) {
         (void) __glXFlushRenderBuffer(gc, gc->pc);
      }

      pc = gc->pc;
      *(uint16_t *) (pc + 0) = command_size;
      *(uint16_t *) (pc + 2) = X_GLrop_DrawArrays;
      *(uint32_t *) (pc + 4) = count;
      *(uint32_t *) (pc + 8) = arrays->enabled_client_array_count;
      *(uint32_t *) (pc + 12) = mode;

      pc += header_size;

      (void) memcpy(pc, arrays->array_info_cache,
                    arrays->array_info_cache_size);
      pc += arrays->array_info_cache_size;

      *elements_per_request = count;
      *total_requests = 0;
   }


   return pc;
}


/**
 */
void
emit_DrawArrays_old(GLenum mode, GLint first, GLsizei count)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;

   GLubyte *pc;
   size_t elements_per_request;
   unsigned total_requests = 0;
   unsigned i;
   size_t total_sent = 0;


   pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
                                   &total_requests, mode, count);


   /* Write the arrays.
    */

   if (total_requests == 0) {
      assert(elements_per_request >= count);

      for (i = 0; i < count; i++) {
         pc = emit_element_old(pc, arrays, i + first);
      }

      assert(pc <= gc->bufEnd);

      gc->pc = pc;
      if (gc->pc > gc->limit) {
         (void) __glXFlushRenderBuffer(gc, gc->pc);
      }
   }
   else {
      unsigned req;


      for (req = 2; req <= total_requests; req++) {
         if (count < elements_per_request) {
            elements_per_request = count;
         }

         pc = gc->pc;
         for (i = 0; i < elements_per_request; i++) {
            pc = emit_element_old(pc, arrays, i + first);
         }

         first += elements_per_request;

         total_sent += (size_t) (pc - gc->pc);
         __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);

         count -= elements_per_request;
      }
   }
}


void
emit_DrawElements_none(GLenum mode, GLsizei count, GLenum type,
                       const GLvoid * indices)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   static const uint16_t begin_cmd[2] = { 8, X_GLrop_Begin };
   static const uint16_t end_cmd[2] = { 4, X_GLrop_End };

   GLubyte *pc;
   size_t single_vertex_size;
   unsigned i;


   single_vertex_size = calculate_single_vertex_size_none(arrays);


   if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
      gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
   }

   pc = gc->pc;

   (void) memcpy(pc, begin_cmd, 4);
   *(int *) (pc + 4) = mode;

   pc += 8;

   for (i = 0; i < count; i++) {
      unsigned index = 0;

      if ((pc + single_vertex_size) >= gc->bufEnd) {
         pc = __glXFlushRenderBuffer(gc, pc);
      }

      switch (type) {
      case GL_UNSIGNED_INT:
         index = (unsigned) (((GLuint *) indices)[i]);
         break;
      case GL_UNSIGNED_SHORT:
         index = (unsigned) (((GLushort *) indices)[i]);
         break;
      case GL_UNSIGNED_BYTE:
         index = (unsigned) (((GLubyte *) indices)[i]);
         break;
      }
      pc = emit_element_none(pc, arrays, index);
   }

   if ((pc + 4) >= gc->bufEnd) {
      pc = __glXFlushRenderBuffer(gc, pc);
   }

   (void) memcpy(pc, end_cmd, 4);
   pc += 4;

   gc->pc = pc;
   if (gc->pc > gc->limit) {
      (void) __glXFlushRenderBuffer(gc, gc->pc);
   }
}


/**
 */
void
emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
                      const GLvoid * indices)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;

   GLubyte *pc;
   size_t elements_per_request;
   unsigned total_requests = 0;
   unsigned i;
   unsigned req;
   unsigned req_element = 0;


   pc = emit_DrawArrays_header_old(gc, arrays, &elements_per_request,
                                   &total_requests, mode, count);


   /* Write the arrays.
    */

   req = 2;
   while (count > 0) {
      if (count < elements_per_request) {
         elements_per_request = count;
      }

      switch (type) {
      case GL_UNSIGNED_INT:{
            const GLuint *ui_ptr = (const GLuint *) indices + req_element;

            for (i = 0; i < elements_per_request; i++) {
               const GLint index = (GLint) * (ui_ptr++);
               pc = emit_element_old(pc, arrays, index);
            }
            break;
         }
      case GL_UNSIGNED_SHORT:{
            const GLushort *us_ptr = (const GLushort *) indices + req_element;

            for (i = 0; i < elements_per_request; i++) {
               const GLint index = (GLint) * (us_ptr++);
               pc = emit_element_old(pc, arrays, index);
            }
            break;
         }
      case GL_UNSIGNED_BYTE:{
            const GLubyte *ub_ptr = (const GLubyte *) indices + req_element;

            for (i = 0; i < elements_per_request; i++) {
               const GLint index = (GLint) * (ub_ptr++);
               pc = emit_element_old(pc, arrays, index);
            }
            break;
         }
      }

      if (total_requests != 0) {
         __glXSendLargeChunk(gc, req, total_requests, gc->pc, pc - gc->pc);
         pc = gc->pc;
         req++;
      }

      count -= elements_per_request;
      req_element += elements_per_request;
   }


   assert((total_requests == 0) || ((req - 1) == total_requests));

   if (total_requests == 0) {
      assert(pc <= gc->bufEnd);

      gc->pc = pc;
      if (gc->pc > gc->limit) {
         (void) __glXFlushRenderBuffer(gc, gc->pc);
      }
   }
}


/**
 * Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
 * If it is not valid, then an error code is set in the GLX context.
 *
 * \returns
 * \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
 */
static GLboolean
validate_mode(struct glx_context * gc, GLenum mode)
{
   switch (mode) {
   case GL_POINTS:
   case GL_LINE_STRIP:
   case GL_LINE_LOOP:
   case GL_LINES:
   case GL_TRIANGLE_STRIP:
   case GL_TRIANGLE_FAN:
   case GL_TRIANGLES:
   case GL_QUAD_STRIP:
   case GL_QUADS:
   case GL_POLYGON:
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return GL_FALSE;
   }

   return GL_TRUE;
}


/**
 * Validate that the \c count parameter to \c glDrawArrays, et. al. is valid.
 * A value less than zero is invalid and will result in \c GL_INVALID_VALUE
 * being set.  A value of zero will not result in an error being set, but
 * will result in \c GL_FALSE being returned.
 *
 * \returns
 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
 */
static GLboolean
validate_count(struct glx_context * gc, GLsizei count)
{
   if (count < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
   }

   return (count > 0);
}


/**
 * Validate that the \c type parameter to \c glDrawElements, et. al. is
 * valid.  Only \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, and
 * \c GL_UNSIGNED_INT are valid.
 *
 * \returns
 * \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
 */
static GLboolean
validate_type(struct glx_context * gc, GLenum type)
{
   switch (type) {
   case GL_UNSIGNED_INT:
   case GL_UNSIGNED_SHORT:
   case GL_UNSIGNED_BYTE:
      return GL_TRUE;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return GL_FALSE;
   }
}


void
__indirect_glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;


   if (validate_mode(gc, mode) && validate_count(gc, count)) {
      if (!arrays->array_info_cache_valid) {
         fill_array_info_cache(arrays);
      }

      arrays->DrawArrays(mode, first, count);
   }
}


void
__indirect_glArrayElement(GLint index)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;

   size_t single_vertex_size;


   single_vertex_size = calculate_single_vertex_size_none(arrays);

   if ((gc->pc + single_vertex_size) >= gc->bufEnd) {
      gc->pc = __glXFlushRenderBuffer(gc, gc->pc);
   }

   gc->pc = emit_element_none(gc->pc, arrays, index);

   if (gc->pc > gc->limit) {
      (void) __glXFlushRenderBuffer(gc, gc->pc);
   }
}


void
__indirect_glDrawElements(GLenum mode, GLsizei count, GLenum type,
                          const GLvoid * indices)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;


   if (validate_mode(gc, mode) && validate_count(gc, count)
       && validate_type(gc, type)) {
      if (!arrays->array_info_cache_valid) {
         fill_array_info_cache(arrays);
      }

      arrays->DrawElements(mode, count, type, indices);
   }
}


void
__indirect_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
                               GLsizei count, GLenum type,
                               const GLvoid * indices)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;


   if (validate_mode(gc, mode) && validate_count(gc, count)
       && validate_type(gc, type)) {
      if (end < start) {
         __glXSetError(gc, GL_INVALID_VALUE);
         return;
      }

      if (!arrays->array_info_cache_valid) {
         fill_array_info_cache(arrays);
      }

      arrays->DrawElements(mode, count, type, indices);
   }
}


void
__indirect_glMultiDrawArrays(GLenum mode, const GLint *first,
                                const GLsizei *count, GLsizei primcount)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   GLsizei i;


   if (validate_mode(gc, mode)) {
      if (!arrays->array_info_cache_valid) {
         fill_array_info_cache(arrays);
      }

      for (i = 0; i < primcount; i++) {
         if (validate_count(gc, count[i])) {
            arrays->DrawArrays(mode, first[i], count[i]);
         }
      }
   }
}


void
__indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
                                  GLenum type, const GLvoid * const * indices,
                                  GLsizei primcount)
{
   struct glx_context *gc = __glXGetCurrentContext();
   const __GLXattribute *state =
      (const __GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   GLsizei i;


   if (validate_mode(gc, mode) && validate_type(gc, type)) {
      if (!arrays->array_info_cache_valid) {
         fill_array_info_cache(arrays);
      }

      for (i = 0; i < primcount; i++) {
         if (validate_count(gc, count[i])) {
            arrays->DrawElements(mode, count[i], type, indices[i]);
         }
      }
   }
}


/* The HDR_SIZE macro argument is the command header size (4 bytes)
 * plus any additional index word e.g. for texture units or vertex
 * attributes.
 */
#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
  do {                                                                  \
    (a)->data = PTR;                                                    \
    (a)->data_type = TYPE;                                              \
    (a)->user_stride = STRIDE;                                          \
    (a)->count = COUNT;                                                 \
    (a)->normalized = NORMALIZED;                                       \
                                                                        \
    (a)->element_size = __glXTypeSize( TYPE ) * COUNT;                  \
    (a)->true_stride = (STRIDE == 0)                                    \
      ? (a)->element_size : STRIDE;                                     \
                                                                        \
    (a)->header[0] = __GLX_PAD(HDR_SIZE + (a)->element_size);           \
    (a)->header[1] = OPCODE;                                            \
  } while(0)


void
__indirect_glVertexPointer(GLint size, GLenum type, GLsizei stride,
                           const GLvoid * pointer)
{
   static const uint16_t short_ops[5] = {
      0, 0, X_GLrop_Vertex2sv, X_GLrop_Vertex3sv, X_GLrop_Vertex4sv
   };
   static const uint16_t int_ops[5] = {
      0, 0, X_GLrop_Vertex2iv, X_GLrop_Vertex3iv, X_GLrop_Vertex4iv
   };
   static const uint16_t float_ops[5] = {
      0, 0, X_GLrop_Vertex2fv, X_GLrop_Vertex3fv, X_GLrop_Vertex4fv
   };
   static const uint16_t double_ops[5] = {
      0, 0, X_GLrop_Vertex2dv, X_GLrop_Vertex3dv, X_GLrop_Vertex4dv
   };
   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (size < 2 || size > 4 || stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   switch (type) {
   case GL_SHORT:
      opcode = short_ops[size];
      break;
   case GL_INT:
      opcode = int_ops[size];
      break;
   case GL_FLOAT:
      opcode = float_ops[size];
      break;
   case GL_DOUBLE:
      opcode = double_ops[size];
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   a = get_array_entry(arrays, GL_VERTEX_ARRAY, 0);
   assert(a != NULL);
   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE, 4,
                          opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glNormalPointer(GLenum type, GLsizei stride,
                           const GLvoid * pointer)
{
   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   switch (type) {
   case GL_BYTE:
      opcode = X_GLrop_Normal3bv;
      break;
   case GL_SHORT:
      opcode = X_GLrop_Normal3sv;
      break;
   case GL_INT:
      opcode = X_GLrop_Normal3iv;
      break;
   case GL_FLOAT:
      opcode = X_GLrop_Normal3fv;
      break;
   case GL_DOUBLE:
      opcode = X_GLrop_Normal3dv;
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   a = get_array_entry(arrays, GL_NORMAL_ARRAY, 0);
   assert(a != NULL);
   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 3, GL_TRUE, 4, opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glColorPointer(GLint size, GLenum type, GLsizei stride,
                          const GLvoid * pointer)
{
   static const uint16_t byte_ops[5] = {
      0, 0, 0, X_GLrop_Color3bv, X_GLrop_Color4bv
   };
   static const uint16_t ubyte_ops[5] = {
      0, 0, 0, X_GLrop_Color3ubv, X_GLrop_Color4ubv
   };
   static const uint16_t short_ops[5] = {
      0, 0, 0, X_GLrop_Color3sv, X_GLrop_Color4sv
   };
   static const uint16_t ushort_ops[5] = {
      0, 0, 0, X_GLrop_Color3usv, X_GLrop_Color4usv
   };
   static const uint16_t int_ops[5] = {
      0, 0, 0, X_GLrop_Color3iv, X_GLrop_Color4iv
   };
   static const uint16_t uint_ops[5] = {
      0, 0, 0, X_GLrop_Color3uiv, X_GLrop_Color4uiv
   };
   static const uint16_t float_ops[5] = {
      0, 0, 0, X_GLrop_Color3fv, X_GLrop_Color4fv
   };
   static const uint16_t double_ops[5] = {
      0, 0, 0, X_GLrop_Color3dv, X_GLrop_Color4dv
   };
   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (size < 3 || size > 4 || stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   switch (type) {
   case GL_BYTE:
      opcode = byte_ops[size];
      break;
   case GL_UNSIGNED_BYTE:
      opcode = ubyte_ops[size];
      break;
   case GL_SHORT:
      opcode = short_ops[size];
      break;
   case GL_UNSIGNED_SHORT:
      opcode = ushort_ops[size];
      break;
   case GL_INT:
      opcode = int_ops[size];
      break;
   case GL_UNSIGNED_INT:
      opcode = uint_ops[size];
      break;
   case GL_FLOAT:
      opcode = float_ops[size];
      break;
   case GL_DOUBLE:
      opcode = double_ops[size];
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   a = get_array_entry(arrays, GL_COLOR_ARRAY, 0);
   assert(a != NULL);
   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer)
{
   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   switch (type) {
   case GL_UNSIGNED_BYTE:
      opcode = X_GLrop_Indexubv;
      break;
   case GL_SHORT:
      opcode = X_GLrop_Indexsv;
      break;
   case GL_INT:
      opcode = X_GLrop_Indexiv;
      break;
   case GL_FLOAT:
      opcode = X_GLrop_Indexfv;
      break;
   case GL_DOUBLE:
      opcode = X_GLrop_Indexdv;
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   a = get_array_entry(arrays, GL_INDEX_ARRAY, 0);
   assert(a != NULL);
   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer)
{
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }


   a = get_array_entry(arrays, GL_EDGE_FLAG_ARRAY, 0);
   assert(a != NULL);
   COMMON_ARRAY_DATA_INIT(a, pointer, GL_UNSIGNED_BYTE, stride, 1, GL_FALSE,
                          4, X_GLrop_EdgeFlagv);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
                             const GLvoid * pointer)
{
   static const uint16_t short_ops[5] = {
      0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
      X_GLrop_TexCoord4sv
   };
   static const uint16_t int_ops[5] = {
      0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
      X_GLrop_TexCoord4iv
   };
   static const uint16_t float_ops[5] = {
      0, X_GLrop_TexCoord1fv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
      X_GLrop_TexCoord4fv
   };
   static const uint16_t double_ops[5] = {
      0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
      X_GLrop_TexCoord4dv
   };

   static const uint16_t mshort_ops[5] = {
      0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
      X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
   };
   static const uint16_t mint_ops[5] = {
      0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
      X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
   };
   static const uint16_t mfloat_ops[5] = {
      0, X_GLrop_MultiTexCoord1fvARB, X_GLrop_MultiTexCoord2fvARB,
      X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
   };
   static const uint16_t mdouble_ops[5] = {
      0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
      X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
   };

   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;
   unsigned header_size;
   unsigned index;


   if (size < 1 || size > 4 || stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   index = arrays->active_texture_unit;
   if (index == 0) {
      switch (type) {
      case GL_SHORT:
         opcode = short_ops[size];
         break;
      case GL_INT:
         opcode = int_ops[size];
         break;
      case GL_FLOAT:
         opcode = float_ops[size];
         break;
      case GL_DOUBLE:
         opcode = double_ops[size];
         break;
      default:
         __glXSetError(gc, GL_INVALID_ENUM);
         return;
      }

      header_size = 4;
   }
   else {
      switch (type) {
      case GL_SHORT:
         opcode = mshort_ops[size];
         break;
      case GL_INT:
         opcode = mint_ops[size];
         break;
      case GL_FLOAT:
         opcode = mfloat_ops[size];
         break;
      case GL_DOUBLE:
         opcode = mdouble_ops[size];
         break;
      default:
         __glXSetError(gc, GL_INVALID_ENUM);
         return;
      }

      header_size = 8;
   }

   a = get_array_entry(arrays, GL_TEXTURE_COORD_ARRAY, index);
   assert(a != NULL);
   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_FALSE,
                          header_size, opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,
                                      const GLvoid * pointer)
{
   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (size != 3 || stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   switch (type) {
   case GL_BYTE:
      opcode = 4126;
      break;
   case GL_UNSIGNED_BYTE:
      opcode = 4131;
      break;
   case GL_SHORT:
      opcode = 4127;
      break;
   case GL_UNSIGNED_SHORT:
      opcode = 4132;
      break;
   case GL_INT:
      opcode = 4128;
      break;
   case GL_UNSIGNED_INT:
      opcode = 4133;
      break;
   case GL_FLOAT:
      opcode = 4129;
      break;
   case GL_DOUBLE:
      opcode = 4130;
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   a = get_array_entry(arrays, GL_SECONDARY_COLOR_ARRAY, 0);
   if (a == NULL) {
      __glXSetError(gc, GL_INVALID_OPERATION);
      return;
   }

   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, GL_TRUE, 4, opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glFogCoordPointer(GLenum type, GLsizei stride,
                                const GLvoid * pointer)
{
   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   if (stride < 0) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   switch (type) {
   case GL_FLOAT:
      opcode = 4124;
      break;
   case GL_DOUBLE:
      opcode = 4125;
      break;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   a = get_array_entry(arrays, GL_FOG_COORD_ARRAY, 0);
   if (a == NULL) {
      __glXSetError(gc, GL_INVALID_OPERATION);
      return;
   }

   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, 1, GL_FALSE, 4, opcode);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


void
__indirect_glVertexAttribPointer(GLuint index, GLint size,
                                    GLenum type, GLboolean normalized,
                                    GLsizei stride, const GLvoid * pointer)
{
   static const uint16_t short_ops[5] = {
        0, X_GLrop_VertexAttrib1svARB, X_GLrop_VertexAttrib2svARB,
        X_GLrop_VertexAttrib3svARB, X_GLrop_VertexAttrib4svARB
   };
   static const uint16_t float_ops[5] = {
        0, X_GLrop_VertexAttrib1fvARB, X_GLrop_VertexAttrib2fvARB,
        X_GLrop_VertexAttrib3fvARB, X_GLrop_VertexAttrib4fvARB
   };
   static const uint16_t double_ops[5] = {
        0, X_GLrop_VertexAttrib1dvARB, X_GLrop_VertexAttrib2dvARB,
        X_GLrop_VertexAttrib3dvARB, X_GLrop_VertexAttrib4dvARB
   };

   uint16_t opcode;
   struct glx_context *gc = __glXGetCurrentContext();
   __GLXattribute *state = (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;
   unsigned true_immediate_count;
   unsigned true_immediate_size;


   if ((size < 1) || (size > 4) || (stride < 0)
       || (index > arrays->num_vertex_program_attribs)) {
      __glXSetError(gc, GL_INVALID_VALUE);
      return;
   }

   if (normalized && (type != GL_FLOAT) && (type != GL_DOUBLE)) {
      switch (type) {
      case GL_BYTE:
         opcode = X_GLrop_VertexAttrib4NbvARB;
         break;
      case GL_UNSIGNED_BYTE:
         opcode = X_GLrop_VertexAttrib4NubvARB;
         break;
      case GL_SHORT:
         opcode = X_GLrop_VertexAttrib4NsvARB;
         break;
      case GL_UNSIGNED_SHORT:
         opcode = X_GLrop_VertexAttrib4NusvARB;
         break;
      case GL_INT:
         opcode = X_GLrop_VertexAttrib4NivARB;
         break;
      case GL_UNSIGNED_INT:
         opcode = X_GLrop_VertexAttrib4NuivARB;
         break;
      default:
         __glXSetError(gc, GL_INVALID_ENUM);
         return;
      }

      true_immediate_count = 4;
   }
   else {
      true_immediate_count = size;

      switch (type) {
      case GL_BYTE:
         opcode = X_GLrop_VertexAttrib4bvARB;
         true_immediate_count = 4;
         break;
      case GL_UNSIGNED_BYTE:
         opcode = X_GLrop_VertexAttrib4ubvARB;
         true_immediate_count = 4;
         break;
      case GL_SHORT:
         opcode = short_ops[size];
         break;
      case GL_UNSIGNED_SHORT:
         opcode = X_GLrop_VertexAttrib4usvARB;
         true_immediate_count = 4;
         break;
      case GL_INT:
         opcode = X_GLrop_VertexAttrib4ivARB;
         true_immediate_count = 4;
         break;
      case GL_UNSIGNED_INT:
         opcode = X_GLrop_VertexAttrib4uivARB;
         true_immediate_count = 4;
         break;
      case GL_FLOAT:
         opcode = float_ops[size];
         break;
      case GL_DOUBLE:
         opcode = double_ops[size];
         break;
      default:
         __glXSetError(gc, GL_INVALID_ENUM);
         return;
      }
   }

   a = get_array_entry(arrays, GL_VERTEX_ATTRIB_ARRAY_POINTER, index);
   if (a == NULL) {
      __glXSetError(gc, GL_INVALID_OPERATION);
      return;
   }

   COMMON_ARRAY_DATA_INIT(a, pointer, type, stride, size, normalized, 8,
                          opcode);

   true_immediate_size = __glXTypeSize(type) * true_immediate_count;
   a->header[0] = __GLX_PAD(8 + true_immediate_size);

   if (a->enabled) {
      arrays->array_info_cache_valid = GL_FALSE;
   }
}


/**
 * I don't have 100% confidence that this is correct.  The different rules
 * about whether or not generic vertex attributes alias "classic" vertex
 * attributes (i.e., attrib1 ?= primary color) between ARB_vertex_program,
 * ARB_vertex_shader, and NV_vertex_program are a bit confusing.  My
 * feeling is that the client-side doesn't have to worry about it.  The
 * client just sends all the data to the server and lets the server deal
 * with it.
 */
void
__indirect_glVertexAttribPointerNV(GLuint index, GLint size,
                                   GLenum type, GLsizei stride,
                                   const GLvoid * pointer)
{
   struct glx_context *gc = __glXGetCurrentContext();
   GLboolean normalized = GL_FALSE;


   switch (type) {
   case GL_UNSIGNED_BYTE:
      if (size != 4) {
         __glXSetError(gc, GL_INVALID_VALUE);
         return;
      }
      normalized = GL_TRUE;
      /* fallthrough */
   case GL_SHORT:
   case GL_FLOAT:
   case GL_DOUBLE:
      __indirect_glVertexAttribPointer(index, size, type,
                                          normalized, stride, pointer);
      return;
   default:
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }
}


void
__indirect_glClientActiveTexture(GLenum texture)
{
   struct glx_context *const gc = __glXGetCurrentContext();
   __GLXattribute *const state =
      (__GLXattribute *) (gc->client_state_private);
   struct array_state_vector *const arrays = state->array_state;
   const GLint unit = (GLint) texture - GL_TEXTURE0;


   if ((unit < 0) || (unit >= arrays->num_texture_units)) {
      __glXSetError(gc, GL_INVALID_ENUM);
      return;
   }

   arrays->active_texture_unit = unit;
}


/**
 * Modify the enable state for the selected array
 */
GLboolean
__glXSetArrayEnable(__GLXattribute * state, GLenum key, unsigned index,
                    GLboolean enable)
{
   struct array_state_vector *arrays = state->array_state;
   struct array_state *a;


   /* Texture coordinate arrays have an implict index set when the
    * application calls glClientActiveTexture.
    */
   if (key == GL_TEXTURE_COORD_ARRAY) {
      index = arrays->active_texture_unit;
   }

   a = get_array_entry(arrays, key, index);

   if ((a != NULL) && (a->enabled != enable)) {
      a->enabled = enable;
      arrays->array_info_cache_valid = GL_FALSE;
   }

   return (a != NULL);
}


void
__glXArrayDisableAll(__GLXattribute * state)
{
   struct array_state_vector *arrays = state->array_state;
   unsigned i;


   for (i = 0; i < arrays->num_arrays; i++) {
      arrays->arrays[i].enabled = GL_FALSE;
   }

   arrays->array_info_cache_valid = GL_FALSE;
}


/**
 */
GLboolean
__glXGetArrayEnable(const __GLXattribute * const state,
                    GLenum key, unsigned index, GLintptr * dest)
{
   const struct array_state_vector *arrays = state->array_state;
   const struct array_state *a =
      get_array_entry((struct array_state_vector *) arrays,
                      key, index);

   if (a != NULL) {
      *dest = (GLintptr) a->enabled;
   }

   return (a != NULL);
}


/**
 */
GLboolean
__glXGetArrayType(const __GLXattribute * const state,
                  GLenum key, unsigned index, GLintptr * dest)
{
   const struct array_state_vector *arrays = state->array_state;
   const struct array_state *a =
      get_array_entry((struct array_state_vector *) arrays,
                      key, index);

   if (a != NULL) {
      *dest = (GLintptr) a->data_type;
   }

   return (a != NULL);
}


/**
 */
GLboolean
__glXGetArraySize(const __GLXattribute * const state,
                  GLenum key, unsigned index, GLintptr * dest)
{
   const struct array_state_vector *arrays = state->array_state;
   const struct array_state *a =
      get_array_entry((struct array_state_vector *) arrays,
                      key, index);

   if (a != NULL) {
      *dest = (GLintptr) a->count;
   }

   return (a != NULL);
}


/**
 */
GLboolean
__glXGetArrayStride(const __GLXattribute * const state,
                    GLenum key, unsigned index, GLintptr * dest)
{
   const struct array_state_vector *arrays = state->array_state;
   const struct array_state *a =
      get_array_entry((struct array_state_vector *) arrays,
                      key, index);

   if (a != NULL) {
      *dest = (GLintptr) a->user_stride;
   }

   return (a != NULL);
}


/**
 */
GLboolean
__glXGetArrayPointer(const __GLXattribute * const state,
                     GLenum key, unsigned index, void **dest)
{
   const struct array_state_vector *arrays = state->array_state;
   const struct array_state *a =
      get_array_entry((struct array_state_vector *) arrays,
                      key, index);


   if (a != NULL) {
      *dest = (void *) (a->data);
   }

   return (a != NULL);
}


/**
 */
GLboolean
__glXGetArrayNormalized(const __GLXattribute * const state,
                        GLenum key, unsigned index, GLintptr * dest)
{
   const struct array_state_vector *arrays = state->array_state;
   const struct array_state *a =
      get_array_entry((struct array_state_vector *) arrays,
                      key, index);


   if (a != NULL) {
      *dest = (GLintptr) a->normalized;
   }

   return (a != NULL);
}


/**
 */
GLuint
__glXGetActiveTextureUnit(const __GLXattribute * const state)
{
   return state->array_state->active_texture_unit;
}


void
__glXPushArrayState(__GLXattribute * state)
{
   struct array_state_vector *arrays = state->array_state;
   struct array_stack_state *stack =
      &arrays->stack[(arrays->stack_index * arrays->num_arrays)];
   unsigned i;

   /* XXX are we pushing _all_ the necessary fields? */
   for (i = 0; i < arrays->num_arrays; i++) {
      stack[i].data = arrays->arrays[i].data;
      stack[i].data_type = arrays->arrays[i].data_type;
      stack[i].user_stride = arrays->arrays[i].user_stride;
      stack[i].count = arrays->arrays[i].count;
      stack[i].key = arrays->arrays[i].key;
      stack[i].index = arrays->arrays[i].index;
      stack[i].enabled = arrays->arrays[i].enabled;
   }

   arrays->active_texture_unit_stack[arrays->stack_index] =
      arrays->active_texture_unit;

   arrays->stack_index++;
}


void
__glXPopArrayState(__GLXattribute * state)
{
   struct array_state_vector *arrays = state->array_state;
   struct array_stack_state *stack;
   unsigned i;


   arrays->stack_index--;
   stack = &arrays->stack[(arrays->stack_index * arrays->num_arrays)];

   for (i = 0; i < arrays->num_arrays; i++) {
      switch (stack[i].key) {
      case GL_NORMAL_ARRAY:
         __indirect_glNormalPointer(stack[i].data_type,
                                    stack[i].user_stride, stack[i].data);
         break;
      case GL_COLOR_ARRAY:
         __indirect_glColorPointer(stack[i].count,
                                   stack[i].data_type,
                                   stack[i].user_stride, stack[i].data);
         break;
      case GL_INDEX_ARRAY:
         __indirect_glIndexPointer(stack[i].data_type,
                                   stack[i].user_stride, stack[i].data);
         break;
      case GL_EDGE_FLAG_ARRAY:
         __indirect_glEdgeFlagPointer(stack[i].user_stride, stack[i].data);
         break;
      case GL_TEXTURE_COORD_ARRAY:
         arrays->active_texture_unit = stack[i].index;
         __indirect_glTexCoordPointer(stack[i].count,
                                      stack[i].data_type,
                                      stack[i].user_stride, stack[i].data);
         break;
      case GL_SECONDARY_COLOR_ARRAY:
         __indirect_glSecondaryColorPointer(stack[i].count,
                                               stack[i].data_type,
                                               stack[i].user_stride,
                                               stack[i].data);
         break;
      case GL_FOG_COORDINATE_ARRAY:
         __indirect_glFogCoordPointer(stack[i].data_type,
                                         stack[i].user_stride, stack[i].data);
         break;

      }

      __glXSetArrayEnable(state, stack[i].key, stack[i].index,
                          stack[i].enabled);
   }

   arrays->active_texture_unit =
      arrays->active_texture_unit_stack[arrays->stack_index];
}
