home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / mesa-3_1.lha / src / varray.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-07  |  32.3 KB  |  1,182 lines

  1. /* $Id: varray.c,v 1.13.2.3 1999/12/01 12:18:47 keithw Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.1
  6.  * 
  7.  * Copyright (C) 1999  Brian Paul   All Rights Reserved.
  8.  * 
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  * 
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27. #ifdef PC_HEADER
  28. #include "all.h"
  29. #else
  30. #ifndef XFree86Server
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <string.h>
  34. #else
  35. #include "GL/xf86glx.h"
  36. #endif
  37. #include "context.h"
  38. #include "api.h"
  39. #include "cva.h"
  40. #include "enable.h"
  41. #include "enums.h"
  42. #include "dlist.h"
  43. #include "light.h"
  44. #include "macros.h"
  45. #include "mmath.h"
  46. #include "pipeline.h"
  47. #include "texstate.h"
  48. #include "translate.h"
  49. #include "types.h"
  50. #include "varray.h"
  51. #include "vb.h"
  52. #include "vbfill.h"
  53. #include "vbrender.h"
  54. #include "vbindirect.h"
  55. #include "vbxform.h"
  56. #include "xform.h"
  57. #ifdef XFree86Server
  58. #include "GL/xf86glx.h"
  59. #endif
  60. #endif
  61.  
  62. #if defined(GLX_DIRECT_RENDERING) && !defined(XFree86Server) && !defined(GLX_USE_DLOPEN)
  63. #define NEED_MESA_FUNCS_WRAPPED
  64. #include "mesa_api.h"
  65. #endif
  66.  
  67.  
  68. void GLAPIENTRY glVertexPointer(CTX_ARG GLint size, GLenum type, GLsizei stride,
  69.                                  const GLvoid *ptr )
  70. {
  71.    GLcontext *ctx;
  72.    GET_CONTEXT;
  73.    CHECK_CONTEXT;
  74.    ctx = CC;
  75.    
  76.    if (size<2 || size>4) {
  77.       gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(size)" );
  78.       return;
  79.    }
  80.    if (stride<0) {
  81.       gl_error( ctx, GL_INVALID_VALUE, "glVertexPointer(stride)" );
  82.       return;
  83.    }
  84.    
  85.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  86.       fprintf(stderr, "glVertexPointer( sz %d type %s stride %d )\n", size, 
  87.           gl_lookup_enum_by_nr( type ),
  88.           stride);
  89.  
  90.    ctx->Array.Vertex.StrideB = stride;
  91.    if (!stride) {
  92.       switch (type) {
  93.       case GL_SHORT:
  94.          ctx->Array.Vertex.StrideB =  size*sizeof(GLshort);
  95.          break;
  96.       case GL_INT:
  97.          ctx->Array.Vertex.StrideB =  size*sizeof(GLint);
  98.          break;
  99.       case GL_FLOAT:
  100.          ctx->Array.Vertex.StrideB =  size*sizeof(GLfloat);
  101.          break;
  102.       case GL_DOUBLE:
  103.          ctx->Array.Vertex.StrideB =  size*sizeof(GLdouble);
  104.          break;
  105.       default:
  106.          gl_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
  107.          return;
  108.       }
  109.    }
  110.    ctx->Array.Vertex.Size = size;
  111.    ctx->Array.Vertex.Type = type;
  112.    ctx->Array.Vertex.Stride = stride;
  113.    ctx->Array.Vertex.Ptr = (void *) ptr;
  114.    ctx->Array.VertexFunc = gl_trans_4f_tab[size][TYPE_IDX(type)];
  115.    ctx->Array.VertexEltFunc = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
  116.    ctx->Array.NewArrayState |= VERT_OBJ_ANY;
  117.    ctx->NewState |= NEW_CLIENT_STATE;
  118. }
  119.  
  120.  
  121.  
  122.  
  123. void GLAPIENTRY glNormalPointer(CTX_ARG GLenum type, GLsizei stride,
  124.                                  const GLvoid *ptr )
  125. {
  126.    GLcontext *ctx;
  127.    GET_CONTEXT;
  128.    CHECK_CONTEXT;
  129.    ctx = CC;
  130.    
  131.    if (stride<0) {
  132.       gl_error( ctx, GL_INVALID_VALUE, "glNormalPointer(stride)" );
  133.       return;
  134.    }
  135.  
  136.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  137.       fprintf(stderr, "glNormalPointer( type %s stride %d )\n", 
  138.           gl_lookup_enum_by_nr( type ),
  139.           stride);
  140.  
  141.    ctx->Array.Normal.StrideB = stride;
  142.    if (!stride) {
  143.       switch (type) {
  144.       case GL_BYTE:
  145.          ctx->Array.Normal.StrideB =  3*sizeof(GLbyte);
  146.          break;
  147.       case GL_SHORT:
  148.          ctx->Array.Normal.StrideB =  3*sizeof(GLshort);
  149.          break;
  150.       case GL_INT:
  151.          ctx->Array.Normal.StrideB =  3*sizeof(GLint);
  152.          break;
  153.       case GL_FLOAT:
  154.          ctx->Array.Normal.StrideB =  3*sizeof(GLfloat);
  155.          break;
  156.       case GL_DOUBLE:
  157.          ctx->Array.Normal.StrideB =  3*sizeof(GLdouble);
  158.          break;
  159.       default:
  160.          gl_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
  161.          return;
  162.       }
  163.    }
  164.    ctx->Array.Normal.Type = type;
  165.    ctx->Array.Normal.Stride = stride;
  166.    ctx->Array.Normal.Ptr = (void *) ptr;
  167.    ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(type)];
  168.    ctx->Array.NormalEltFunc = gl_trans_elt_3f_tab[TYPE_IDX(type)];
  169.    ctx->Array.NewArrayState |= VERT_NORM;
  170.    ctx->NewState |= NEW_CLIENT_STATE;
  171. }
  172.  
  173.  
  174.  
  175. void GLAPIENTRY glColorPointer(CTX_ARG GLint size, GLenum type, GLsizei stride,
  176.                                 const GLvoid *ptr )
  177. {
  178.    GLcontext *ctx;
  179.    GET_CONTEXT;
  180.    CHECK_CONTEXT;
  181.    ctx = CC;
  182.    if (size<3 || size>4) {
  183.       gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(size)" );
  184.       return;
  185.    }
  186.    if (stride<0) {
  187.       gl_error( ctx, GL_INVALID_VALUE, "glColorPointer(stride)" );
  188.       return;
  189.    }
  190.  
  191.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  192.       fprintf(stderr, "glColorPointer( sz %d type %s stride %d )\n", size, 
  193.       gl_lookup_enum_by_nr( type ),
  194.       stride);
  195.  
  196.    ctx->Array.Color.StrideB = stride;
  197.    if (!stride) {
  198.       switch (type) {
  199.       case GL_BYTE:
  200.          ctx->Array.Color.StrideB =  size*sizeof(GLbyte);
  201.          break;
  202.       case GL_UNSIGNED_BYTE:
  203.          ctx->Array.Color.StrideB =  size*sizeof(GLubyte);
  204.          break;
  205.       case GL_SHORT:
  206.          ctx->Array.Color.StrideB =  size*sizeof(GLshort);
  207.          break;
  208.       case GL_UNSIGNED_SHORT:
  209.          ctx->Array.Color.StrideB =  size*sizeof(GLushort);
  210.          break;
  211.       case GL_INT:
  212.          ctx->Array.Color.StrideB =  size*sizeof(GLint);
  213.          break;
  214.       case GL_UNSIGNED_INT:
  215.          ctx->Array.Color.StrideB =  size*sizeof(GLuint);
  216.          break;
  217.       case GL_FLOAT:
  218.          ctx->Array.Color.StrideB =  size*sizeof(GLfloat);
  219.          break;
  220.       case GL_DOUBLE:
  221.          ctx->Array.Color.StrideB =  size*sizeof(GLdouble);
  222.          break;
  223.       default:
  224.          gl_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
  225.          return;
  226.       }
  227.    }
  228.    ctx->Array.Color.Size = size;
  229.    ctx->Array.Color.Type = type;
  230.    ctx->Array.Color.Stride = stride;
  231.    ctx->Array.Color.Ptr = (void *) ptr;
  232.    ctx->Array.ColorFunc = gl_trans_4ub_tab[size][TYPE_IDX(type)];
  233.    ctx->Array.ColorEltFunc = gl_trans_elt_4ub_tab[size][TYPE_IDX(type)];
  234.    ctx->Array.NewArrayState |= VERT_RGBA;
  235.    ctx->NewState |= NEW_CLIENT_STATE;
  236. }
  237.  
  238.  
  239.  
  240. void GLAPIENTRY glIndexPointer(CTX_ARG GLenum type, GLsizei stride,
  241.                                 const GLvoid *ptr )
  242. {
  243.    GLcontext *ctx;
  244.    GET_CONTEXT;
  245.    CHECK_CONTEXT;
  246.    ctx = CC;
  247.    
  248.    if (stride<0) {
  249.       gl_error( ctx, GL_INVALID_VALUE, "glIndexPointer(stride)" );
  250.       return;
  251.    }
  252.  
  253.    ctx->Array.Index.StrideB = stride;
  254.    if (!stride) {
  255.       switch (type) {
  256.       case GL_UNSIGNED_BYTE:
  257.          ctx->Array.Index.StrideB =  sizeof(GLubyte);
  258.          break;
  259.       case GL_SHORT:
  260.          ctx->Array.Index.StrideB =  sizeof(GLshort);
  261.          break;
  262.       case GL_INT:
  263.          ctx->Array.Index.StrideB =  sizeof(GLint);
  264.          break;
  265.       case GL_FLOAT:
  266.          ctx->Array.Index.StrideB =  sizeof(GLfloat);
  267.          break;
  268.       case GL_DOUBLE:
  269.          ctx->Array.Index.StrideB =  sizeof(GLdouble);
  270.          break;
  271.       default:
  272.          gl_error( ctx, GL_INVALID_ENUM, "glIndexPointer(type)" );
  273.          return;
  274.       }
  275.    }
  276.    ctx->Array.Index.Type = type;
  277.    ctx->Array.Index.Stride = stride;
  278.    ctx->Array.Index.Ptr = (void *) ptr;
  279.    ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
  280.    ctx->Array.IndexEltFunc = gl_trans_elt_1ui_tab[TYPE_IDX(type)];
  281.    ctx->Array.NewArrayState |= VERT_INDEX;
  282.    ctx->NewState |= NEW_CLIENT_STATE;
  283. }
  284.  
  285.  
  286.  
  287. void GLAPIENTRY glTexCoordPointer(CTX_ARG GLint size, GLenum type,
  288.                                    GLsizei stride, const GLvoid *ptr )
  289. {
  290.    GLuint texUnit;
  291.    
  292.    GLcontext *ctx;
  293.    GET_CONTEXT;
  294.    CHECK_CONTEXT;
  295.    ctx = CC;
  296.    
  297.    texUnit = ctx->Array.ActiveTexture;
  298.  
  299.    if (size<1 || size>4) {
  300.       gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(size)" );
  301.       return;
  302.    }
  303.    if (stride<0) {
  304.       gl_error( ctx, GL_INVALID_VALUE, "glTexCoordPointer(stride)" );
  305.       return;
  306.    }
  307.  
  308.    if (MESA_VERBOSE&(VERBOSE_VARRAY|VERBOSE_API))
  309.       fprintf(stderr, "glTexCoordPointer( unit %u sz %d type %s stride %d )\n", 
  310.       texUnit,
  311.       size, 
  312.       gl_lookup_enum_by_nr( type ),
  313.       stride);
  314.  
  315.    ctx->Array.TexCoord[texUnit].StrideB = stride;
  316.    if (!stride) {
  317.       switch (type) {
  318.       case GL_SHORT:
  319.          ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLshort);
  320.          break;
  321.       case GL_INT:
  322.          ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLint);
  323.          break;
  324.       case GL_FLOAT:
  325.          ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLfloat);
  326.          break;
  327.       case GL_DOUBLE:
  328.          ctx->Array.TexCoord[texUnit].StrideB =  size*sizeof(GLdouble);
  329.          break;
  330.       default:
  331.          gl_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
  332.          return;
  333.       }
  334.    }
  335.    ctx->Array.TexCoord[texUnit].Size = size;
  336.    ctx->Array.TexCoord[texUnit].Type = type;
  337.    ctx->Array.TexCoord[texUnit].Stride = stride;
  338.    ctx->Array.TexCoord[texUnit].Ptr = (void *) ptr;
  339.  
  340.    ctx->Array.TexCoordFunc[texUnit] = gl_trans_4f_tab[size][TYPE_IDX(type)];
  341.    ctx->Array.TexCoordEltFunc[texUnit] = gl_trans_elt_4f_tab[size][TYPE_IDX(type)];
  342.    ctx->Array.NewArrayState |= PIPE_TEX(texUnit);
  343.    ctx->NewState |= NEW_CLIENT_STATE;
  344. }
  345.  
  346.  
  347.  
  348.  
  349. void GLAPIENTRY glEdgeFlagPointer(CTX_ARG GLsizei stride, const void *vptr )
  350. {
  351.    const GLboolean *ptr = (GLboolean *)vptr;
  352.    
  353.    GLcontext *ctx;
  354.    GET_CONTEXT;
  355.    CHECK_CONTEXT;
  356.    ctx = CC;
  357.  
  358.    if (stride<0) {
  359.       gl_error( ctx, GL_INVALID_VALUE, "glEdgeFlagPointer(stride)" );
  360.       return;
  361.    }
  362.    ctx->Array.EdgeFlag.Stride = stride;
  363.    ctx->Array.EdgeFlag.StrideB = stride ? stride : sizeof(GLboolean);
  364.    ctx->Array.EdgeFlag.Ptr = (GLboolean *) ptr;
  365.    if (stride != sizeof(GLboolean)) {
  366.       ctx->Array.EdgeFlagFunc = gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
  367.    } else {
  368.       ctx->Array.EdgeFlagFunc = 0;
  369.    }
  370.    ctx->Array.EdgeFlagEltFunc = gl_trans_elt_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
  371.    ctx->Array.NewArrayState |= VERT_EDGE;
  372.    ctx->NewState |= NEW_CLIENT_STATE;
  373. }
  374.  
  375.  
  376. /* Called only from gl_DrawElements
  377.  */
  378. void gl_CVAEltPointer( GLcontext *ctx, GLenum type, const GLvoid *ptr )
  379. {
  380.    switch (type) {
  381.       case GL_UNSIGNED_BYTE:
  382.          ctx->CVA.Elt.StrideB = sizeof(GLubyte);
  383.          break;
  384.       case GL_UNSIGNED_SHORT:
  385.          ctx->CVA.Elt.StrideB = sizeof(GLushort);
  386.          break;
  387.       case GL_UNSIGNED_INT:
  388.          ctx->CVA.Elt.StrideB = sizeof(GLuint);
  389.          break;
  390.       default:
  391.          gl_error( ctx, GL_INVALID_ENUM, "glEltPointer(type)" );
  392.          return;
  393.    }
  394.    ctx->CVA.Elt.Type = type;
  395.    ctx->CVA.Elt.Stride = 0;
  396.    ctx->CVA.Elt.Ptr = (void *) ptr;
  397.    ctx->CVA.EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
  398.    ctx->Array.NewArrayState |= VERT_ELT; /* ??? */
  399. }
  400.  
  401.  
  402.  
  403. /* KW: Batch function to exec all the array elements in the input
  404.  *     buffer prior to transform.  Done only the first time a vertex
  405.  *     buffer is executed or compiled.
  406.  *
  407.  * KW: Have to do this after each glEnd if cva isn't active.  (also
  408.  *     have to do it after each full buffer)
  409.  */
  410. void gl_exec_array_elements( GLcontext *ctx, struct immediate *IM,
  411.                  GLuint start, 
  412.                  GLuint count)
  413. {
  414.    GLuint *flags = IM->Flag;
  415.    GLuint *elts = IM->Elt;
  416.    GLuint translate = ctx->Array.Flags;
  417.    GLuint i;
  418.  
  419.    if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  420.       fprintf(stderr, "exec_array_elements %d .. %d\n", start, count);
  421.    
  422.    if (translate & VERT_OBJ_ANY) 
  423.       (ctx->Array.VertexEltFunc)( IM->Obj, 
  424.                   &ctx->Array.Vertex, 
  425.                   flags, elts, (VERT_ELT|VERT_OBJ_ANY),
  426.                   start, count);
  427.    
  428.    if (translate & VERT_NORM) 
  429.       (ctx->Array.NormalEltFunc)( IM->Normal, 
  430.                   &ctx->Array.Normal, 
  431.                   flags, elts, (VERT_ELT|VERT_NORM),
  432.                   start, count);
  433.  
  434.    if (translate & VERT_EDGE) 
  435.       (ctx->Array.EdgeFlagEltFunc)( IM->EdgeFlag, 
  436.                     &ctx->Array.EdgeFlag, 
  437.                     flags, elts, (VERT_ELT|VERT_EDGE),
  438.                     start, count);
  439.    
  440.    if (translate & VERT_RGBA)
  441.       (ctx->Array.ColorEltFunc)( IM->Color, 
  442.                  &ctx->Array.Color, 
  443.                  flags, elts, (VERT_ELT|VERT_RGBA),
  444.                  start, count);
  445.  
  446.    if (translate & VERT_INDEX)
  447.       (ctx->Array.IndexEltFunc)( IM->Index, 
  448.                  &ctx->Array.Index, 
  449.                  flags, elts, (VERT_ELT|VERT_INDEX),
  450.                  start, count);
  451.  
  452.    if (translate & VERT_TEX0_ANY)
  453.       (ctx->Array.TexCoordEltFunc[0])( IM->TexCoord[0], 
  454.                        &ctx->Array.TexCoord[0], 
  455.                        flags, elts, (VERT_ELT|VERT_TEX0_ANY),
  456.                        start, count);
  457.  
  458.    if (translate & VERT_TEX1_ANY)
  459.       (ctx->Array.TexCoordEltFunc[1])( IM->TexCoord[1], 
  460.                        &ctx->Array.TexCoord[1], 
  461.                        flags, elts, (VERT_ELT|VERT_TEX1_ANY),
  462.                        start, count);
  463.  
  464.  
  465.    for (i = start ; i < count ; i++) 
  466.       if (flags[i] & VERT_ELT) 
  467.      flags[i] |= translate;
  468.  
  469. }
  470.  
  471.  
  472.  
  473. void gl_DrawArrays( GLcontext *ctx, GLenum mode, GLint start, GLsizei count )
  474. {
  475.    struct vertex_buffer *VB = ctx->VB;
  476.    GLint i;
  477.  
  478.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawArrays");
  479.  
  480.    if (count<0) {
  481.       gl_error( ctx, GL_INVALID_VALUE, "glDrawArrays(count)" );
  482.       return;
  483.    }
  484.  
  485.    if (!ctx->CompileFlag && ctx->Array.Vertex.Enabled)
  486.    {
  487.       GLint remaining = count;
  488.       GLint i;
  489.       struct gl_client_array *Normal;
  490.       struct gl_client_array *Color;
  491.       struct gl_client_array *Index;
  492.       struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS];
  493.       struct gl_client_array *EdgeFlag;
  494.       struct immediate *IM = VB->IM;
  495.       struct gl_pipeline *elt = &ctx->CVA.elt;
  496.       GLboolean relock;
  497.       GLuint fallback, required;
  498.  
  499.       if (ctx->NewState)
  500.      gl_update_state( ctx );    
  501.  
  502.       /* Just turn off cva on this path.  Could be useful for multipass
  503.        * rendering to keep it turned on.
  504.        */
  505.       relock = ctx->CompileCVAFlag;
  506.  
  507.       if (relock) {
  508.      ctx->CompileCVAFlag = 0;
  509.      elt->pipeline_valid = 0;
  510.       }
  511.  
  512.       if (!elt->pipeline_valid)
  513.      gl_build_immediate_pipeline( ctx );
  514.  
  515.       required = elt->inputs;
  516.       fallback = (elt->inputs & ~ctx->Array.Summary);
  517.  
  518.       /* The translate function doesn't do anything about size.  It
  519.        * just ensures that type and stride come out right.
  520.        */
  521.       IM->v.Obj.size = ctx->Array.Vertex.Size;
  522.       
  523.       if (required & VERT_RGBA) 
  524.       {
  525.      Color = &ctx->Array.Color;
  526.      if (fallback & VERT_RGBA) {
  527.         Color = &ctx->Fallback.Color;
  528.         ctx->Array.ColorFunc = 
  529.            gl_trans_4ub_tab[4][TYPE_IDX(GL_UNSIGNED_BYTE)];
  530.      }
  531.       }
  532.    
  533.       if (required & VERT_INDEX) 
  534.       {
  535.      Index = &ctx->Array.Index;
  536.      if (fallback & VERT_INDEX) {
  537.         Index = &ctx->Fallback.Index;
  538.         ctx->Array.IndexFunc = gl_trans_1ui_tab[TYPE_IDX(GL_UNSIGNED_INT)];
  539.      }
  540.       }
  541.  
  542.       for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) 
  543.       {
  544.      GLuint flag = VERT_TEX_ANY(i);
  545.  
  546.      if (required & flag) {
  547.         TexCoord[i] = &ctx->Array.TexCoord[i];
  548.  
  549.         if (fallback & flag) 
  550.         {
  551.            TexCoord[i] = &ctx->Fallback.TexCoord[i];
  552.            TexCoord[i]->Size = gl_texcoord_size( ctx->Current.Flag, i );
  553.  
  554.            ctx->Array.TexCoordFunc[i] = 
  555.           gl_trans_4f_tab[TexCoord[i]->Size][TYPE_IDX(GL_FLOAT)];
  556.         }
  557.      }
  558.       }
  559.  
  560.       if (ctx->Array.Flags != ctx->Array.Flag[0])
  561.       for (i = 0 ; i < VB_MAX ; i++) 
  562.         ctx->Array.Flag[i] = ctx->Array.Flags;
  563.  
  564.  
  565.       if (required & VERT_NORM) 
  566.       {
  567.      Normal = &ctx->Array.Normal;
  568.      if (fallback & VERT_NORM) {
  569.         Normal = &ctx->Fallback.Normal;
  570.         ctx->Array.NormalFunc = gl_trans_3f_tab[TYPE_IDX(GL_FLOAT)];
  571.      }
  572.       }
  573.  
  574.       if ( required & VERT_EDGE )
  575.       {
  576.      if (mode == GL_TRIANGLES || 
  577.          mode == GL_QUADS || 
  578.          mode == GL_POLYGON)
  579.      {
  580.         EdgeFlag = &ctx->Array.EdgeFlag;
  581.         if (fallback & VERT_EDGE) {
  582.            EdgeFlag = &ctx->Fallback.EdgeFlag;
  583.            ctx->Array.EdgeFlagFunc = 
  584.           gl_trans_1ub_tab[TYPE_IDX(GL_UNSIGNED_BYTE)];
  585.         }
  586.      }
  587.      else
  588.         required &= ~VERT_EDGE;
  589.       }
  590.  
  591.       VB->Primitive = IM->Primitive; 
  592.       VB->NextPrimitive = IM->NextPrimitive; 
  593.       VB->MaterialMask = IM->MaterialMask;
  594.       VB->Material = IM->Material;
  595.       VB->BoundsPtr = 0;      
  596.  
  597.       while (remaining > 0) {
  598.          GLint vbspace = VB_MAX - VB_START;
  599.      GLuint count, n;
  600.      
  601.      if (vbspace >= remaining) {
  602.         n = remaining;
  603.         VB->LastPrimitive = VB_START + n;
  604.      } else {
  605.         n = vbspace;
  606.         VB->LastPrimitive = VB_START;
  607.      }
  608.      
  609.      VB->CullMode = 0;
  610.      
  611.      ctx->Array.VertexFunc( IM->Obj + VB_START, 
  612.                 &ctx->Array.Vertex, start, n );
  613.      
  614.      if (required & VERT_NORM) {
  615.         ctx->Array.NormalFunc( IM->Normal + VB_START, 
  616.                    Normal, start, n );
  617.      }
  618.      
  619.      if (required & VERT_EDGE) {
  620.         ctx->Array.EdgeFlagFunc( IM->EdgeFlag + VB_START, 
  621.                      EdgeFlag, start, n );
  622.      }
  623.      
  624.      if (required & VERT_RGBA) {
  625.         ctx->Array.ColorFunc( IM->Color + VB_START, 
  626.                   Color, start, n );
  627.      }
  628.      
  629.      if (required & VERT_INDEX) {
  630.         ctx->Array.IndexFunc( IM->Index + VB_START, 
  631.                   Index, start, n );
  632.      }
  633.      
  634.      if (required & VERT_TEX0_ANY) {
  635.         IM->v.TexCoord[0].size = TexCoord[0]->Size;
  636.         ctx->Array.TexCoordFunc[0]( IM->TexCoord[0] + VB_START, 
  637.                     TexCoord[0], start, n );
  638.      }
  639.      
  640.      if (required & VERT_TEX1_ANY) {
  641.         IM->v.TexCoord[1].size = TexCoord[1]->Size;
  642.         ctx->Array.TexCoordFunc[1]( IM->TexCoord[1] + VB_START, 
  643.                     TexCoord[1], start, n );
  644.      }
  645.  
  646.      VB->ObjPtr = &IM->v.Obj;
  647.      VB->NormalPtr = &IM->v.Normal;
  648.      VB->ColorPtr = &IM->v.Color;
  649.      VB->Color[0] = VB->Color[1] = VB->ColorPtr;
  650.      VB->IndexPtr = &IM->v.Index;
  651.      VB->EdgeFlagPtr = &IM->v.EdgeFlag;
  652.      VB->TexCoordPtr[0] = &IM->v.TexCoord[0];
  653.      VB->TexCoordPtr[1] = &IM->v.TexCoord[1];
  654.  
  655.      VB->Flag = ctx->Array.Flag;
  656.      VB->OrFlag = ctx->Array.Flags;
  657.  
  658.      VB->Start = IM->Start = VB_START;
  659.      count = VB->Count = IM->Count = VB_START + n;
  660.  
  661. #define RESET_VEC(v, t, s, c) (v.start = t v.data[s], v.count = c)  
  662.  
  663.      RESET_VEC(IM->v.Obj, (GLfloat *), VB_START, count);
  664.      RESET_VEC(IM->v.Normal, (GLfloat *), VB_START, count);
  665.      RESET_VEC(IM->v.TexCoord[0], (GLfloat *), VB_START, count);
  666.      RESET_VEC(IM->v.TexCoord[1], (GLfloat *), VB_START, count);
  667.      RESET_VEC(IM->v.Index, &, VB_START, count);
  668.      RESET_VEC(IM->v.Elt, &, VB_START, count);
  669.      RESET_VEC(IM->v.EdgeFlag, &, VB_START, count);
  670.      RESET_VEC(IM->v.Color, (GLubyte *), VB_START, count);
  671.      RESET_VEC(VB->Clip, (GLfloat *), VB_START, count);
  672.      RESET_VEC(VB->Eye, (GLfloat *), VB_START, count);
  673.      RESET_VEC(VB->Win, (GLfloat *), VB_START, count);
  674.      RESET_VEC(VB->BColor, (GLubyte *), VB_START, count); 
  675.      RESET_VEC(VB->BIndex, &, VB_START, count);
  676.  
  677.      VB->NextPrimitive[VB->CopyStart] = VB->Count;
  678.      VB->Primitive[VB->CopyStart] = mode;
  679.      ctx->Array.Flag[count] |= VERT_END_VB;
  680.  
  681.          /* Transform and render.
  682.       */
  683.          gl_run_pipeline( VB );
  684.      gl_reset_vb( VB );
  685.  
  686.      ctx->Array.Flag[count] = ctx->Array.Flags;
  687.      ctx->Array.Flag[VB_START] = ctx->Array.Flags;
  688.  
  689.          start += n;
  690.          remaining -= n;
  691.       }
  692.  
  693.       gl_reset_input( ctx );
  694.  
  695.       if (relock) {
  696.      ctx->CompileCVAFlag = relock;
  697.      elt->pipeline_valid = 0;
  698.       }
  699.    }
  700.    else if (ctx->Array.Vertex.Enabled) 
  701.    {
  702.       /* The GL_COMPILE and GL_COMPILE_AND_EXECUTE cases.  These
  703.        * could be handled by the above code, but it gets a little
  704.        * complex.  The generated list is still of good quality
  705.        * this way.
  706.        */
  707.       gl_Begin( ctx, mode );
  708.       for (i=0;i<count;i++) {
  709.          gl_ArrayElement( ctx, start+i );
  710.       }
  711.       gl_End( ctx );
  712.    }
  713.    else
  714.    {
  715.       /* The degenerate case where vertices are not enabled - only
  716.        * need to process the very final array element, as all of the
  717.        * preceding ones would be overwritten anyway. 
  718.        */
  719.       gl_Begin( ctx, mode );
  720.       gl_ArrayElement( ctx, start+count );
  721.       gl_End( ctx );
  722.    }
  723. }
  724.  
  725.  
  726.  
  727. /* KW: Exactly fakes the effects of calling glArrayElement multiple times.
  728.  *     Compilation is handled via. the IM->maybe_transform_vb() callback.
  729.  */
  730. #if 1
  731. #define DRAW_ELT(FUNC, TYPE)                \
  732. static void FUNC( GLcontext *ctx, GLenum mode,        \
  733.           TYPE *indices, GLuint count )        \
  734. {                            \
  735.    GLuint i,j;                        \
  736.                             \
  737.    gl_Begin( ctx, mode );                \
  738.                             \
  739.    for (j = 0 ; j < count ; ) {                \
  740.       struct immediate *IM = ctx->input;        \
  741.       GLuint start = IM->Start;                \
  742.       GLuint nr = MIN2( VB_MAX, count - j + start );    \
  743.       GLuint sf = IM->Flag[start];            \
  744.       IM->FlushElt |= IM->ArrayEltFlush;        \
  745.                             \
  746.       for (i = start ; i < nr ; i++) {            \
  747.      IM->Elt[i] = (GLuint) *indices++;        \
  748.      IM->Flag[i] = VERT_ELT;            \
  749.       }                            \
  750.                             \
  751.       if (j == 0) IM->Flag[start] |= sf;        \
  752.                             \
  753.       IM->Count = nr;                    \
  754.       j += nr - start;                    \
  755.                             \
  756.       if (j == count) gl_End( ctx );            \
  757.       IM->maybe_transform_vb( IM );            \
  758.    }                            \
  759. }
  760. #else 
  761. #define DRAW_ELT(FUNC, TYPE)                \
  762. static void FUNC( GLcontext *ctx, GLenum mode,        \
  763.            TYPE *indices, GLuint count )    \
  764. {                            \
  765.   int i;                        \
  766.   glBegin(mode);                    \
  767.   for (i = 0 ; i < count ; i++)                \
  768.     glArrayElement( indices[i] );            \
  769.   glEnd();                        \
  770. }
  771. #endif
  772.     
  773.  
  774. DRAW_ELT( draw_elt_ubyte, GLubyte )
  775. DRAW_ELT( draw_elt_ushort, GLushort )
  776. DRAW_ELT( draw_elt_uint, GLuint )
  777.  
  778.  
  779. static GLuint natural_stride[0x10] = 
  780. {
  781.    sizeof(GLbyte),        /* 0 */
  782.    sizeof(GLubyte),        /* 1 */
  783.    sizeof(GLshort),        /* 2 */
  784.    sizeof(GLushort),        /* 3 */
  785.    sizeof(GLint),        /* 4 */
  786.    sizeof(GLuint),        /* 5 */
  787.    sizeof(GLfloat),        /* 6 */
  788.    2 * sizeof(GLbyte),        /* 7 */
  789.    3 * sizeof(GLbyte),        /* 8 */
  790.    4 * sizeof(GLbyte),        /* 9 */
  791.    sizeof(GLdouble),        /* a */
  792.    0,                /* b */
  793.    0,                /* c */
  794.    0,                /* d */
  795.    0,                /* e */
  796.    0                /* f */
  797. };
  798.  
  799. void GLAPIENTRY glDrawElements(CTX_ARG GLenum mode, GLsizei count,
  800.                                 GLenum type, const GLvoid *indices )
  801. {
  802.    GLcontext *ctx;
  803.    struct gl_cva *cva;
  804.       
  805.    GET_CONTEXT;
  806.    CHECK_CONTEXT;
  807.    ctx = CC;
  808.  
  809.    cva = &ctx->CVA;
  810.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDrawElements");
  811.  
  812.    if (count <= 0) {
  813.       if (count < 0)
  814.      gl_error( ctx, GL_INVALID_VALUE, "glDrawElements(count)" );
  815.       return;
  816.    }
  817.  
  818.    if (mode < 0 || mode > GL_POLYGON) {
  819.       gl_error( ctx, GL_INVALID_ENUM, "glDrawArrays(mode)" );
  820.       return;
  821.    }
  822.    
  823.    if (type != GL_UNSIGNED_INT && type != GL_UNSIGNED_BYTE && type != GL_UNSIGNED_SHORT)
  824.    {
  825.        gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
  826.        return;
  827.    }
  828.  
  829.    if (ctx->NewState)
  830.       gl_update_state(ctx);
  831.  
  832.    if (ctx->CompileCVAFlag) 
  833.    {
  834. #if defined(MESA_CVA_PROF)
  835.       force_init_prof(); 
  836. #endif
  837.  
  838.       /* Treat VERT_ELT like a special client array.
  839.        */
  840.       ctx->Array.NewArrayState |= VERT_ELT;
  841.       ctx->Array.Summary |= VERT_ELT;
  842.       ctx->Array.Flags |= VERT_ELT;
  843.  
  844.       cva->elt_mode = mode;
  845.       cva->elt_count = count;
  846.       cva->Elt.Type = type;
  847.       cva->Elt.Ptr = (void *) indices;
  848.       cva->Elt.StrideB = natural_stride[TYPE_IDX(type)];
  849.       cva->EltFunc = gl_trans_1ui_tab[TYPE_IDX(type)];
  850.  
  851.       if (!cva->pre.pipeline_valid) 
  852.      gl_build_precalc_pipeline( ctx );
  853.       else if (MESA_VERBOSE & VERBOSE_PIPELINE)
  854.      fprintf(stderr, ": dont rebuild\n");
  855.  
  856.       gl_cva_force_precalc( ctx );
  857.  
  858.       /* Did we 'precalculate' the render op?
  859.        */
  860.       if (ctx->CVA.pre.ops & PIPE_OP_RENDER) {
  861.      ctx->Array.NewArrayState |= VERT_ELT;
  862.      ctx->Array.Summary &= ~VERT_ELT;
  863.      ctx->Array.Flags &= ~VERT_ELT;
  864.      return;
  865.       } 
  866.  
  867.       if ( (MESA_VERBOSE&VERBOSE_VARRAY) )
  868.      printf("using immediate\n");
  869.    }
  870.  
  871.  
  872.    /* Otherwise, have to use the immediate path to render.
  873.     */
  874.    switch (type) {
  875.    case GL_UNSIGNED_BYTE:
  876.    {
  877.       GLubyte *ub_indices = (GLubyte *) indices;
  878.       if (ctx->Array.Summary & VERT_OBJ_ANY) {
  879.      draw_elt_ubyte( ctx, mode, ub_indices, count );
  880.       } else {
  881.      gl_ArrayElement( ctx, (GLuint) ub_indices[count-1] );
  882.       }
  883.    }
  884.    break;
  885.    case GL_UNSIGNED_SHORT:
  886.    {
  887.       GLushort *us_indices = (GLushort *) indices;
  888.       if (ctx->Array.Summary & VERT_OBJ_ANY) {
  889.      draw_elt_ushort( ctx, mode, us_indices, count );
  890.       } else {
  891.      gl_ArrayElement( ctx, (GLuint) us_indices[count-1] );
  892.       }
  893.    }
  894.    break;
  895.    case GL_UNSIGNED_INT:
  896.    {
  897.       GLuint *ui_indices = (GLuint *) indices;
  898.       if (ctx->Array.Summary & VERT_OBJ_ANY) {
  899.      draw_elt_uint( ctx, mode, ui_indices, count );
  900.       } else {
  901.      gl_ArrayElement( ctx, ui_indices[count-1] );
  902.       }
  903.    }
  904.    break;
  905.    default:
  906.       gl_error( ctx, GL_INVALID_ENUM, "glDrawElements(type)" );
  907.       break;
  908.    }
  909.  
  910.    if (ctx->CompileCVAFlag) {
  911.       ctx->Array.NewArrayState |= VERT_ELT;
  912.       ctx->Array.Summary &= ~VERT_ELT;
  913.    }
  914. }
  915.  
  916.  
  917.  
  918. void GLAPIENTRY glInterleavedArrays(CTX_ARG GLenum format, GLsizei stride,
  919.                                      const GLvoid *pointer )
  920. {
  921.    GLcontext *ctx;
  922.    GLboolean tflag, cflag, nflag;  /* enable/disable flags */
  923.    GLint tcomps, ccomps, vcomps;   /* components per texcoord, color, vertex */
  924.  
  925.    GLenum ctype;                   /* color type */
  926.    GLint coffset, noffset, voffset;/* color, normal, vertex offsets */
  927.    GLint defstride;                /* default stride */
  928.    GLint c, f;
  929.    GLint coordUnitSave;
  930.    
  931.    GET_CONTEXT;
  932.    CHECK_CONTEXT;
  933.    ctx = CC;
  934.  
  935.  
  936.    f = sizeof(GLfloat);
  937.    c = f * ((4*sizeof(GLubyte) + (f-1)) / f);
  938.  
  939.    if (stride<0) {
  940.       gl_error( ctx, GL_INVALID_VALUE, "glInterleavedArrays(stride)" );
  941.       return;
  942.    }
  943.  
  944.    switch (format) {
  945.       case GL_V2F:
  946.          tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  947.          tcomps = 0;  ccomps = 0;  vcomps = 2;
  948.          voffset = 0;
  949.          defstride = 2*f;
  950.          break;
  951.       case GL_V3F:
  952.          tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  953.          tcomps = 0;  ccomps = 0;  vcomps = 3;
  954.          voffset = 0;
  955.          defstride = 3*f;
  956.          break;
  957.       case GL_C4UB_V2F:
  958.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  959.          tcomps = 0;  ccomps = 4;  vcomps = 2;
  960.          ctype = GL_UNSIGNED_BYTE;
  961.          coffset = 0;
  962.          voffset = c;
  963.          defstride = c + 2*f;
  964.          break;
  965.       case GL_C4UB_V3F:
  966.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  967.          tcomps = 0;  ccomps = 4;  vcomps = 3;
  968.          ctype = GL_UNSIGNED_BYTE;
  969.          coffset = 0;
  970.          voffset = c;
  971.          defstride = c + 3*f;
  972.          break;
  973.       case GL_C3F_V3F:
  974.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  975.          tcomps = 0;  ccomps = 3;  vcomps = 3;
  976.          ctype = GL_FLOAT;
  977.          coffset = 0;
  978.          voffset = 3*f;
  979.          defstride = 6*f;
  980.          break;
  981.       case GL_N3F_V3F:
  982.          tflag = GL_FALSE;  cflag = GL_FALSE;  nflag = GL_TRUE;
  983.          tcomps = 0;  ccomps = 0;  vcomps = 3;
  984.          noffset = 0;
  985.          voffset = 3*f;
  986.          defstride = 6*f;
  987.          break;
  988.       case GL_C4F_N3F_V3F:
  989.          tflag = GL_FALSE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  990.          tcomps = 0;  ccomps = 4;  vcomps = 3;
  991.          ctype = GL_FLOAT;
  992.          coffset = 0;
  993.          noffset = 4*f;
  994.          voffset = 7*f;
  995.          defstride = 10*f;
  996.          break;
  997.       case GL_T2F_V3F:
  998.          tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  999.          tcomps = 2;  ccomps = 0;  vcomps = 3;
  1000.          voffset = 2*f;
  1001.          defstride = 5*f;
  1002.          break;
  1003.       case GL_T4F_V4F:
  1004.          tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_FALSE;
  1005.          tcomps = 4;  ccomps = 0;  vcomps = 4;
  1006.          voffset = 4*f;
  1007.          defstride = 8*f;
  1008.          break;
  1009.       case GL_T2F_C4UB_V3F:
  1010.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1011.          tcomps = 2;  ccomps = 4;  vcomps = 3;
  1012.          ctype = GL_UNSIGNED_BYTE;
  1013.          coffset = 2*f;
  1014.          voffset = c+2*f;
  1015.          defstride = c+5*f;
  1016.          break;
  1017.       case GL_T2F_C3F_V3F:
  1018.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_FALSE;
  1019.          tcomps = 2;  ccomps = 3;  vcomps = 3;
  1020.          ctype = GL_FLOAT;
  1021.          coffset = 2*f;
  1022.          voffset = 5*f;
  1023.          defstride = 8*f;
  1024.          break;
  1025.       case GL_T2F_N3F_V3F:
  1026.          tflag = GL_TRUE;  cflag = GL_FALSE;  nflag = GL_TRUE;
  1027.          tcomps = 2;  ccomps = 0;  vcomps = 3;
  1028.          noffset = 2*f;
  1029.          voffset = 5*f;
  1030.          defstride = 8*f;
  1031.          break;
  1032.       case GL_T2F_C4F_N3F_V3F:
  1033.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  1034.          tcomps = 2;  ccomps = 4;  vcomps = 3;
  1035.          ctype = GL_FLOAT;
  1036.          coffset = 2*f;
  1037.          noffset = 6*f;
  1038.          voffset = 9*f;
  1039.          defstride = 12*f;
  1040.          break;
  1041.       case GL_T4F_C4F_N3F_V4F:
  1042.          tflag = GL_TRUE;  cflag = GL_TRUE;  nflag = GL_TRUE;
  1043.          tcomps = 4;  ccomps = 4;  vcomps = 4;
  1044.          ctype = GL_FLOAT;
  1045.          coffset = 4*f;
  1046.          noffset = 8*f;
  1047.          voffset = 11*f;
  1048.          defstride = 15*f;
  1049.          break;
  1050.       default:
  1051.          gl_error( ctx, GL_INVALID_ENUM, "glInterleavedArrays(format)" );
  1052.          return;
  1053.    }
  1054.  
  1055.    if (stride==0) {
  1056.       stride = defstride;
  1057.    }
  1058.  
  1059.    gl_DisableClientState( ctx, GL_EDGE_FLAG_ARRAY );
  1060.    gl_DisableClientState( ctx, GL_INDEX_ARRAY );
  1061.  
  1062.    /* Texcoords */
  1063.    coordUnitSave = ctx->Array.ActiveTexture;
  1064.    if (tflag) {
  1065.       GLint i;
  1066.       GLint factor = ctx->Array.TexCoordInterleaveFactor;
  1067.       for (i = 0; i < factor; i++) {
  1068.          gl_ClientActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + i) );
  1069.          gl_EnableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
  1070.          glTexCoordPointer(CTX_PRM  tcomps, GL_FLOAT, stride,
  1071.                              (GLubyte *) pointer + i * coffset );
  1072.       }
  1073.       for (i = factor; i < ctx->Const.MaxTextureUnits; i++) {
  1074.          gl_ClientActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + i) );
  1075.          gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
  1076.       }
  1077.    }
  1078.    else {
  1079.       GLint i;
  1080.       for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
  1081.          gl_ClientActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + i) );
  1082.          gl_DisableClientState( ctx, GL_TEXTURE_COORD_ARRAY );
  1083.       }
  1084.    }
  1085.    /* Restore texture coordinate unit index */
  1086.    gl_ClientActiveTexture( ctx, (GLenum) (GL_TEXTURE0_ARB + coordUnitSave) );
  1087.  
  1088.  
  1089.    /* Color */
  1090.    if (cflag) {
  1091.       gl_EnableClientState( ctx, GL_COLOR_ARRAY );
  1092.       glColorPointer(CTX_PRM ccomps, ctype, stride,
  1093.                        (GLubyte*) pointer + coffset );
  1094.    }
  1095.    else {
  1096.       gl_DisableClientState( ctx, GL_COLOR_ARRAY );
  1097.    }
  1098.  
  1099.  
  1100.    /* Normals */
  1101.    if (nflag) {
  1102.       gl_EnableClientState( ctx, GL_NORMAL_ARRAY );
  1103.       glNormalPointer(CTX_PRM GL_FLOAT, stride,
  1104.                         (GLubyte*) pointer + noffset );
  1105.    }
  1106.    else {
  1107.       gl_DisableClientState( ctx, GL_NORMAL_ARRAY );
  1108.    }
  1109.  
  1110.    gl_EnableClientState( ctx, GL_VERTEX_ARRAY );
  1111.    glVertexPointer(CTX_PRM vcomps, GL_FLOAT, stride,
  1112.                      (GLubyte *) pointer + voffset );
  1113. }
  1114.  
  1115.  
  1116.  
  1117. void GLAPIENTRY glDrawRangeElements(CTX_ARG GLenum mode, GLuint start,
  1118.                                      GLuint end, GLsizei count,
  1119.                                      GLenum type, const GLvoid *indices )
  1120. {
  1121.    GLcontext *ctx;
  1122.    GET_CONTEXT;
  1123.    CHECK_CONTEXT;
  1124.    ctx = CC;
  1125.  
  1126.    if (end < start) {
  1127.       gl_error(ctx, GL_INVALID_VALUE, "glDrawRangeElements( end < start )");
  1128.       return;
  1129.    }
  1130.  
  1131.    if (!ctx->Array.LockCount && 2*count > (GLint) 3*(end-start)) {
  1132.       glLockArraysEXT(CTX_PRM start, end );
  1133.       glDrawElements(CTX_PRM mode, count, type, indices );
  1134.       glUnlockArraysEXT(CTX_VPRM );
  1135.    } else {
  1136.       glDrawElements(CTX_PRM mode, count, type, indices );
  1137.    }
  1138. }
  1139.  
  1140.  
  1141.  
  1142. void gl_update_client_state( GLcontext *ctx )
  1143. {
  1144.    static GLuint sz_flags[5] = { 0, 
  1145.                  0,
  1146.                  VERT_OBJ_2, 
  1147.                  VERT_OBJ_23, 
  1148.                  VERT_OBJ_234 };
  1149.  
  1150.    static GLuint tc_flags[5] = { 0, 
  1151.                  VERT_TEX0_1,
  1152.                  VERT_TEX0_12, 
  1153.                  VERT_TEX0_123, 
  1154.                  VERT_TEX0_1234 };
  1155.  
  1156.    ctx->Array.Flags = 0;
  1157.    ctx->Array.Summary = 0;
  1158.    ctx->input->ArrayIncr = 0;
  1159.    
  1160.    if (ctx->Array.Normal.Enabled)      ctx->Array.Flags |= VERT_NORM;
  1161.    if (ctx->Array.Color.Enabled)       ctx->Array.Flags |= VERT_RGBA;
  1162.    if (ctx->Array.Index.Enabled)       ctx->Array.Flags |= VERT_INDEX;
  1163.    if (ctx->Array.EdgeFlag.Enabled)    ctx->Array.Flags |= VERT_EDGE;
  1164.    if (ctx->Array.Vertex.Enabled) {
  1165.       ctx->Array.Flags |= sz_flags[ctx->Array.Vertex.Size];
  1166.       ctx->input->ArrayIncr = 1;
  1167.    }
  1168.    if (ctx->Array.TexCoord[0].Enabled) {
  1169.       ctx->Array.Flags |= tc_flags[ctx->Array.TexCoord[0].Size];
  1170.    }
  1171.    if (ctx->Array.TexCoord[1].Enabled) {
  1172.       ctx->Array.Flags |= (tc_flags[ctx->Array.TexCoord[1].Size] << NR_TEXSIZE_BITS);
  1173.    }
  1174.  
  1175.    /* Not really important any more:
  1176.     */
  1177.    ctx->Array.Summary = ctx->Array.Flags & VERT_DATA;
  1178.    ctx->input->ArrayAndFlags = ~ctx->Array.Flags;
  1179.    ctx->input->ArrayEltFlush = !(ctx->CompileCVAFlag);
  1180. }
  1181.  
  1182.