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

  1. /* $Id: t_imm_fixup.c,v 1.39 2002/10/29 20:29:03 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.  
  27. /*
  28.  * Authors:
  29.  *    Keith Whitwell <keith@tungstengraphics.com>
  30.  */
  31.  
  32.  
  33. #include "glheader.h"
  34. #include "context.h"
  35. #include "enums.h"
  36. #include "dlist.h"
  37. #include "colormac.h"
  38. #include "light.h"
  39. #include "macros.h"
  40. #include "imports.h"
  41. #include "mmath.h"
  42. #include "state.h"
  43. #include "mtypes.h"
  44.  
  45. #include "math/m_matrix.h"
  46. #include "math/m_xform.h"
  47.  
  48. #include "t_context.h"
  49. #include "t_imm_alloc.h"
  50. #include "t_imm_debug.h"
  51. #include "t_imm_elt.h"
  52. #include "t_imm_fixup.h"
  53. #include "t_imm_exec.h"
  54. #include "t_pipeline.h"
  55.  
  56.  
  57. static const GLuint increment[GL_POLYGON+2] = { 1,2,1,1,3,1,1,4,2,1,1 };
  58. static const GLuint intro[GL_POLYGON+2]     = { 0,0,2,2,0,2,2,0,2,2,0 };
  59.  
  60. void
  61. _tnl_fixup_4f( GLfloat data[][4], GLuint flag[], GLuint start, GLuint match )
  62. {
  63.    GLuint i = start;
  64.  
  65.    for (;;) {
  66.       if ((flag[++i] & match) == 0) {
  67.      COPY_4FV(data[i], data[i-1]);
  68.      if (flag[i] & VERT_BIT_END_VB) break;
  69.       }
  70.    }
  71. }
  72.  
  73. void
  74. _tnl_fixup_3f( float data[][3], GLuint flag[], GLuint start, GLuint match )
  75. {
  76.    GLuint i = start;
  77.  
  78.  
  79.    for (;;) {
  80.       if ((flag[++i] & match) == 0) {
  81. /*       _mesa_debug(NULL, "_tnl_fixup_3f copy to %p values %f %f %f\n", */
  82. /*           data[i],  */
  83. /*           data[i-1][0], */
  84. /*           data[i-1][1], */
  85. /*           data[i-1][2]); */
  86.      COPY_3V(data[i], data[i-1]);
  87.      if (flag[i] & VERT_BIT_END_VB) break;
  88.       }
  89.    }
  90. }
  91.  
  92.  
  93. void
  94. _tnl_fixup_1ui( GLuint *data, GLuint flag[], GLuint start, GLuint match )
  95. {
  96.    GLuint i = start;
  97.  
  98.    for (;;) {
  99.       if ((flag[++i] & match) == 0) {
  100.      data[i] = data[i-1];
  101.      if (flag[i] & VERT_BIT_END_VB) break;
  102.       }
  103.    }
  104.    flag[i] |= match;
  105. }
  106.  
  107.  
  108. void
  109. _tnl_fixup_1f( GLfloat *data, GLuint flag[], GLuint start, GLuint match )
  110. {
  111.    GLuint i = start;
  112.  
  113.    for (;;) {
  114.       if ((flag[++i] & match) == 0) {
  115.      data[i] = data[i-1];
  116.      if (flag[i] & VERT_BIT_END_VB) break;
  117.       }
  118.    }
  119.    flag[i] |= match;
  120. }
  121.  
  122. void
  123. _tnl_fixup_1ub( GLubyte *data, GLuint flag[], GLuint start, GLuint match )
  124. {
  125.    GLuint i = start;
  126.  
  127.    for (;;) {
  128.       if ((flag[++i] & match) == 0) {
  129.      data[i] = data[i-1];
  130.      if (flag[i] & VERT_BIT_END_VB) break;
  131.       }
  132.    }
  133.    flag[i] |= match;
  134. }
  135.  
  136.  
  137. static void
  138. fixup_first_4f( GLfloat data[][4], GLuint flag[], GLuint match,
  139.         GLuint start, GLfloat *dflt )
  140. {
  141.    GLuint i = start-1;
  142.    match |= VERT_BIT_END_VB;
  143.  
  144.    while ((flag[++i]&match) == 0)
  145.       COPY_4FV(data[i], dflt);
  146. }
  147.  
  148. #if 0
  149. static void
  150. fixup_first_3f( GLfloat data[][3], GLuint flag[], GLuint match,
  151.         GLuint start, GLfloat *dflt )
  152. {
  153.    GLuint i = start-1;
  154.    match |= VERT_BIT_END_VB;
  155.  
  156. /*     _mesa_debug(NULL, "fixup_first_3f default: %f %f %f start: %d\n", */
  157. /*         dflt[0], dflt[1], dflt[2], start);  */
  158.  
  159.    while ((flag[++i]&match) == 0)
  160.       COPY_3FV(data[i], dflt);
  161. }
  162. #endif
  163.  
  164. static void
  165. fixup_first_1ui( GLuint data[], GLuint flag[], GLuint match,
  166.          GLuint start, GLuint dflt )
  167. {
  168.    GLuint i = start-1;
  169.    match |= VERT_BIT_END_VB;
  170.  
  171.    while ((flag[++i]&match) == 0)
  172.       data[i] = dflt;
  173. }
  174.  
  175. #if 00
  176. static void
  177. fixup_first_1f( GLfloat data[], GLuint flag[], GLuint match,
  178.         GLuint start, GLfloat dflt )
  179. {
  180.    GLuint i = start-1;
  181.    match |= VERT_BIT_END_VB;
  182.  
  183.    while ((flag[++i]&match) == 0)
  184.       data[i] = dflt;
  185. }
  186. #endif
  187.  
  188. static void
  189. fixup_first_1ub( GLubyte data[], GLuint flag[], GLuint match,
  190.          GLuint start, GLubyte dflt )
  191. {
  192.    GLuint i = start-1;
  193.    match |= VERT_BIT_END_VB;
  194.  
  195.    while ((flag[++i]&match) == 0)
  196.       data[i] = dflt;
  197. }
  198.  
  199. /*
  200.  * Copy vertex attributes from the ctx->Current group into the immediate
  201.  * struct at the given position according to copyMask.
  202.  */
  203. static void copy_from_current( GLcontext *ctx, struct immediate *IM, 
  204.                   GLuint pos, GLuint copyMask )
  205. {
  206.    GLuint attrib, attribBit;
  207.  
  208.    if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  209.       _tnl_print_vert_flags("copy from current", copyMask); 
  210.  
  211. #if 0
  212.    if (copyMask & VERT_BIT_NORMAL) {
  213.       COPY_4V(IM->Attrib[VERT_ATTRIB_NORMAL][pos],
  214.               ctx->Current.Attrib[VERT_ATTRIB_NORMAL]);
  215.    }
  216.  
  217.    if (copyMask & VERT_BIT_COLOR0) {
  218.       COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR0][pos],
  219.                 ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
  220.    }
  221.  
  222.    if (copyMask & VERT_BIT_COLOR1)
  223.       COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR1][pos],
  224.                 ctx->Current.Attrib[VERT_ATTRIB_COLOR1]);
  225.  
  226.    if (copyMask & VERT_BIT_FOG)
  227.       IM->Attrib[VERT_ATTRIB_FOG][pos][0] = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
  228.  
  229.    if (copyMask & VERT_BITS_TEX_ANY) {
  230.       GLuint i;
  231.       for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
  232.      if (copyMask & VERT_BIT_TEX(i))
  233.             COPY_4FV(IM->Attrib[VERT_ATTRIB_TEX0 + i][pos],
  234.                      ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i]);
  235.       }
  236.    }
  237. #else
  238.    for (attrib = 0, attribBit = 1; attrib < 16; attrib++, attribBit <<= 1) {
  239.       if (copyMask & attribBit) {
  240.          COPY_4FV( IM->Attrib[attrib][pos], ctx->Current.Attrib[attrib]);
  241.       }
  242.    }
  243. #endif
  244.  
  245.    if (copyMask & VERT_BIT_INDEX)
  246.       IM->Index[pos] = ctx->Current.Index;
  247.  
  248.    if (copyMask & VERT_BIT_EDGEFLAG)
  249.       IM->EdgeFlag[pos] = ctx->Current.EdgeFlag;
  250. }
  251.  
  252.  
  253. void _tnl_fixup_input( GLcontext *ctx, struct immediate *IM )
  254. {
  255.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  256.    GLuint start = IM->CopyStart;
  257.    GLuint andflag = IM->CopyAndFlag;
  258.    GLuint orflag = IM->CopyOrFlag | IM->Evaluated;
  259.    GLuint fixup;
  260.  
  261.    IM->CopyTexSize = IM->TexSize;
  262.  
  263. /*     _mesa_debug(ctx, "Fixup input, Start: %u Count: %u LastData: %u\n", */
  264. /*         IM->Start, IM->Count, IM->LastData); */
  265. /*     _tnl_print_vert_flags("Orflag", orflag); */
  266. /*     _tnl_print_vert_flags("Andflag", andflag); */
  267.  
  268.  
  269.    fixup = ~andflag & VERT_BITS_FIXUP;
  270.  
  271.    if (!ctx->CompileFlag)
  272.       fixup &= tnl->pipeline.inputs;
  273.  
  274.    if (!ctx->ExecuteFlag)
  275.       fixup &= orflag;
  276.  
  277.    if ((orflag & (VERT_BIT_POS|VERT_BITS_EVAL_ANY)) == 0)
  278.       fixup = 0;
  279.  
  280.    if (fixup) {
  281.       GLuint copy = fixup & ~IM->Flag[start];
  282.  
  283.  
  284.       /* Equivalent to a lazy copy-from-current when setting up the
  285.        * immediate.
  286.        */
  287.       if (ctx->ExecuteFlag && copy) 
  288.      copy_from_current( ctx, IM, start, copy );
  289.  
  290.       if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
  291.        _tnl_print_vert_flags("fixup", fixup); 
  292.  
  293.       /* XXX replace these conditionals with a loop over the 16
  294.        * vertex attributes.
  295.        */
  296.  
  297.       if (fixup & VERT_BITS_TEX_ANY) {
  298.      GLuint i;
  299.      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
  300.         if (fixup & VERT_BIT_TEX(i)) {
  301.            if (orflag & VERT_BIT_TEX(i))
  302.           _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag,
  303.                                  start, VERT_BIT_TEX(i) );
  304.            else
  305.           fixup_first_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag,
  306.                                   VERT_BIT_END_VB, start,
  307.                   IM->Attrib[VERT_ATTRIB_TEX0 + i][start]);
  308.         }
  309.      }
  310.       }
  311.    
  312.  
  313.       if (fixup & VERT_BIT_EDGEFLAG) {
  314.      if (orflag & VERT_BIT_EDGEFLAG)
  315.         _tnl_fixup_1ub( IM->EdgeFlag, IM->Flag, start, VERT_BIT_EDGEFLAG );
  316.      else
  317.         fixup_first_1ub( IM->EdgeFlag, IM->Flag, VERT_BIT_END_VB, start,
  318.                  IM->EdgeFlag[start] );
  319.       }
  320.  
  321.       if (fixup & VERT_BIT_INDEX) {
  322.      if (orflag & VERT_BIT_INDEX)
  323.         _tnl_fixup_1ui( IM->Index, IM->Flag, start, VERT_BIT_INDEX );
  324.      else
  325.         fixup_first_1ui( IM->Index, IM->Flag, VERT_BIT_END_VB, start, 
  326.                  IM->Index[start] );
  327.       }
  328.  
  329.       if (fixup & VERT_BIT_COLOR0) {
  330.      if (orflag & VERT_BIT_COLOR0)
  331.         _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag, start,
  332.                            VERT_BIT_COLOR0 );
  333.      /* No need for else case as the drivers understand stride
  334.       * zero here.  (TODO - propogate this)
  335.       */
  336.       }
  337.       
  338.       if (fixup & VERT_BIT_COLOR1) {
  339.      if (orflag & VERT_BIT_COLOR1)
  340.         _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, start, 
  341.                VERT_BIT_COLOR1 );
  342.      else
  343.         fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag, VERT_BIT_END_VB, start,
  344.                 IM->Attrib[VERT_ATTRIB_COLOR1][start] );
  345.       }
  346.       
  347.       if (fixup & VERT_BIT_FOG) {
  348.      if (orflag & VERT_BIT_FOG)
  349.         _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag,
  350.                            start, VERT_BIT_FOG );
  351.      else
  352.         fixup_first_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag, VERT_BIT_END_VB,
  353.                             start, IM->Attrib[VERT_ATTRIB_FOG][start] );
  354.       }
  355.  
  356.       if (fixup & VERT_BIT_NORMAL) {
  357.      if (orflag & VERT_BIT_NORMAL)
  358.         _tnl_fixup_4f( IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag, start,
  359.                            VERT_BIT_NORMAL );
  360.      else
  361.         fixup_first_4f( IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag,
  362.                             VERT_BIT_END_VB, start,
  363.                 IM->Attrib[VERT_ATTRIB_NORMAL][start] );
  364.       }
  365.    }
  366.       
  367.    /* Prune possible half-filled slot.
  368.     */
  369.    IM->Flag[IM->LastData+1] &= ~VERT_BIT_END_VB;
  370.    IM->Flag[IM->Count] |= VERT_BIT_END_VB;
  371.  
  372.  
  373.    /* Materials:
  374.     */
  375.    if (IM->MaterialOrMask & ~IM->MaterialAndMask) {
  376.       GLuint vulnerable = IM->MaterialOrMask;
  377.       GLuint i = IM->Start;
  378.  
  379.       do {
  380.      while (!(IM->Flag[i] & VERT_BIT_MATERIAL))
  381.         i++;
  382.  
  383.      vulnerable &= ~IM->MaterialMask[i];
  384.      _mesa_copy_material_pairs( IM->Material[i],
  385.                     ctx->Light.Material,
  386.                     vulnerable );
  387.  
  388.  
  389.     ++i;
  390.       } while (vulnerable);
  391.    }
  392. }
  393.  
  394.  
  395. static void
  396. copy_material( struct immediate *next,
  397.                struct immediate *prev,
  398.                GLuint dst, GLuint src )
  399. {
  400. /*     _mesa_debug(NULL, "%s\n", __FUNCTION__); */
  401.  
  402.    if (next->Material == 0) {
  403.       next->Material = (struct gl_material (*)[2])
  404.          MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
  405.       next->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
  406.    }
  407.  
  408.    next->MaterialMask[dst] = prev->MaterialOrMask;
  409.    MEMCPY(next->Material[dst], prev->Material[src],
  410.           2 * sizeof(struct gl_material));
  411. }
  412.  
  413.  
  414.  
  415. static GLboolean is_fan_like[GL_POLYGON+1] = {
  416.    GL_FALSE,
  417.    GL_FALSE,
  418.    GL_TRUE,            /* line loop */
  419.    GL_FALSE,
  420.    GL_FALSE,
  421.    GL_FALSE,
  422.    GL_TRUE,            /* tri fan */
  423.    GL_FALSE,
  424.    GL_FALSE,
  425.    GL_TRUE            /* polygon */
  426. };
  427.  
  428.  
  429. /* Copy the untransformed data from the shared vertices of a primitive
  430.  * that wraps over two immediate structs.  This is done prior to
  431.  * set_immediate so that prev and next may point to the same
  432.  * structure.  In general it's difficult to avoid this copy on long
  433.  * primitives.
  434.  *
  435.  * Have to be careful with the transitions between display list
  436.  * replay, compile and normal execute modes.
  437.  */
  438. void _tnl_copy_immediate_vertices( GLcontext *ctx, struct immediate *next )
  439. {
  440.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  441.    struct immediate *prev = tnl->ExecCopySource;
  442.    struct vertex_arrays *inputs = &tnl->imm_inputs;
  443.    GLuint count = tnl->ExecCopyCount;
  444.    GLuint *elts = tnl->ExecCopyElts;
  445.    GLuint offset = IMM_MAX_COPIED_VERTS - count;
  446.    GLuint i;
  447.  
  448.    if (!prev) {
  449.       ASSERT(tnl->ExecCopyCount == 0);
  450.       return;
  451.    }
  452.  
  453.    next->CopyStart = next->Start - count;
  454.  
  455.    if ((prev->CopyOrFlag & VERT_BITS_DATA) == VERT_BIT_ELT &&
  456.        ctx->Array.LockCount &&
  457.        ctx->Array.Vertex.Enabled)
  458.    {
  459.       /* Copy Elt values only
  460.        */
  461.       for (i = 0 ; i < count ; i++)
  462.       {
  463.      GLuint src = elts[i+offset];
  464.      GLuint dst = next->CopyStart+i;
  465.      next->Elt[dst] = prev->Elt[src];
  466.      next->Flag[dst] = VERT_BIT_ELT;
  467.      elts[i+offset] = dst;
  468.       }
  469. /*        _mesa_debug(ctx, "ADDING VERT_BIT_ELT!\n"); */
  470.       next->CopyOrFlag |= VERT_BIT_ELT;
  471.       next->CopyAndFlag &= VERT_BIT_ELT;
  472.    }
  473.    else {
  474.       GLuint copy = tnl->pipeline.inputs & (prev->CopyOrFlag|prev->Evaluated);
  475.       GLuint flag;
  476.  
  477.       if (is_fan_like[ctx->Driver.CurrentExecPrimitive]) {
  478.      flag = ((prev->CopyOrFlag|prev->Evaluated) & VERT_BITS_FIXUP);
  479.      next->CopyOrFlag |= flag;
  480.       } 
  481.       else {
  482.      /* Don't let an early 'glColor', etc. poison the elt path.
  483.       */
  484.      flag = ((prev->OrFlag|prev->Evaluated) & VERT_BITS_FIXUP);
  485.       }
  486.  
  487.       next->TexSize |= tnl->ExecCopyTexSize;
  488.       next->CopyAndFlag &= flag;
  489.      
  490.  
  491. /*        _tnl_print_vert_flags("copy vertex components", copy); */
  492. /*        _tnl_print_vert_flags("prev copyorflag", prev->CopyOrFlag); */
  493. /*        _tnl_print_vert_flags("flag", flag); */
  494.  
  495.       /* Copy whole vertices
  496.        */
  497.       for (i = 0 ; i < count ; i++)
  498.       {
  499.      GLuint src = elts[i+offset];
  500.      GLuint isrc = src - prev->CopyStart;
  501.      GLuint dst = next->CopyStart+i;
  502.  
  503.      /* Values subject to eval must be copied out of the 'inputs'
  504.       * struct.  (Copied rows should not be evaluated twice).
  505.       *
  506.       * Note these pointers are null when inactive.
  507.       */
  508.      COPY_4FV( next->Attrib[VERT_ATTRIB_POS][dst],
  509.                    inputs->Obj.data[isrc] );
  510.  
  511.      if (copy & VERT_BIT_NORMAL) {
  512. /*          _mesa_debug(ctx, "copy vert norm %d to %d (%p): %f %f %f\n", */
  513. /*              isrc, dst,  */
  514. /*              next->Normal[dst], */
  515. /*              inputs->Normal.data[isrc][0], */
  516. /*              inputs->Normal.data[isrc][1], */
  517. /*              inputs->Normal.data[isrc][2]); */
  518.         COPY_3FV( next->Attrib[VERT_ATTRIB_NORMAL][dst], inputs->Normal.data[isrc] );
  519.      }
  520.  
  521.      if (copy & VERT_BIT_COLOR0)
  522.         COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR0][dst], 
  523.               ((GLfloat (*)[4])inputs->Color.Ptr)[isrc] );
  524.  
  525.      if (copy & VERT_BIT_INDEX)
  526.         next->Index[dst] = inputs->Index.data[isrc];
  527.  
  528.      if (copy & VERT_BITS_TEX_ANY) {
  529.         GLuint i;
  530.         for (i = 0 ; i < prev->MaxTextureUnits ; i++) {
  531.            if (copy & VERT_BIT_TEX(i))
  532.           COPY_4FV( next->Attrib[VERT_ATTRIB_TEX0 + i][dst], 
  533.                 inputs->TexCoord[i].data[isrc] );
  534.         }
  535.      }
  536.  
  537.      /* Remaining values should be the same in the 'input' struct and the
  538.       * original immediate.
  539.       */
  540.      if (copy & (VERT_BIT_ELT|VERT_BIT_EDGEFLAG|VERT_BIT_COLOR1|VERT_BIT_FOG|
  541.              VERT_BIT_MATERIAL)) {
  542.  
  543.         if (prev->Flag[src] & VERT_BIT_MATERIAL)
  544.            copy_material(next, prev, dst, src);
  545.  
  546.         next->Elt[dst] = prev->Elt[src];
  547.         next->EdgeFlag[dst] = prev->EdgeFlag[src];
  548.         COPY_4FV( next->Attrib[VERT_ATTRIB_COLOR1][dst],
  549.                       prev->Attrib[VERT_ATTRIB_COLOR1][src] );
  550.         COPY_4FV( next->Attrib[VERT_ATTRIB_FOG][dst],
  551.                       prev->Attrib[VERT_ATTRIB_FOG][src] );
  552.      }
  553.  
  554.      next->Flag[dst] = flag;
  555.      next->CopyOrFlag |= prev->Flag[src] & (VERT_BITS_FIXUP|
  556.                         VERT_BIT_MATERIAL|
  557.                         VERT_BIT_POS);
  558.       elts[i+offset] = dst;
  559.       }
  560.    }
  561.  
  562.    if (--tnl->ExecCopySource->ref_count == 0) 
  563.       _tnl_free_immediate( ctx, tnl->ExecCopySource );
  564.   
  565.    tnl->ExecCopySource = next; next->ref_count++;
  566. }
  567.  
  568.  
  569.  
  570. /* Revive a compiled immediate struct - propogate new 'Current'
  571.  * values.  Often this is redundant because the current values were
  572.  * known and fixed up at compile time (or in the first execution of
  573.  * the cassette).
  574.  */
  575. void _tnl_fixup_compiled_cassette( GLcontext *ctx, struct immediate *IM )
  576. {
  577.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  578.    GLuint fixup;
  579.    GLuint start = IM->Start;
  580.  
  581. /*     _mesa_debug(ctx, "%s\n", __FUNCTION__); */
  582.  
  583.    IM->Evaluated = 0;
  584.    IM->CopyOrFlag = IM->OrFlag;      
  585.    IM->CopyAndFlag = IM->AndFlag; 
  586.    IM->CopyTexSize = IM->TexSize | tnl->ExecCopyTexSize;
  587.  
  588.    _tnl_copy_immediate_vertices( ctx, IM );
  589.  
  590.    if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) {
  591.       ASSERT(IM->CopyStart == IM->Start);
  592.    }
  593.  
  594.    /* Naked array elements can be copied into the first cassette in a
  595.     * display list.  Need to translate them away:
  596.     */
  597.    if (IM->CopyOrFlag & VERT_BIT_ELT) {
  598.       GLuint copy = tnl->pipeline.inputs & ~ctx->Array._Enabled;
  599.       GLuint i;
  600.  
  601.       ASSERT(IM->CopyStart < IM->Start);
  602.  
  603.       _tnl_translate_array_elts( ctx, IM, IM->CopyStart, IM->Start );
  604.  
  605.       for (i = IM->CopyStart ; i < IM->Start ; i++)
  606.      copy_from_current( ctx, IM, i, copy ); 
  607.  
  608.       _tnl_copy_to_current( ctx, IM, ctx->Array._Enabled, IM->Start );
  609.    }
  610.  
  611.    fixup = tnl->pipeline.inputs & ~IM->Flag[start] & VERT_BITS_FIXUP;
  612.  
  613. /*     _tnl_print_vert_flags("fixup compiled", fixup); */
  614.  
  615.    if (fixup) {
  616.  
  617.       /* XXX try to replace this code with a loop over the 16 vertex
  618.        * attributes.
  619.        */
  620.  
  621.       if (fixup & VERT_BIT_NORMAL) {
  622.      fixup_first_4f(IM->Attrib[VERT_ATTRIB_NORMAL], IM->Flag,
  623.                         VERT_BIT_NORMAL, start,
  624.             ctx->Current.Attrib[VERT_ATTRIB_NORMAL] );
  625.       }
  626.  
  627.       if (fixup & VERT_BIT_COLOR0) {
  628.      if (IM->CopyOrFlag & VERT_BIT_COLOR0)
  629.         fixup_first_4f(IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
  630.                            VERT_BIT_COLOR0, start,
  631.                ctx->Current.Attrib[VERT_ATTRIB_COLOR0] );
  632.      else
  633.         fixup &= ~VERT_BIT_COLOR0;
  634.       }
  635.  
  636.       if (fixup & VERT_BIT_COLOR1)
  637.      fixup_first_4f(IM->Attrib[VERT_ATTRIB_COLOR1], IM->Flag,
  638.                         VERT_BIT_COLOR1, start,
  639.             ctx->Current.Attrib[VERT_ATTRIB_COLOR1] );
  640.  
  641.       if (fixup & VERT_BIT_FOG)
  642.      fixup_first_4f( IM->Attrib[VERT_ATTRIB_FOG], IM->Flag,
  643.                          VERT_BIT_FOG, start,
  644.                          ctx->Current.Attrib[VERT_ATTRIB_FOG] );
  645.  
  646.       if (fixup & VERT_BITS_TEX_ANY) {
  647.      GLuint i;
  648.      for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++) {
  649.         if (fixup & VERT_BIT_TEX(i))
  650.            fixup_first_4f( IM->Attrib[VERT_ATTRIB_TEX0 + i], IM->Flag,
  651.                                VERT_BIT_TEX(i), start,
  652.                    ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i] );
  653.      }
  654.       }
  655.  
  656.       if (fixup & VERT_BIT_EDGEFLAG)
  657.      fixup_first_1ub(IM->EdgeFlag, IM->Flag, VERT_BIT_EDGEFLAG, start,
  658.              ctx->Current.EdgeFlag );
  659.  
  660.       if (fixup & VERT_BIT_INDEX)
  661.      fixup_first_1ui(IM->Index, IM->Flag, VERT_BIT_INDEX, start,
  662.              ctx->Current.Index );
  663.  
  664.       IM->CopyOrFlag |= fixup;
  665.    }
  666.    
  667.  
  668.    /* Materials:
  669.     */
  670.    if (IM->MaterialOrMask & ~IM->MaterialAndMask) {
  671.       GLuint vulnerable = IM->MaterialOrMask;
  672.       GLuint i = IM->Start;
  673.  
  674.       do {
  675.      while (!(IM->Flag[i] & VERT_BIT_MATERIAL))
  676.         i++;
  677.  
  678.      vulnerable &= ~IM->MaterialMask[i];
  679.      _mesa_copy_material_pairs( IM->Material[i],
  680.                     ctx->Light.Material,
  681.                     vulnerable );
  682.  
  683.  
  684.      ++i;
  685.       } while (vulnerable);
  686.    }
  687. }
  688.  
  689.  
  690.  
  691.  
  692.  
  693.  
  694. static void copy_none( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
  695. {
  696.    (void) (start && ovf && tnl && count);
  697. }
  698.  
  699. static void copy_last( TNLcontext *tnl, GLuint start, GLuint count, GLuint ovf)
  700. {
  701.    (void) start; (void) ovf;
  702.    tnl->ExecCopyCount = 1;
  703.    tnl->ExecCopyElts[2] = count-1;
  704. }
  705.  
  706. static void copy_first_and_last( TNLcontext *tnl, GLuint start, GLuint count,
  707.                  GLuint ovf)
  708. {
  709.    (void) ovf;
  710.    tnl->ExecCopyCount = 2;
  711.    tnl->ExecCopyElts[1] = start;
  712.    tnl->ExecCopyElts[2] = count-1;
  713. }
  714.  
  715. static void copy_last_two( TNLcontext *tnl, GLuint start, GLuint count,
  716.                GLuint ovf )
  717. {
  718.    (void) start;
  719.    tnl->ExecCopyCount = 2+ovf;
  720.    tnl->ExecCopyElts[0] = count-3;
  721.    tnl->ExecCopyElts[1] = count-2;
  722.    tnl->ExecCopyElts[2] = count-1;
  723. }
  724.  
  725. static void copy_overflow( TNLcontext *tnl, GLuint start, GLuint count,
  726.                GLuint ovf )
  727. {
  728.    (void) start;
  729.    tnl->ExecCopyCount = ovf;
  730.    tnl->ExecCopyElts[0] = count-3;
  731.    tnl->ExecCopyElts[1] = count-2;
  732.    tnl->ExecCopyElts[2] = count-1;
  733. }
  734.  
  735.  
  736. typedef void (*copy_func)( TNLcontext *tnl, GLuint start, GLuint count,
  737.                GLuint ovf );
  738.  
  739. static copy_func copy_tab[GL_POLYGON+2] =
  740. {
  741.    copy_none,
  742.    copy_overflow,
  743.    copy_first_and_last,
  744.    copy_last,
  745.    copy_overflow,
  746.    copy_last_two,
  747.    copy_first_and_last,
  748.    copy_overflow,
  749.    copy_last_two,
  750.    copy_first_and_last,
  751.    copy_none
  752. };
  753.  
  754.  
  755.  
  756.  
  757.  
  758. /* Figure out what vertices need to be copied next time.
  759.  */
  760. void
  761. _tnl_get_exec_copy_verts( GLcontext *ctx, struct immediate *IM )
  762. {
  763.  
  764.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  765.    GLuint last = IM->LastPrimitive;
  766.    GLuint prim = ctx->Driver.CurrentExecPrimitive;
  767.    GLuint pincr = increment[prim];
  768.    GLuint pintro = intro[prim];
  769.    GLuint ovf = 0;
  770.  
  771. /*     _mesa_debug(ctx, "_tnl_get_exec_copy_verts %s\n",  */
  772. /*         _mesa_lookup_enum_by_nr(prim)); */
  773.  
  774.    if (tnl->ExecCopySource)
  775.       if (--tnl->ExecCopySource->ref_count == 0) 
  776.      _tnl_free_immediate( ctx, tnl->ExecCopySource );
  777.  
  778.    if (prim == GL_POLYGON+1) {
  779.       tnl->ExecCopySource = 0;
  780.       tnl->ExecCopyCount = 0;
  781.       tnl->ExecCopyTexSize = 0;
  782.       tnl->ExecParity = 0;
  783.    } else {
  784.       /* Remember this immediate as the one to copy from.
  785.        */
  786.       tnl->ExecCopySource = IM; IM->ref_count++;
  787.       tnl->ExecCopyCount = 0;
  788.       tnl->ExecCopyTexSize = IM->CopyTexSize;
  789.  
  790.       if (IM->LastPrimitive != IM->CopyStart)
  791.      tnl->ExecParity = 0;
  792.      
  793.       tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1;
  794.  
  795.  
  796.       if (pincr != 1 && (IM->Count - last - pintro))
  797.      ovf = (IM->Count - last - pintro) % pincr;
  798.  
  799.       if (last < IM->Count)
  800.      copy_tab[prim]( tnl, last, IM->Count, ovf );
  801.    }
  802. }
  803.  
  804.  
  805. /* Recalculate ExecCopyElts, ExecParity, etc.  
  806.  */
  807. void 
  808. _tnl_get_purged_copy_verts( GLcontext *ctx, struct immediate *IM ) 
  809. {
  810.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  811.  
  812.    if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) {
  813.       GLuint last = IM->LastPrimitive;
  814.       GLenum prim = IM->Primitive[last];
  815.       GLuint pincr = increment[prim];
  816.       GLuint pintro = intro[prim];
  817.       GLuint ovf = 0, i;
  818.  
  819.       tnl->ExecCopyCount = 0;
  820.       if (IM->LastPrimitive != IM->CopyStart)
  821.      tnl->ExecParity = 0;
  822.      
  823.       tnl->ExecParity ^= IM->PrimitiveLength[IM->LastPrimitive] & 1;
  824.  
  825.       if (pincr != 1 && (IM->Count - last - pintro))
  826.      ovf = (IM->Count - last - pintro) % pincr;
  827.  
  828.       if (last < IM->Count)
  829.      copy_tab[prim]( tnl, last, IM->Count, ovf );
  830.  
  831.       for (i = 0 ; i < tnl->ExecCopyCount ; i++)
  832.      tnl->ExecCopyElts[i] = IM->Elt[tnl->ExecCopyElts[i]];
  833.    }
  834. }
  835.  
  836.  
  837. void _tnl_upgrade_current_data( GLcontext *ctx,
  838.                 GLuint required,
  839.                 GLuint flags )
  840. {
  841.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  842.    struct vertex_buffer *VB = &tnl->vb;
  843.    struct immediate *IM = (struct immediate *)VB->import_source;
  844.  
  845.    ASSERT(IM);
  846.  
  847. /*     _tnl_print_vert_flags("_tnl_upgrade_client_data", required); */
  848.  
  849.    if ((required & VERT_BIT_COLOR0) && (VB->ColorPtr[0]->Flags & CA_CLIENT_DATA)) {
  850.       struct gl_client_array *tmp = &tnl->imm_inputs.Color;
  851.       GLuint start = IM->CopyStart;
  852.  
  853.       tmp->Ptr = IM->Attrib[VERT_ATTRIB_COLOR0] + start;
  854.       tmp->StrideB = 4 * sizeof(GLfloat);
  855.       tmp->Flags = 0;
  856.  
  857.       COPY_4FV( IM->Attrib[VERT_ATTRIB_COLOR0][start],
  858.                 ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);   
  859.  
  860.       /*
  861.       ASSERT(IM->Flag[IM->LastData+1] & VERT_BIT_END_VB);
  862.       */
  863.  
  864.       fixup_first_4f( IM->Attrib[VERT_ATTRIB_COLOR0], IM->Flag,
  865.                       VERT_BIT_END_VB,
  866.                       start, IM->Attrib[VERT_ATTRIB_COLOR0][start] );
  867.  
  868.       VB->importable_data &= ~VERT_BIT_COLOR0;
  869.    }
  870. }
  871.  
  872.