home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tnl / t_imm_eval.cpp < prev    next >
C/C++ Source or Header  |  2002-10-29  |  27KB  |  855 lines

  1. /* $Id: t_imm_eval.c,v 1.27 2002/10/29 20:29:02 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  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.  * Authors:
  27.  *    Keith Whitwell <keith@tungstengraphics.com>
  28.  *    Brian Paul - vertex program updates
  29.  */
  30.  
  31.  
  32. #include "glheader.h"
  33. #include "colormac.h"
  34. #include "context.h"
  35. #include "macros.h"
  36. #include "imports.h"
  37. #include "mmath.h"
  38. #include "mtypes.h"
  39. #include "math/m_eval.h"
  40.  
  41. #include "t_context.h"
  42. #include "t_imm_debug.h"
  43. #include "t_imm_eval.h"
  44. #include "t_imm_exec.h"
  45. #include "t_imm_fixup.h"
  46. #include "t_imm_alloc.h"
  47.  
  48.  
  49. static void eval_points1( GLfloat outcoord[][4],
  50.               GLfloat coord[][4],
  51.               const GLuint *flags,
  52.               GLfloat du, GLfloat u1 )
  53. {
  54.    GLuint i;
  55.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  56.       if (flags[i] & VERT_BITS_EVAL_ANY) {
  57.      outcoord[i][0] = coord[i][0];
  58.      outcoord[i][1] = coord[i][1];
  59.      if (flags[i] & VERT_BIT_EVAL_P1)
  60.         outcoord[i][0] = coord[i][0] * du + u1;
  61.       }
  62. }
  63.  
  64. static void eval_points2( GLfloat outcoord[][4],
  65.               GLfloat coord[][4],
  66.               const GLuint *flags,
  67.               GLfloat du, GLfloat u1,
  68.               GLfloat dv, GLfloat v1 )
  69. {
  70.    GLuint i;
  71.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++) {
  72.       if (flags[i] & VERT_BITS_EVAL_ANY) {
  73.      outcoord[i][0] = coord[i][0];
  74.      outcoord[i][1] = coord[i][1];
  75.      if (flags[i] & VERT_BIT_EVAL_P2) {
  76.         outcoord[i][0] = coord[i][0] * du + u1;
  77.         outcoord[i][1] = coord[i][1] * dv + v1;
  78.      }
  79.       }
  80.    }
  81. }
  82.  
  83. static const GLubyte dirty_flags[5] = {
  84.    0,                /* not possible */
  85.    VEC_DIRTY_0,
  86.    VEC_DIRTY_1,
  87.    VEC_DIRTY_2,
  88.    VEC_DIRTY_3
  89. };
  90.  
  91.  
  92. static void eval1_4f( GLvector4f *dest,
  93.               GLfloat coord[][4],
  94.               const GLuint *flags,
  95.               GLuint dimension,
  96.               const struct gl_1d_map *map )
  97. {
  98.    const GLfloat u1 = map->u1;
  99.    const GLfloat du = map->du;
  100.    GLfloat (*to)[4] = dest->data;
  101.    GLuint i;
  102.  
  103.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  104.       if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
  105.      GLfloat u = (coord[i][0] - u1) * du;
  106.      ASSIGN_4V(to[i], 0,0,0,1);
  107.      _math_horner_bezier_curve(map->Points, to[i], u,
  108.                    dimension, map->Order);
  109.       }
  110.  
  111.    dest->size = MAX2(dest->size, dimension);
  112.    dest->flags |= dirty_flags[dimension];
  113. }
  114.  
  115.  
  116. /* as above, but dest is a gl_client_array */
  117. static void eval1_4f_ca( struct gl_client_array *dest,
  118.              GLfloat coord[][4],
  119.              const GLuint *flags,
  120.              GLuint dimension,
  121.              const struct gl_1d_map *map )
  122. {
  123.    const GLfloat u1 = map->u1;
  124.    const GLfloat du = map->du;
  125.    GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
  126.    GLuint i;
  127.  
  128.    ASSERT(dest->Type == GL_FLOAT);
  129.    ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
  130.  
  131.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  132.       if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
  133.      GLfloat u = (coord[i][0] - u1) * du;
  134.      ASSIGN_4V(to[i], 0,0,0,1);
  135.      _math_horner_bezier_curve(map->Points, to[i], u,
  136.                    dimension, map->Order);
  137.       }
  138.  
  139.    dest->Size = MAX2(dest->Size, (GLint) dimension);
  140. }
  141.  
  142.  
  143. static void eval1_1ui( GLvector1ui *dest,
  144.                GLfloat coord[][4],
  145.                const GLuint *flags,
  146.                const struct gl_1d_map *map )
  147. {
  148.    const GLfloat u1 = map->u1;
  149.    const GLfloat du = map->du;
  150.    GLuint *to = dest->data;
  151.    GLuint i;
  152.  
  153.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  154.       if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
  155.      GLfloat u = (coord[i][0] - u1) * du;
  156.      GLfloat tmp;
  157.      _math_horner_bezier_curve(map->Points, &tmp, u, 1, map->Order);
  158.      to[i] = (GLuint) (GLint) tmp;
  159.       }
  160.  
  161. }
  162.  
  163. static void eval1_norm( GLvector4f *dest,
  164.             GLfloat coord[][4],
  165.             const GLuint *flags,
  166.             const struct gl_1d_map *map )
  167. {
  168.    const GLfloat u1 = map->u1;
  169.    const GLfloat du = map->du;
  170.    GLfloat (*to)[4] = dest->data;
  171.    GLuint i;
  172.  
  173.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  174.       if (flags[i] & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1)) {
  175.      GLfloat u = (coord[i][0] - u1) * du;
  176.      _math_horner_bezier_curve(map->Points, to[i], u, 3, map->Order);
  177.       }
  178. }
  179.  
  180.  
  181. static void eval2_obj_norm( GLvector4f *obj_ptr,
  182.                 GLvector4f *norm_ptr,
  183.                 GLfloat coord[][4],
  184.                 GLuint *flags,
  185.                 GLuint dimension,
  186.                 const struct gl_2d_map *map )
  187. {
  188.    const GLfloat u1 = map->u1;
  189.    const GLfloat du = map->du;
  190.    const GLfloat v1 = map->v1;
  191.    const GLfloat dv = map->dv;
  192.    GLfloat (*obj)[4] = obj_ptr->data;
  193.    GLfloat (*normal)[4] = norm_ptr->data;
  194.    GLuint i;
  195.  
  196.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  197.       if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
  198.      GLfloat u = (coord[i][0] - u1) * du;
  199.      GLfloat v = (coord[i][1] - v1) * dv;
  200.      GLfloat du[4], dv[4];
  201.  
  202.      ASSIGN_4V(obj[i], 0,0,0,1);
  203.      _math_de_casteljau_surf(map->Points, obj[i], du, dv, u, v, dimension,
  204.                  map->Uorder, map->Vorder);
  205.  
  206.      if (dimension == 4) {
  207.         du[0] = du[0]*obj[i][3] - du[3]*obj[i][0];
  208.         du[1] = du[1]*obj[i][3] - du[3]*obj[i][1];
  209.         du[2] = du[2]*obj[i][3] - du[3]*obj[i][2];
  210.      
  211.         dv[0] = dv[0]*obj[i][3] - dv[3]*obj[i][0];
  212.         dv[1] = dv[1]*obj[i][3] - dv[3]*obj[i][1];
  213.         dv[2] = dv[2]*obj[i][3] - dv[3]*obj[i][2];
  214.      }
  215.  
  216.      CROSS3(normal[i], du, dv);
  217.      NORMALIZE_3FV(normal[i]);
  218.       }
  219.  
  220.    obj_ptr->size = MAX2(obj_ptr->size, dimension);
  221.    obj_ptr->flags |= dirty_flags[dimension];
  222. }
  223.  
  224.  
  225. static void eval2_4f( GLvector4f *dest,
  226.               GLfloat coord[][4],
  227.               const GLuint *flags,
  228.               GLuint dimension,
  229.               const struct gl_2d_map *map )
  230. {
  231.    const GLfloat u1 = map->u1;
  232.    const GLfloat du = map->du;
  233.    const GLfloat v1 = map->v1;
  234.    const GLfloat dv = map->dv;
  235.    GLfloat (*to)[4] = dest->data;
  236.    GLuint i;
  237.  
  238.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  239.       if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
  240.      GLfloat u = (coord[i][0] - u1) * du;
  241.      GLfloat v = (coord[i][1] - v1) * dv;
  242.  
  243.      _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
  244.                   map->Uorder, map->Vorder);
  245.       }
  246.  
  247.    dest->size = MAX2(dest->size, dimension);
  248.    dest->flags |= dirty_flags[dimension];
  249. }
  250.  
  251.  
  252. /* as above, but dest is a gl_client_array */
  253. static void eval2_4f_ca( struct gl_client_array *dest,
  254.              GLfloat coord[][4],
  255.              const GLuint *flags,
  256.              GLuint dimension,
  257.              const struct gl_2d_map *map )
  258. {
  259.    const GLfloat u1 = map->u1;
  260.    const GLfloat du = map->du;
  261.    const GLfloat v1 = map->v1;
  262.    const GLfloat dv = map->dv;
  263.    GLfloat (*to)[4] = (GLfloat (*)[4])dest->Ptr;
  264.    GLuint i;
  265.  
  266.    ASSERT(dest->Type == GL_FLOAT);
  267.    ASSERT(dest->StrideB == 4 * sizeof(GLfloat));
  268.  
  269.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  270.       if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
  271.      GLfloat u = (coord[i][0] - u1) * du;
  272.      GLfloat v = (coord[i][1] - v1) * dv;
  273.      _math_horner_bezier_surf(map->Points, to[i], u, v, dimension,
  274.                   map->Uorder, map->Vorder);
  275.       }
  276.  
  277.    dest->Size = MAX2(dest->Size, (GLint) dimension);
  278. }
  279.  
  280.  
  281. static void eval2_norm( GLvector4f *dest,
  282.             GLfloat coord[][4],
  283.             GLuint *flags,
  284.             const struct gl_2d_map *map )
  285. {
  286.    const GLfloat u1 = map->u1;
  287.    const GLfloat du = map->du;
  288.    const GLfloat v1 = map->v1;
  289.    const GLfloat dv = map->dv;
  290.    GLfloat (*to)[4] = dest->data;
  291.    GLuint i;
  292.  
  293.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++) {
  294.       if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
  295.      GLfloat u = (coord[i][0] - u1) * du;
  296.      GLfloat v = (coord[i][1] - v1) * dv;
  297.      _math_horner_bezier_surf(map->Points, to[i], u, v, 3,
  298.                   map->Uorder, map->Vorder);
  299.       }
  300.    }
  301. }
  302.  
  303.  
  304. static void eval2_1ui( GLvector1ui *dest,
  305.                GLfloat coord[][4],
  306.                const GLuint *flags,
  307.                const struct gl_2d_map *map )
  308. {
  309.    const GLfloat u1 = map->u1;
  310.    const GLfloat du = map->du;
  311.    const GLfloat v1 = map->v1;
  312.    const GLfloat dv = map->dv;
  313.    GLuint *to = dest->data;
  314.    GLuint i;
  315.  
  316.    for (i = 0 ; !(flags[i] & VERT_BIT_END_VB) ; i++)
  317.       if (flags[i] & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2)) {
  318.      GLfloat u = (coord[i][0] - u1) * du;
  319.      GLfloat v = (coord[i][1] - v1) * dv;
  320.      GLfloat tmp;
  321.      _math_horner_bezier_surf(map->Points, &tmp, u, v, 1,
  322.                   map->Uorder, map->Vorder);
  323.  
  324.      to[i] = (GLuint) (GLint) tmp;
  325.       }
  326. }
  327.  
  328.  
  329. static void copy_4f( GLfloat to[][4], GLfloat from[][4], GLuint count )
  330. {
  331.    MEMCPY( to, from, count * sizeof(to[0]));
  332. }
  333.  
  334. static void copy_4f_stride( GLfloat to[][4], const GLfloat *from, 
  335.                 GLuint stride, GLuint count )
  336. {
  337.    if (stride == 4 * sizeof(GLfloat))
  338.       MEMCPY( to, from, count * sizeof(to[0]));
  339.    else {
  340.       GLuint i;
  341.       for (i = 0 ; i < count ; i++, STRIDE_F(from, stride))
  342.      COPY_4FV( to[i], from );
  343.    }
  344. }
  345.  
  346. static void copy_3f( GLfloat to[][4], GLfloat from[][4], GLuint count )
  347. {
  348.    GLuint i;
  349.    for (i = 0 ; i < count ; i++) {
  350.       COPY_3FV(to[i], from[i]);
  351.    }
  352. }
  353.  
  354.  
  355. static void copy_1ui( GLuint to[], const GLuint from[], GLuint count )
  356. {
  357.    MEMCPY( to, from, (count) * sizeof(to[0]));
  358. }
  359.  
  360.  
  361.  
  362. /* Translate eval enabled flags to VERT_* flags.
  363.  */
  364. static void update_eval( GLcontext *ctx )
  365. {
  366.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  367.    GLuint eval1 = 0, eval2 = 0;
  368.    GLuint i;
  369.  
  370.    if (ctx->Eval.Map1Index)
  371.       eval1 |= VERT_BIT_INDEX;
  372.  
  373.    if (ctx->Eval.Map2Index)
  374.       eval2 |= VERT_BIT_INDEX;
  375.  
  376.    if (ctx->Eval.Map1Color4)
  377.       eval1 |= VERT_BIT_COLOR0;
  378.  
  379.    if (ctx->Eval.Map2Color4)
  380.       eval2 |= VERT_BIT_COLOR0;
  381.  
  382.    if (ctx->Eval.Map1Normal)
  383.       eval1 |= VERT_BIT_NORMAL;
  384.  
  385.    if (ctx->Eval.Map2Normal)
  386.       eval2 |= VERT_BIT_NORMAL;
  387.  
  388.    if (ctx->Eval.Map1TextureCoord4 ||
  389.        ctx->Eval.Map1TextureCoord3 ||
  390.        ctx->Eval.Map1TextureCoord2 ||
  391.        ctx->Eval.Map1TextureCoord1)
  392.       eval1 |= VERT_BIT_TEX0;
  393.  
  394.    if (ctx->Eval.Map2TextureCoord4 ||
  395.        ctx->Eval.Map2TextureCoord3 ||
  396.        ctx->Eval.Map2TextureCoord2 ||
  397.        ctx->Eval.Map2TextureCoord1)
  398.       eval2 |= VERT_BIT_TEX0;
  399.  
  400.    if (ctx->Eval.Map1Vertex4)
  401.       eval1 |= VERT_BITS_OBJ_234;
  402.  
  403.    if (ctx->Eval.Map1Vertex3)
  404.       eval1 |= VERT_BITS_OBJ_23;
  405.  
  406.    if (ctx->Eval.Map2Vertex4) {
  407.       if (ctx->Eval.AutoNormal)
  408.      eval2 |= VERT_BITS_OBJ_234 | VERT_BIT_NORMAL;
  409.       else
  410.      eval2 |= VERT_BITS_OBJ_234;
  411.    }
  412.    else if (ctx->Eval.Map2Vertex3) {
  413.       if (ctx->Eval.AutoNormal)
  414.      eval2 |= VERT_BITS_OBJ_23 | VERT_BIT_NORMAL;
  415.       else
  416.      eval2 |= VERT_BITS_OBJ_23;
  417.    }
  418.  
  419.    tnl->eval.EvalMap1Flags = eval1;
  420.    tnl->eval.EvalMap2Flags = eval2;
  421.  
  422.    /* GL_NV_vertex_program evaluators */
  423.    eval1 = eval2 = 0;
  424.    for (i = 0; i < VERT_ATTRIB_MAX; i++) {
  425.       if (ctx->Eval.Map1Attrib[i])
  426.          eval1 |= (1 << i);
  427.       if (ctx->Eval.Map2Attrib[i])
  428.          eval2 |= (1 << i);
  429.    }
  430.    tnl->eval.EvalMap1AttribFlags = eval1;
  431.    tnl->eval.EvalMap2AttribFlags = eval2;
  432.  
  433.    tnl->eval.EvalNewState = 0;
  434. }
  435.  
  436.  
  437. /* This looks a lot like a pipeline stage, but for various reasons is
  438.  * better handled outside the pipeline, and considered the final stage
  439.  * of fixing up an immediate struct for execution.
  440.  *
  441.  * Really want to cache the results of this function in display lists,
  442.  * at least for EvalMesh commands.
  443.  */
  444. void _tnl_eval_immediate( GLcontext *ctx, struct immediate *IM )
  445. {
  446.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  447.    struct vertex_arrays *tmp = &tnl->imm_inputs;
  448.    struct immediate *store = tnl->eval.im;
  449.    GLuint *flags = IM->Flag + IM->CopyStart;
  450.    GLuint copycount;
  451.    GLuint orflag = IM->OrFlag;
  452.    GLuint any_eval1 = orflag & (VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1);
  453.    GLuint any_eval2 = orflag & (VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2);
  454.    GLuint req = 0;
  455.    GLuint purge_flags = 0;
  456.    GLfloat (*coord)[4] = IM->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
  457.  
  458.    if (IM->AndFlag & VERT_BITS_EVAL_ANY)
  459.       copycount = IM->Start - IM->CopyStart; /* just copy copied vertices */
  460.    else
  461.       copycount = IM->Count - IM->CopyStart; /* copy all vertices */
  462.  
  463.    if (!store)
  464.       store = tnl->eval.im = _tnl_alloc_immediate( ctx );
  465.  
  466.    if (tnl->eval.EvalNewState & _NEW_EVAL)
  467.       update_eval( ctx );
  468.  
  469.    if (any_eval1) {
  470.       req |= tnl->pipeline.inputs
  471.          & (tnl->eval.EvalMap1Flags | tnl->eval.EvalMap1AttribFlags);
  472.  
  473.       if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3 &&
  474.           !ctx->Eval.Map1Attrib[0])
  475.      purge_flags = (VERT_BIT_EVAL_P1|VERT_BIT_EVAL_C1);
  476.  
  477.       if (orflag & VERT_BIT_EVAL_P1) {
  478.      eval_points1( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart, 
  479.                coord, flags,
  480.                ctx->Eval.MapGrid1du,
  481.                ctx->Eval.MapGrid1u1);
  482.      
  483.      coord = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
  484.       }
  485.    }
  486.  
  487.    if (any_eval2) {
  488.       req |= tnl->pipeline.inputs
  489.          & (tnl->eval.EvalMap2Flags | tnl->eval.EvalMap2AttribFlags);
  490.  
  491.       if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3 &&
  492.           !ctx->Eval.Map2Attrib[0])
  493.      purge_flags |= (VERT_BIT_EVAL_P2|VERT_BIT_EVAL_C2);
  494.  
  495.       if (orflag & VERT_BIT_EVAL_P2) {
  496.      eval_points2( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart, 
  497.                coord, flags,
  498.                ctx->Eval.MapGrid2du,
  499.                ctx->Eval.MapGrid2u1,
  500.                ctx->Eval.MapGrid2dv,
  501.                ctx->Eval.MapGrid2v1 );
  502.  
  503.      coord = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
  504.       }
  505.    }
  506.  
  507.    /* Perform the evaluations on active data elements.
  508.     */
  509.    if (req & VERT_BIT_INDEX) {
  510.       GLuint generated = 0;
  511.  
  512.       if (copycount)
  513.      copy_1ui( store->Index + IM->CopyStart, tmp->Index.data, copycount );
  514.  
  515.       tmp->Index.data = store->Index + IM->CopyStart;
  516.       tmp->Index.start = store->Index + IM->CopyStart;
  517.  
  518.       if (ctx->Eval.Map1Index && any_eval1) {
  519.      eval1_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map1Index );
  520.      generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  521.       }
  522.  
  523.       if (ctx->Eval.Map2Index && any_eval2) {
  524.      eval2_1ui( &tmp->Index, coord, flags, &ctx->EvalMap.Map2Index );
  525.      generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  526.       }
  527.    }
  528.  
  529.    if (req & VERT_BIT_COLOR0) {
  530.       GLuint generated = 0;
  531.  
  532.       if (copycount) 
  533.      copy_4f_stride( store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart, 
  534.              (GLfloat *)tmp->Color.Ptr, 
  535.              tmp->Color.StrideB,
  536.              copycount );
  537.  
  538.       tmp->Color.Ptr = store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart;
  539.       tmp->Color.StrideB = 4 * sizeof(GLfloat);
  540.       tmp->Color.Flags = 0;
  541.       tnl->vb.importable_data &= ~VERT_BIT_COLOR0;
  542.  
  543.       if (ctx->VertexProgram.Enabled) {
  544.          tmp->Attribs[VERT_ATTRIB_COLOR0].data =
  545.             store->Attrib[VERT_ATTRIB_COLOR0] + IM->CopyStart;
  546.          tmp->Attribs[VERT_ATTRIB_COLOR0].start =
  547.             (GLfloat *) tmp->Attribs[VERT_ATTRIB_COLOR0].data;
  548.          tmp->Attribs[VERT_ATTRIB_COLOR0].size = 0;
  549.       }
  550.  
  551.       /* Vertex program maps have priority over conventional attribs */
  552.       if (any_eval1) {
  553.          if (ctx->VertexProgram.Enabled
  554.              && ctx->Eval.Map1Attrib[VERT_ATTRIB_COLOR0]) {
  555.             eval1_4f_ca( &tmp->Color, coord, flags, 4,
  556.                          &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_COLOR0] );
  557.             generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  558.          }
  559.          else if (ctx->Eval.Map1Color4) {
  560.             eval1_4f_ca( &tmp->Color, coord, flags, 4,
  561.                          &ctx->EvalMap.Map1Color4 );
  562.             generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  563.          }
  564.       }
  565.  
  566.       if (any_eval2) {
  567.          if (ctx->VertexProgram.Enabled
  568.              && ctx->Eval.Map2Attrib[VERT_ATTRIB_COLOR0]) {
  569.             eval2_4f_ca( &tmp->Color, coord, flags, 4,
  570.                          &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_COLOR0] );
  571.             generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  572.          }
  573.          else if (ctx->Eval.Map2Color4) {
  574.             eval2_4f_ca( &tmp->Color, coord, flags, 4,
  575.                          &ctx->EvalMap.Map2Color4 );
  576.             generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  577.          }
  578.       }
  579.    }
  580.  
  581.    if (req & VERT_BIT_TEX0) {
  582.       GLuint generated = 0;
  583.  
  584.       if (copycount)
  585.      copy_4f( store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart, 
  586.           tmp->TexCoord[0].data, copycount );
  587.       else
  588.      tmp->TexCoord[0].size = 0;
  589.  
  590.       tmp->TexCoord[0].data = store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart;
  591.       tmp->TexCoord[0].start = (GLfloat *)tmp->TexCoord[0].data;
  592.  
  593.       if (ctx->VertexProgram.Enabled) {
  594.          tmp->Attribs[VERT_ATTRIB_TEX0].data =
  595.             store->Attrib[VERT_ATTRIB_TEX0] + IM->CopyStart;
  596.          tmp->Attribs[VERT_ATTRIB_TEX0].start =
  597.             (GLfloat *) tmp->Attribs[VERT_ATTRIB_TEX0].data;
  598.          tmp->Attribs[VERT_ATTRIB_TEX0].size = 0;
  599.       }
  600.  
  601.       /* Vertex program maps have priority over conventional attribs */
  602.       if (any_eval1) {
  603.          if (ctx->VertexProgram.Enabled
  604.              && ctx->Eval.Map1Attrib[VERT_ATTRIB_TEX0]) {
  605.         eval1_4f( &tmp->TexCoord[0], coord, flags, 4,
  606.               &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_TEX0] );
  607.         generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  608.          }
  609.      else if (ctx->Eval.Map1TextureCoord4) {
  610.         eval1_4f( &tmp->TexCoord[0], coord, flags, 4,
  611.               &ctx->EvalMap.Map1Texture4 );
  612.         generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  613.      }
  614.      else if (ctx->Eval.Map1TextureCoord3) {
  615.         eval1_4f( &tmp->TexCoord[0], coord, flags, 3,
  616.               &ctx->EvalMap.Map1Texture3 );
  617.         generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  618.      }
  619.      else if (ctx->Eval.Map1TextureCoord2) {
  620.         eval1_4f( &tmp->TexCoord[0], coord, flags, 2,
  621.               &ctx->EvalMap.Map1Texture2 );
  622.         generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  623.      }
  624.      else if (ctx->Eval.Map1TextureCoord1) {
  625.         eval1_4f( &tmp->TexCoord[0], coord, flags, 1,
  626.               &ctx->EvalMap.Map1Texture1 );
  627.         generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  628.      }
  629.       }
  630.  
  631.       if (any_eval2) {
  632.          if (ctx->VertexProgram.Enabled
  633.              && ctx->Eval.Map2Attrib[VERT_ATTRIB_TEX0]) {
  634.         eval2_4f( &tmp->TexCoord[0], coord, flags, 4,
  635.               &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_TEX0] );
  636.         generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  637.          }
  638.      else if (ctx->Eval.Map2TextureCoord4) {
  639.         eval2_4f( &tmp->TexCoord[0], coord, flags, 4,
  640.               &ctx->EvalMap.Map2Texture4 );
  641.         generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  642.      }
  643.      else if (ctx->Eval.Map2TextureCoord3) {
  644.         eval2_4f( &tmp->TexCoord[0], coord, flags, 3,
  645.               &ctx->EvalMap.Map2Texture3 );
  646.         generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  647.      }
  648.      else if (ctx->Eval.Map2TextureCoord2) {
  649.         eval2_4f( &tmp->TexCoord[0], coord, flags, 2,
  650.               &ctx->EvalMap.Map2Texture2 );
  651.         generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  652.      }
  653.      else if (ctx->Eval.Map2TextureCoord1) {
  654.         eval2_4f( &tmp->TexCoord[0], coord, flags, 1,
  655.               &ctx->EvalMap.Map2Texture1 );
  656.         generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  657.      }
  658.       }
  659.    }
  660.  
  661.    if (req & VERT_BIT_NORMAL) {
  662.       GLuint generated = 0;
  663.  
  664.       if (copycount) {
  665.      copy_3f( store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart,
  666.                   tmp->Normal.data, copycount );
  667.       }
  668.  
  669.       tmp->Normal.data = store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart;
  670.       tmp->Normal.start = (GLfloat *)tmp->Normal.data;
  671.  
  672.       if (ctx->VertexProgram.Enabled) {
  673.          tmp->Attribs[VERT_ATTRIB_NORMAL].data =
  674.             store->Attrib[VERT_ATTRIB_NORMAL] + IM->CopyStart;
  675.          tmp->Attribs[VERT_ATTRIB_NORMAL].start =
  676.             (GLfloat *) tmp->Attribs[VERT_ATTRIB_NORMAL].data;
  677.          tmp->Attribs[VERT_ATTRIB_NORMAL].size = 0;
  678.       }
  679.  
  680.       if (any_eval1) {
  681.          if (ctx->VertexProgram.Enabled &&
  682.              ctx->Eval.Map1Attrib[VERT_ATTRIB_NORMAL]) {
  683.             eval1_norm( &tmp->Normal, coord, flags,
  684.                         &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_NORMAL] );
  685.             generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  686.          }
  687.          else if (ctx->Eval.Map1Normal) {
  688.             eval1_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map1Normal );
  689.             generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  690.          }
  691.       }
  692.  
  693.       if (any_eval2) {
  694.          if (ctx->VertexProgram.Enabled &&
  695.              ctx->Eval.Map2Attrib[VERT_ATTRIB_NORMAL]) {
  696.             eval2_norm( &tmp->Normal, coord, flags,
  697.                         &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_NORMAL] );
  698.             generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  699.          }
  700.          else if (ctx->Eval.Map2Normal) {
  701.             eval2_norm( &tmp->Normal, coord, flags, &ctx->EvalMap.Map2Normal );
  702.             generated |= VERT_BIT_EVAL_C2|VERT_BIT_EVAL_P2;
  703.          }
  704.       }
  705.    }
  706.  
  707.    /* In the AutoNormal case, the copy and assignment of tmp->NormalPtr
  708.     * are done above.
  709.     */
  710.    if (req & VERT_BIT_POS) {
  711.       if (copycount) {
  712.      /* This copy may already have occurred when eliminating
  713.       * glEvalPoint calls:
  714.       */
  715.      if (coord != store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart) {
  716.         copy_4f( store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart,
  717.                      tmp->Obj.data, copycount );
  718.          }
  719.       }
  720.       else {
  721.      tmp->Obj.size = 0;
  722.       }
  723.  
  724.       tmp->Obj.data = store->Attrib[VERT_ATTRIB_POS] + IM->CopyStart;
  725.       tmp->Obj.start = (GLfloat *) tmp->Obj.data;
  726.  
  727. #if 1
  728.       /*tmp->Attribs[0].count = count;*/
  729.       tmp->Attribs[0].data = store->Attrib[0] + IM->CopyStart;
  730.       tmp->Attribs[0].start = (GLfloat *) tmp->Attribs[0].data;
  731.       tmp->Attribs[0].size = 0;
  732. #endif
  733.  
  734.       /* Note: Normal data is already prepared above.
  735.        */
  736.  
  737.       if (any_eval1) {
  738.          if (ctx->VertexProgram.Enabled &&
  739.              ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]) {
  740.         eval1_4f( &tmp->Obj, coord, flags, 4,
  741.               &ctx->EvalMap.Map1Attrib[VERT_ATTRIB_POS] );
  742.          }
  743.      else if (ctx->Eval.Map1Vertex4) {
  744.         eval1_4f( &tmp->Obj, coord, flags, 4,
  745.               &ctx->EvalMap.Map1Vertex4 );
  746.      }
  747.      else if (ctx->Eval.Map1Vertex3) {
  748.         eval1_4f( &tmp->Obj, coord, flags, 3,
  749.               &ctx->EvalMap.Map1Vertex3 );
  750.      }
  751.       }
  752.  
  753.       if (any_eval2) {
  754.          if (ctx->VertexProgram.Enabled &&
  755.              ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]) {
  756.         if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
  757.            eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4,
  758.                    &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_POS] );
  759.         else
  760.            eval2_4f( &tmp->Obj, coord, flags, 4,
  761.              &ctx->EvalMap.Map2Attrib[VERT_ATTRIB_POS] );
  762.          }
  763.      else if (ctx->Eval.Map2Vertex4) {
  764.         if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
  765.            eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 4,
  766.                    &ctx->EvalMap.Map2Vertex4 );
  767.         else
  768.            eval2_4f( &tmp->Obj, coord, flags, 4,
  769.              &ctx->EvalMap.Map2Vertex4 );
  770.      }
  771.      else if (ctx->Eval.Map2Vertex3) {
  772.         if (ctx->Eval.AutoNormal && (req & VERT_BIT_NORMAL))
  773.            eval2_obj_norm( &tmp->Obj, &tmp->Normal, coord, flags, 3,
  774.                    &ctx->EvalMap.Map2Vertex3 );
  775.         else
  776.            eval2_4f( &tmp->Obj, coord, flags, 3,
  777.              &ctx->EvalMap.Map2Vertex3 );
  778.      }
  779.       }
  780.    }
  781.  
  782.  
  783.    if (ctx->VertexProgram.Enabled) {
  784.       /* We already evaluated position, normal, color and texture 0 above.
  785.        * now evaluate any other generic attributes.
  786.        */
  787.       const GLuint skipBits = (VERT_BIT_POS |
  788.                                VERT_BIT_NORMAL |
  789.                                VERT_BIT_COLOR0 |
  790.                                VERT_BIT_TEX0);
  791.       GLuint generated = 0;
  792.       GLuint attr;
  793.       for (attr = 0; attr < VERT_ATTRIB_MAX; attr++) {
  794.          if ((1 << attr) & req & ~skipBits) {
  795.             if (any_eval1 && ctx->Eval.Map1Attrib[attr]) {
  796.                /* evaluate 1-D vertex attrib map [i] */
  797.                eval1_4f( &tmp->Attribs[attr], coord, flags, 4,
  798.                          &ctx->EvalMap.Map1Attrib[attr] );
  799.                generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  800.             }
  801.             if (any_eval2 && ctx->Eval.Map2Attrib[attr]) {
  802.                /* evaluate 2-D vertex attrib map [i] */
  803.                eval2_4f( &tmp->Attribs[attr], coord, flags, 4,
  804.                          &ctx->EvalMap.Map2Attrib[attr] );
  805.                generated |= VERT_BIT_EVAL_C1|VERT_BIT_EVAL_P1;
  806.             }
  807.          }
  808.       }
  809.    }
  810.  
  811.    /* Calculate new IM->Elts, IM->Primitive, IM->PrimitiveLength for
  812.     * the case where vertex maps are not enabled for some received
  813.     * eval coordinates.  In this case those slots in the immediate
  814.     * must be ignored.
  815.     */
  816.    if (purge_flags) {
  817.       const GLuint vertex = VERT_BIT_POS|(VERT_BITS_EVAL_ANY & ~purge_flags);
  818.       GLuint last_new_prim = 0;
  819.       GLuint new_prim_length = 0;
  820.       GLuint next_old_prim = 0;
  821.       struct vertex_buffer *VB = &tnl->vb;
  822.       const GLuint count = VB->Count;
  823.       GLuint i, j;
  824.  
  825.       for (i = 0, j = 0 ; i < count ; i++) {
  826.      if (flags[i] & vertex) {
  827.         store->Elt[j++] = i;
  828.         new_prim_length++;
  829.      }
  830.      if (i == next_old_prim) {
  831.         next_old_prim += VB->PrimitiveLength[i];
  832.         VB->PrimitiveLength[last_new_prim] = new_prim_length;
  833.         VB->Primitive[j] = VB->Primitive[i];
  834.         last_new_prim = j;
  835.      }
  836.       }
  837.       
  838.       VB->Elts = store->Elt;
  839.       _tnl_get_purged_copy_verts( ctx, store );
  840.    }
  841.  
  842.    /* Produce new flags array:
  843.     */
  844.    {
  845.       const GLuint count = tnl->vb.Count + 1;
  846.       GLuint i;
  847.  
  848.       copy_1ui( store->Flag, flags, count );
  849.       tnl->vb.Flag = store->Flag;
  850.       for (i = 0 ; i < count ; i++)
  851.      store->Flag[i] |= req;
  852.       IM->Evaluated = req;    /* hack for copying. */
  853.    }
  854. }
  855.