home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / tnl / t_imm_api.cpp < prev    next >
C/C++ Source or Header  |  2002-12-18  |  38KB  |  1,404 lines

  1. /* $Id: t_imm_api.c,v 1.37 2002/11/25 20:27:47 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2001  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.  */
  29.  
  30.  
  31.  
  32. #include "glheader.h"
  33. #include "context.h"
  34. #include "dlist.h"
  35. #include "enums.h"
  36. #include "light.h"
  37. #include "imports.h"
  38. #include "state.h"
  39. #include "colormac.h"
  40. #include "macros.h"
  41. #include "vtxfmt.h"
  42.  
  43. #include "t_context.h"
  44. #include "t_imm_api.h"
  45. #include "t_imm_elt.h"
  46. #include "t_imm_exec.h"
  47. #include "t_imm_dlist.h"
  48.  
  49.  
  50. /* A cassette is full or flushed on a statechange.
  51.  */
  52. void _tnl_flush_immediate( GLcontext *ctx, struct immediate *IM )
  53. {
  54.    if (!ctx) {
  55.       /* We were called by glVertex, glEvalCoord, glArrayElement, etc.
  56.        * The current context is corresponds to the IM structure.
  57.        */
  58.       GET_CURRENT_CONTEXT(context);
  59.       ctx = context;
  60.    }
  61.  
  62.    if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
  63.       _mesa_debug(ctx, "_tnl_flush_immediate IM: %d compiling: %d\n",
  64.                   IM->id, ctx->CompileFlag);
  65.  
  66.    if (IM->FlushElt == FLUSH_ELT_EAGER) {
  67.       _tnl_translate_array_elts( ctx, IM, IM->LastPrimitive, IM->Count );
  68.    }
  69.  
  70.    /* Mark the last primitive:
  71.     */
  72.    IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
  73.    IM->Primitive[IM->LastPrimitive] |= PRIM_LAST;
  74.  
  75.    if (ctx->CompileFlag)
  76.       _tnl_compile_cassette( ctx, IM );
  77.    else
  78.       _tnl_execute_cassette( ctx, IM );
  79. }
  80.  
  81.  
  82. /* Hook for ctx->Driver.FlushVertices:
  83.  */
  84. void _tnl_flush_vertices( GLcontext *ctx, GLuint flags )
  85. {
  86.    struct immediate *IM = TNL_CURRENT_IM(ctx);
  87.  
  88.    if (MESA_VERBOSE & VERBOSE_IMMEDIATE)
  89.       _mesa_debug(ctx,
  90.                   "_tnl_flush_vertices flags %x IM(%d) %d..%d Flag[%d]: %x\n", 
  91.                   flags, IM->id, IM->Start, IM->Count, IM->Start,
  92.                   IM->Flag[IM->Start]);
  93.  
  94.    if (IM->Flag[IM->Start]) {
  95.       if ((flags & FLUSH_UPDATE_CURRENT) || 
  96.       IM->Count > IM->Start ||
  97.       (IM->Flag[IM->Start] & (VERT_BIT_BEGIN | VERT_BIT_END))) {
  98.      _tnl_flush_immediate( ctx, IM );
  99.       }
  100.    }
  101. }
  102.  
  103.  
  104. void
  105. _tnl_save_Begin( GLenum mode )
  106. {
  107.    GET_CURRENT_CONTEXT(ctx);
  108.    struct immediate *IM = TNL_CURRENT_IM(ctx);
  109.    GLuint inflags, state;
  110.  
  111. /*     _mesa_debug(ctx, "%s: before: %x\n", __FUNCTION__, IM->BeginState); */
  112.  
  113.    if (mode > GL_POLYGON) {
  114.       _mesa_compile_error( ctx, GL_INVALID_ENUM, "_tnl_Begin" );
  115.       return;
  116.    }
  117.  
  118.    if (ctx->NewState)
  119.       _mesa_update_state(ctx);
  120.  
  121. #if 000
  122.    /* if only a very few slots left, might as well flush now
  123.     */
  124.    if (IM->Count > IMM_MAXDATA-8) {
  125.       _tnl_flush_immediate( ctx, IM );
  126.       IM = TNL_CURRENT_IM(ctx);
  127.    }
  128. #endif
  129.  
  130.    if (IM->Count > IMM_MAXDATA-8) {
  131.       _tnl_flush_immediate( ctx, IM );
  132.       IM = TNL_CURRENT_IM(ctx);
  133.    }
  134.  
  135.    /* Check for and flush buffered vertices from internal operations.
  136.     */
  137.    if (IM->SavedBeginState) {
  138.       _tnl_flush_immediate( ctx, IM );
  139.       IM = TNL_CURRENT_IM(ctx);
  140.       IM->BeginState = IM->SavedBeginState;
  141.       IM->SavedBeginState = 0;
  142.    }
  143.  
  144.    state = IM->BeginState;
  145.    inflags = state & (VERT_BEGIN_0|VERT_BEGIN_1);
  146.    state |= inflags << 2;    /* set error conditions */
  147.  
  148.    if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
  149.    {
  150.       GLuint count = IM->Count;
  151.       GLuint last = IM->LastPrimitive;
  152.  
  153.       state |= (VERT_BEGIN_0|VERT_BEGIN_1);
  154.       IM->Flag[count] |= VERT_BIT_BEGIN;
  155.       IM->Primitive[count] = mode | PRIM_BEGIN;
  156.       IM->PrimitiveLength[IM->LastPrimitive] = count - IM->LastPrimitive;
  157.       IM->LastPrimitive = count;
  158.  
  159.       /* Not quite right.  Need to use the fallback '_aa_ArrayElement'
  160.        * when not known to be inside begin/end and arrays are
  161.        * unlocked.  
  162.        */
  163.       if (IM->FlushElt == FLUSH_ELT_EAGER) {
  164.      _tnl_translate_array_elts( ctx, IM, last, count );
  165.       }
  166.    }
  167.  
  168.    ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
  169.    IM->BeginState = state;
  170.  
  171.    /* Update save_primitive now.  Don't touch ExecPrimitive as this is
  172.     * updated in the replay of this cassette if we are in
  173.     * COMPILE_AND_EXECUTE mode.
  174.     */
  175.    if (ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN)
  176.       ctx->Driver.CurrentSavePrimitive = PRIM_INSIDE_UNKNOWN_PRIM;
  177.    else if (ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END)
  178.       ctx->Driver.CurrentSavePrimitive = mode;
  179. }
  180.  
  181.  
  182. void
  183. _tnl_Begin( GLenum mode )
  184. {
  185.    GET_CURRENT_CONTEXT(ctx);
  186.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  187.    ASSERT (!ctx->CompileFlag);
  188.  
  189.    if (mode > GL_POLYGON) {
  190.       _mesa_error( ctx, GL_INVALID_ENUM, "_tnl_Begin(0x%x)", mode );
  191.       return;
  192.    }
  193.  
  194.    if (ctx->Driver.CurrentExecPrimitive != PRIM_OUTSIDE_BEGIN_END) {
  195.       _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_Begin" );
  196.       return;
  197.    }
  198.  
  199.    if (ctx->NewState)
  200.       _mesa_update_state(ctx);
  201.  
  202.    {
  203.       struct immediate *IM = TNL_CURRENT_IM(ctx);
  204.       if (IM->Count > IMM_MAXDATA-8) {
  205.      _tnl_flush_immediate( ctx, IM );
  206.      IM = TNL_CURRENT_IM(ctx);
  207.       }
  208.    }
  209.  
  210.  
  211.    {
  212.       struct immediate *IM = TNL_CURRENT_IM(ctx);
  213.       GLuint count = IM->Count;
  214.       GLuint last = IM->LastPrimitive;
  215.  
  216.       if (IM->Start == IM->Count &&
  217.       tnl->Driver.NotifyBegin &&
  218.       tnl->Driver.NotifyBegin( ctx, mode )) {
  219.      return;
  220.       }
  221.  
  222.       assert( IM->SavedBeginState == 0 );
  223.       assert( IM->BeginState == 0 );
  224.  
  225.       /* Not quite right.  Need to use the fallback '_aa_ArrayElement'
  226.        * when not known to be inside begin/end and arrays are
  227.        * unlocked.  
  228.        */
  229.       if (IM->FlushElt == FLUSH_ELT_EAGER) {
  230.      _tnl_translate_array_elts( ctx, IM, last, count );
  231.       }
  232.  
  233.       IM->Flag[count] |= VERT_BIT_BEGIN;
  234.       IM->Primitive[count] = mode | PRIM_BEGIN;
  235.       IM->PrimitiveLength[last] = count - last;
  236.       IM->LastPrimitive = count;
  237.       IM->BeginState = (VERT_BEGIN_0|VERT_BEGIN_1);
  238.  
  239. /*        _mesa_debug(ctx, "%s: %x\n", __FUNCTION__, IM->BeginState);  */
  240.  
  241.       ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
  242.       ctx->Driver.CurrentExecPrimitive = mode;
  243.    }
  244. }
  245.  
  246.  
  247. /* Function which allows operations like 'glRectf' to decompose to a
  248.  * begin/end object and vertices without worrying about what happens
  249.  * with display lists.
  250.  */
  251. GLboolean
  252. _tnl_hard_begin( GLcontext *ctx, GLenum p )
  253. {
  254. /*     _mesa_debug(ctx, "%s\n", __FUNCTION__); */
  255.  
  256.    if (!ctx->CompileFlag) {
  257.       /* If not compiling, treat as a normal begin().
  258.        */
  259. /*        _mesa_debug(ctx, "%s: treating as glBegin\n", __FUNCTION__); */
  260.       glBegin( p );
  261.       return GL_TRUE;
  262.    }
  263.    else {
  264.       /* Otherwise, need to do special processing to preserve the
  265.        * condition that these vertices will only be replayed outside
  266.        * future begin/end objects.
  267.        */
  268.       struct immediate *IM = TNL_CURRENT_IM(ctx);
  269.  
  270.       if (ctx->NewState)
  271.      _mesa_update_state(ctx);
  272.  
  273.       if (IM->Count > IMM_MAXDATA-8) {
  274.      _tnl_flush_immediate( ctx, IM );
  275.      IM = TNL_CURRENT_IM(ctx);
  276.       }
  277.  
  278.       /* A lot depends on the degree to which the display list has
  279.        * constrained the possible begin/end states at this point:
  280.        */
  281.       switch (IM->BeginState & (VERT_BEGIN_0|VERT_BEGIN_1)) {
  282.       case VERT_BEGIN_0|VERT_BEGIN_1:
  283.      /* This is an immediate known to be inside a begin/end object.
  284.       */
  285.      ASSERT(ctx->Driver.CurrentSavePrimitive <= GL_POLYGON);
  286.      IM->BeginState |= (VERT_ERROR_1|VERT_ERROR_0);
  287.      return GL_FALSE;
  288.  
  289.       case VERT_BEGIN_0:
  290.       case VERT_BEGIN_1:
  291.      /* This is a display-list immediate in an unknown begin/end
  292.       * state.  Assert it is empty and convert it to a 'hard' one.
  293.       */
  294.      ASSERT(IM->SavedBeginState == 0);
  295.      ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN);
  296.  
  297.      /* Push current beginstate, to be restored later.  Don't worry
  298.       * about raising errors.
  299.       */
  300.      IM->SavedBeginState = IM->BeginState;
  301.  
  302.      /* FALLTHROUGH */
  303.  
  304.       case 0:
  305.      /* Unless we have fallen through, this is an immediate known to
  306.       * be outside begin/end objects.
  307.       */
  308.      ASSERT(ctx->Driver.CurrentSavePrimitive == PRIM_UNKNOWN ||
  309.         ctx->Driver.CurrentSavePrimitive == PRIM_OUTSIDE_BEGIN_END);
  310.      ASSERT (IM->FlushElt != FLUSH_ELT_EAGER);
  311.  
  312.      IM->BeginState |= VERT_BEGIN_0|VERT_BEGIN_1;
  313.      IM->Flag[IM->Count] |= VERT_BIT_BEGIN;
  314.      IM->Primitive[IM->Count] = p | PRIM_BEGIN;
  315.      IM->PrimitiveLength[IM->LastPrimitive] = IM->Count - IM->LastPrimitive;
  316.      IM->LastPrimitive = IM->Count;
  317.  
  318.      /* This is necessary as this immediate will not be flushed in
  319.       * _tnl_end() -- we leave it active, hoping to pick up more
  320.       * vertices before the next state change.
  321.       */
  322.      ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
  323.      return GL_TRUE;
  324.  
  325.       default:
  326.      assert (0);
  327.      return GL_TRUE;
  328.       }
  329.    }
  330. }
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337. /* Both streams now outside begin/end.
  338.  *
  339.  * Leave SavedBeginState untouched -- attempt to gather several
  340.  * rects/arrays together in a single immediate struct.
  341.  */
  342. void
  343. _tnl_end( GLcontext *ctx )
  344. {
  345.    struct immediate *IM = TNL_CURRENT_IM(ctx);
  346.    GLuint state = IM->BeginState;
  347.    GLuint inflags = (~state) & (VERT_BEGIN_0|VERT_BEGIN_1);
  348.  
  349.    assert( ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES );
  350.  
  351.    state |= inflags << 2;    /* errors */
  352.  
  353.    if (inflags != (VERT_BEGIN_0|VERT_BEGIN_1))
  354.    {
  355.       GLuint count = IM->Count;
  356.       GLuint last = IM->LastPrimitive;
  357.  
  358.       state &= ~(VERT_BEGIN_0|VERT_BEGIN_1); /* update state */
  359.       IM->Flag[count] |= VERT_BIT_END;
  360.       IM->Primitive[last] |= PRIM_END;
  361.       IM->PrimitiveLength[last] = count - last;
  362.       IM->Primitive[count] = PRIM_OUTSIDE_BEGIN_END; /* removes PRIM_BEGIN 
  363.                               * flag if length == 0
  364.                               */
  365.       IM->LastPrimitive = count;
  366.  
  367.       if (IM->FlushElt == FLUSH_ELT_EAGER) {
  368.      _tnl_translate_array_elts( ctx, IM, last, count );
  369.       }
  370.    }
  371.  
  372.    IM->BeginState = state;
  373.  
  374.    if (!ctx->CompileFlag) {
  375.       if (ctx->Driver.CurrentExecPrimitive == PRIM_OUTSIDE_BEGIN_END) 
  376.      _mesa_error( ctx, GL_INVALID_OPERATION, "_tnl_End" );
  377.       else
  378.      ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
  379.    }
  380.  
  381.    /* You can set this flag to get the old 'flush_vb on glEnd()'
  382.     * behaviour.
  383.     */
  384.    if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH)
  385.       _tnl_flush_immediate( ctx, IM );
  386. }
  387.  
  388. void
  389. _tnl_End(void)
  390. {
  391.    GET_CURRENT_CONTEXT(ctx);
  392.  
  393.    _tnl_end( ctx );
  394.  
  395.    /* Need to keep save primitive uptodate in COMPILE and
  396.     * COMPILE_AND_EXEC modes, need to keep exec primitive uptodate
  397.     * otherwise.
  398.     */
  399.    if (ctx->CompileFlag)
  400.       ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END;
  401. }
  402.  
  403.  
  404. #define COLOR( r, g, b, a )                    \
  405. {                                \
  406.    GET_IMMEDIATE;                        \
  407.    GLuint count = IM->Count;                    \
  408.    GLfloat *color = IM->Attrib[VERT_ATTRIB_COLOR0][count];    \
  409.    IM->Flag[count] |= VERT_BIT_COLOR0;                \
  410.    color[0] = r;                        \
  411.    color[1] = g;                        \
  412.    color[2] = b;                        \
  413.    color[3] = a;                        \
  414. }
  415.  
  416. static void
  417. _tnl_Color3f( GLfloat red, GLfloat green, GLfloat blue )
  418. {
  419.    COLOR( red, green, blue, 1.0 );
  420. }
  421.  
  422. static void
  423. _tnl_Color3ub( GLubyte red, GLubyte green, GLubyte blue )
  424. {
  425.    COLOR(UBYTE_TO_FLOAT(red),
  426.          UBYTE_TO_FLOAT(green),
  427.          UBYTE_TO_FLOAT(blue),
  428.          1.0);
  429. }
  430.  
  431. static void
  432. _tnl_Color4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
  433. {
  434. /*   COLOR( red, green, blue, alpha ); */
  435. //debug expanded EK
  436.     struct immediate *IM = _tnl_CurrentInput;
  437.     GLuint count = IM->Count; 
  438.     GLfloat *color = IM->Attrib[3][count]; 
  439.     IM->Flag[count] |= (1 << 3);
  440.     color[0] = red; 
  441.     color[1] = green; 
  442.     color[2] = blue; 
  443.     color[3] = alpha;
  444. }
  445.  
  446. static void
  447. _tnl_Color4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
  448. {
  449.    COLOR(UBYTE_TO_FLOAT(red),
  450.          UBYTE_TO_FLOAT(green),
  451.          UBYTE_TO_FLOAT(blue),
  452.          UBYTE_TO_FLOAT(alpha));
  453. }
  454.  
  455. static void
  456. _tnl_Color3fv( const GLfloat *v )
  457. {
  458.    COLOR( v[0], v[1], v[2], 1.0 );
  459. }
  460.  
  461. static void
  462. _tnl_Color3ubv( const GLubyte *v )
  463. {
  464.    COLOR(UBYTE_TO_FLOAT(v[0]),
  465.          UBYTE_TO_FLOAT(v[1]),
  466.          UBYTE_TO_FLOAT(v[2]),
  467.          1.0 );
  468. }
  469.  
  470. static void
  471. _tnl_Color4fv( const GLfloat *v )
  472. {
  473.    COLOR( v[0], v[1], v[2], v[3] );
  474. }
  475.  
  476. static void
  477. _tnl_Color4ubv( const GLubyte *v)
  478. {
  479.    COLOR(UBYTE_TO_FLOAT(v[0]),
  480.          UBYTE_TO_FLOAT(v[1]),
  481.          UBYTE_TO_FLOAT(v[2]),
  482.          UBYTE_TO_FLOAT(v[3]));
  483. }
  484.  
  485.  
  486.  
  487.  
  488. #define SECONDARY_COLOR( r, g, b )            \
  489. {                            \
  490.    GLuint count;                    \
  491.    GET_IMMEDIATE;                    \
  492.    count = IM->Count;                    \
  493.    IM->Flag[count] |= VERT_BIT_COLOR1;            \
  494.    IM->Attrib[VERT_ATTRIB_COLOR1][count][0] = r;    \
  495.    IM->Attrib[VERT_ATTRIB_COLOR1][count][1] = g;    \
  496.    IM->Attrib[VERT_ATTRIB_COLOR1][count][2] = b;    \
  497. }
  498.  
  499. static void
  500. _tnl_SecondaryColor3fEXT( GLfloat red, GLfloat green, GLfloat blue )
  501. {
  502.    SECONDARY_COLOR( red, green, blue );
  503. }
  504.  
  505. static void
  506. _tnl_SecondaryColor3ubEXT( GLubyte red, GLubyte green, GLubyte blue )
  507. {
  508.    SECONDARY_COLOR(UBYTE_TO_FLOAT(red),
  509.                    UBYTE_TO_FLOAT(green),
  510.                    UBYTE_TO_FLOAT(blue));
  511. }
  512.  
  513. static void
  514. _tnl_SecondaryColor3fvEXT( const GLfloat *v )
  515. {
  516.    SECONDARY_COLOR( v[0], v[1], v[2] );
  517. }
  518.  
  519. static void
  520. _tnl_SecondaryColor3ubvEXT( const GLubyte *v )
  521. {
  522.    SECONDARY_COLOR(UBYTE_TO_FLOAT(v[0]),
  523.                    UBYTE_TO_FLOAT(v[1]),
  524.                    UBYTE_TO_FLOAT(v[2]));
  525. }
  526.  
  527.  
  528. static void
  529. _tnl_EdgeFlag( GLboolean flag )
  530. {
  531.    GLuint count;
  532.    GET_IMMEDIATE;
  533.    count = IM->Count;
  534.    IM->EdgeFlag[count] = flag;
  535.    IM->Flag[count] |= VERT_BIT_EDGEFLAG;
  536. }
  537.  
  538.  
  539. static void
  540. _tnl_EdgeFlagv( const GLboolean *flag )
  541. {
  542.    GLuint count;
  543.    GET_IMMEDIATE;
  544.    count = IM->Count;
  545.    IM->EdgeFlag[count] = *flag;
  546.    IM->Flag[count] |= VERT_BIT_EDGEFLAG;
  547. }
  548.  
  549.  
  550. static void
  551. _tnl_FogCoordfEXT( GLfloat f )
  552. {
  553.    GLuint count;
  554.    GET_IMMEDIATE;
  555.    count = IM->Count;
  556.    IM->Attrib[VERT_ATTRIB_FOG][count][0] = f; /*FogCoord[count] = f;*/
  557.    IM->Flag[count] |= VERT_BIT_FOG;
  558. }
  559.  
  560. static void
  561. _tnl_FogCoordfvEXT( const GLfloat *v )
  562. {
  563.    GLuint count;
  564.    GET_IMMEDIATE;
  565.    count = IM->Count;
  566.    IM->Attrib[VERT_ATTRIB_FOG][count][0] = v[0]; /*FogCoord[count] = v[0];*/
  567.    IM->Flag[count] |= VERT_BIT_FOG;
  568. }
  569.  
  570.  
  571. static void
  572. _tnl_Indexi( GLint c )
  573. {
  574.    GLuint count;
  575.    GET_IMMEDIATE;
  576.    count = IM->Count;
  577.    IM->Index[count] = c;
  578.    IM->Flag[count] |= VERT_BIT_INDEX;
  579. }
  580.  
  581.  
  582. static void
  583. _tnl_Indexiv( const GLint *c )
  584. {
  585.    GLuint count;
  586.    GET_IMMEDIATE;
  587.    count = IM->Count;
  588.    IM->Index[count] = *c;
  589.    IM->Flag[count] |= VERT_BIT_INDEX;
  590. }
  591.  
  592.  
  593. #define NORMAL( x, y, z )                \
  594. {                            \
  595.    GLuint count;                    \
  596.    GLfloat *normal;                    \
  597.    GET_IMMEDIATE;                    \
  598.    count = IM->Count;                    \
  599.    IM->Flag[count] |= VERT_BIT_NORMAL;            \
  600.    normal = IM->Attrib[VERT_ATTRIB_NORMAL][count];    \
  601.    ASSIGN_3V(normal, x,y,z);                \
  602. }
  603.  
  604. #if defined(USE_IEEE)
  605. #define NORMALF( x, y, z )                    \
  606. {                                \
  607.    GLuint count;                        \
  608.    fi_type *normal;                        \
  609.    GET_IMMEDIATE;                        \
  610.    count = IM->Count;                        \
  611.    IM->Flag[count] |= VERT_BIT_NORMAL;                \
  612.    normal = (fi_type *)IM->Attrib[VERT_ATTRIB_NORMAL][count];    \
  613.    normal[0].i = ((fi_type *)&(x))->i;                \
  614.    normal[1].i = ((fi_type *)&(y))->i;                \
  615.    normal[2].i = ((fi_type *)&(z))->i;                \
  616. }
  617. #else
  618. #define NORMALF NORMAL
  619. #endif
  620.  
  621. static void
  622. _tnl_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz )
  623. {
  624.    NORMALF(nx, ny, nz);
  625. }
  626.  
  627.  
  628. static void
  629. _tnl_Normal3fv( const GLfloat *v )
  630. {
  631.    NORMALF( v[0], v[1], v[2] );
  632. /*     struct immediate *IM = (struct immediate *)(((GLcontext *) _glapi_Context)->swtnl_im); */
  633. /*     IM->Flag[IM->Count] = VERT_NORM; */
  634. }
  635.  
  636.  
  637.  
  638. #define TEXCOORD1(s)                \
  639. {                        \
  640.    GLuint count;                \
  641.    GLfloat *tc;                    \
  642.    GET_IMMEDIATE;                \
  643.    count = IM->Count;                \
  644.    IM->Flag[count] |= VERT_BIT_TEX0;        \
  645.    tc = IM->Attrib[VERT_ATTRIB_TEX0][count];    \
  646.    ASSIGN_4V(tc,s,0,0,1);            \
  647. }
  648.  
  649. #define TEXCOORD2(s, t)                \
  650. {                        \
  651.    GLuint count;                \
  652.    GLfloat *tc;                    \
  653.    GET_IMMEDIATE;                \
  654.    count = IM->Count;                \
  655.    IM->Flag[count] |= VERT_BIT_TEX0;        \
  656.    tc = IM->Attrib[VERT_ATTRIB_TEX0][count];    \
  657.    ASSIGN_4V(tc, s, t, 0, 1);                \
  658. }
  659.  
  660. #define TEXCOORD3(s, t, u)            \
  661. {                        \
  662.    GLuint count;                \
  663.    GLfloat *tc;                    \
  664.    GET_IMMEDIATE;                \
  665.    count = IM->Count;                \
  666.    IM->Flag[count] |= VERT_BIT_TEX0;        \
  667.    IM->TexSize |= TEX_0_SIZE_3;            \
  668.    tc = IM->Attrib[VERT_ATTRIB_TEX0][count];    \
  669.    ASSIGN_4V(tc, s, t, u, 1);            \
  670. }
  671.  
  672. #define TEXCOORD4(s, t, u, v)            \
  673. {                        \
  674.    GLuint count;                \
  675.    GLfloat *tc;                    \
  676.    GET_IMMEDIATE;                \
  677.    count = IM->Count;                \
  678.    IM->Flag[count] |= VERT_BIT_TEX0;        \
  679.    IM->TexSize |= TEX_0_SIZE_4;            \
  680.    tc = IM->Attrib[VERT_ATTRIB_TEX0][count];    \
  681.    ASSIGN_4V(tc, s, t, u, v);            \
  682. }
  683.  
  684. #if defined(USE_IEEE)
  685. #define TEXCOORD2F(s, t)                \
  686. {                            \
  687.    GLuint count;                    \
  688.    fi_type *tc;                        \
  689.    GET_IMMEDIATE;                    \
  690.    count = IM->Count;                    \
  691.    IM->Flag[count] |= VERT_BIT_TEX0;            \
  692.    tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0][count];    \
  693.    tc[0].i = ((fi_type *)&(s))->i;            \
  694.    tc[1].i = ((fi_type *)&(t))->i;            \
  695.    tc[2].i = 0;                        \
  696.    tc[3].i = IEEE_ONE;                    \
  697. }
  698. #else
  699. #define TEXCOORD2F TEXCOORD2
  700. #endif
  701.  
  702. static void
  703. _tnl_TexCoord1f( GLfloat s )
  704. {
  705.    TEXCOORD1(s);
  706. }
  707.  
  708.  
  709. static void
  710. _tnl_TexCoord2f( GLfloat s, GLfloat t )
  711. {
  712.    TEXCOORD2F(s, t);
  713. }
  714.  
  715.  
  716. static void
  717. _tnl_TexCoord3f( GLfloat s, GLfloat t, GLfloat r )
  718. {
  719.    TEXCOORD3(s, t, r);
  720. }
  721.  
  722. static void
  723. _tnl_TexCoord4f( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
  724. {
  725.    TEXCOORD4(s, t, r, q)
  726. }
  727.  
  728. static void
  729. _tnl_TexCoord1fv( const GLfloat *v )
  730. {
  731.    TEXCOORD1(v[0]);
  732. }
  733.  
  734. static void
  735. _tnl_TexCoord2fv( const GLfloat *v )
  736. {
  737.    TEXCOORD2F(v[0], v[1]);
  738. }
  739.  
  740. static void
  741. _tnl_TexCoord3fv( const GLfloat *v )
  742. {
  743.    TEXCOORD3(v[0], v[1], v[2]);
  744. }
  745.  
  746. static void
  747. _tnl_TexCoord4fv( const GLfloat *v )
  748. {
  749.    TEXCOORD4(v[0], v[1], v[2], v[3]);
  750. }
  751.  
  752.  
  753.  
  754. /* KW: Run into bad problems in vertex copying if we don't fully pad
  755.  *     the incoming vertices.
  756.  */
  757. #define VERTEX2(IM, x,y)                \
  758. {                            \
  759.    GLuint count = IM->Count++;                \
  760.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  761.    IM->Flag[count] |= VERT_BIT_POS;            \
  762.    ASSIGN_4V(dest, x, y, 0, 1);                \
  763. /*     ASSERT(IM->Flag[IM->Count]==0);         */    \
  764.    if (count == IMM_MAXDATA - 1)            \
  765.       _tnl_flush_immediate( NULL, IM );            \
  766. }
  767.  
  768. #define VERTEX3(IM,x,y,z)                \
  769. {                            \
  770.    GLuint count = IM->Count++;                \
  771.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  772.    IM->Flag[count] |= VERT_BITS_OBJ_23;            \
  773.    ASSIGN_4V(dest, x, y, z, 1);                \
  774. /*     ASSERT(IM->Flag[IM->Count]==0); */        \
  775.    if (count == IMM_MAXDATA - 1)            \
  776.       _tnl_flush_immediate( NULL, IM );            \
  777. }
  778.  
  779. #define VERTEX4(IM, x,y,z,w)                \
  780. {                            \
  781.    GLuint count = IM->Count++;                \
  782.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  783.    IM->Flag[count] |= VERT_BITS_OBJ_234;        \
  784.    ASSIGN_4V(dest, x, y, z, w);                \
  785.    if (count == IMM_MAXDATA - 1)            \
  786.       _tnl_flush_immediate( NULL, IM );            \
  787. }
  788.  
  789. #if defined(USE_IEEE)
  790. #define VERTEX2F(IM, x, y)                        \
  791. {                                    \
  792.    GLuint count = IM->Count++;                        \
  793.    fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count];    \
  794.    IM->Flag[count] |= VERT_BIT_POS;                     \
  795.    dest[0].i = ((fi_type *)&(x))->i;                    \
  796.    dest[1].i = ((fi_type *)&(y))->i;                    \
  797.    dest[2].i = 0;                            \
  798.    dest[3].i = IEEE_ONE;                        \
  799. /*     ASSERT(IM->Flag[IM->Count]==0); */                \
  800.    if (count == IMM_MAXDATA - 1)                    \
  801.       _tnl_flush_immediate( NULL, IM );                    \
  802. }
  803. #else
  804. #define VERTEX2F VERTEX2
  805. #endif
  806.  
  807. #if defined(USE_IEEE)
  808. #define VERTEX3F(IM, x, y, z)                        \
  809. {                                    \
  810.    GLuint count = IM->Count++;                        \
  811.    fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count];    \
  812.    IM->Flag[count] |= VERT_BITS_OBJ_23;                    \
  813.    dest[0].i = ((fi_type *)&(x))->i;                    \
  814.    dest[1].i = ((fi_type *)&(y))->i;                    \
  815.    dest[2].i = ((fi_type *)&(z))->i;                    \
  816.    dest[3].i = IEEE_ONE;                        \
  817. /*     ASSERT(IM->Flag[IM->Count]==0);     */                \
  818.    if (count == IMM_MAXDATA - 1)                    \
  819.       _tnl_flush_immediate( NULL, IM );                    \
  820. }
  821. #else
  822. #define VERTEX3F VERTEX3
  823. #endif
  824.  
  825. #if defined(USE_IEEE)
  826. #define VERTEX4F(IM, x, y, z, w)                    \
  827. {                                    \
  828.    GLuint count = IM->Count++;                        \
  829.    fi_type *dest = (fi_type *)IM->Attrib[VERT_ATTRIB_POS][count];    \
  830.    IM->Flag[count] |= VERT_BITS_OBJ_234;                \
  831.    dest[0].i = ((fi_type *)&(x))->i;                    \
  832.    dest[1].i = ((fi_type *)&(y))->i;                    \
  833.    dest[2].i = ((fi_type *)&(z))->i;                    \
  834.    dest[3].i = ((fi_type *)&(w))->i;                    \
  835.    if (count == IMM_MAXDATA - 1)                    \
  836.       _tnl_flush_immediate( NULL, IM );                    \
  837. }
  838. #else
  839. #define VERTEX4F VERTEX4
  840. #endif
  841.  
  842.  
  843.  
  844. static void
  845. _tnl_Vertex2f( GLfloat x, GLfloat y )
  846. {
  847. //   GET_IMMEDIATE;
  848. //   VERTEX2F( IM, x, y );
  849. //debug expanded EK
  850.    struct immediate *IM = _tnl_CurrentInput;
  851.    { GLuint count = IM->Count++; 
  852.      fi_type *dest = (fi_type *)IM->Attrib[0][count];
  853.      IM->Flag[count] |= (1 << 0); 
  854.      dest[0].i = ((fi_type *)&(x))->i;
  855.      dest[1].i = ((fi_type *)&(y))->i; 
  856.      dest[2].i = 0; 
  857.      dest[3].i = 0x3f800000; 
  858.      if (count == (216 + 3) - 1) 
  859.         _tnl_flush_immediate( 0, IM );
  860.   }
  861. }
  862.  
  863. static void
  864. _tnl_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
  865. {
  866.    GET_IMMEDIATE;
  867.    VERTEX3F( IM, x, y, z );
  868. }
  869. static void
  870. _tnl_Vertex4f( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
  871. {
  872.    GET_IMMEDIATE;
  873.    VERTEX4F( IM, x, y, z, w );
  874. }
  875.  
  876. static void
  877. _tnl_Vertex2fv( const GLfloat *v )
  878. {
  879.    GET_IMMEDIATE;
  880.    VERTEX2F( IM, v[0], v[1] );
  881. }
  882.  
  883. static void
  884. _tnl_Vertex3fv( const GLfloat *v )
  885. {
  886.    GET_IMMEDIATE;
  887.    VERTEX3F( IM, v[0], v[1], v[2] );
  888. }
  889.  
  890. static void
  891. _tnl_Vertex4fv( const GLfloat *v )
  892. {
  893.    GET_IMMEDIATE;
  894.    VERTEX4F( IM, v[0], v[1], v[2], v[3] );
  895. }
  896.  
  897.  
  898.  
  899.  
  900. /*
  901.  * GL_ARB_multitexture
  902.  *
  903.  * Note: the multitexture spec says that specifying an invalid target
  904.  * has undefined results and does not have to generate an error.  Just
  905.  * don't crash.  We no-op on invalid targets.
  906.  */
  907.  
  908. #define MAX_TARGET (GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
  909.  
  910. #define MULTI_TEXCOORD1(target, s)            \
  911. {                            \
  912.    GET_IMMEDIATE;                    \
  913.    GLuint texunit = target - GL_TEXTURE0_ARB;        \
  914.    if (texunit < IM->MaxTextureUnits) {            \
  915.       GLuint count = IM->Count;                \
  916.       GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];    \
  917.       ASSIGN_4V(tc, s, 0.0F, 0.0F, 1.0F);        \
  918.       IM->Flag[count] |= VERT_BIT_TEX(texunit);        \
  919.    }                            \
  920. }
  921.  
  922. #define MULTI_TEXCOORD2(target, s, t)            \
  923. {                            \
  924.    GET_IMMEDIATE;                    \
  925.    GLuint texunit = target - GL_TEXTURE0_ARB;        \
  926.    if (texunit < IM->MaxTextureUnits) {            \
  927.       GLuint count = IM->Count;                \
  928.       GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];    \
  929.       ASSIGN_4V(tc, s, t, 0.0F, 1.0F);            \
  930.       IM->Flag[count] |= VERT_BIT_TEX(texunit);        \
  931.    }                            \
  932. }
  933.  
  934. #define MULTI_TEXCOORD3(target, s, t, u)        \
  935. {                            \
  936.    GET_IMMEDIATE;                    \
  937.    GLuint texunit = target - GL_TEXTURE0_ARB;        \
  938.    if (texunit < IM->MaxTextureUnits) {            \
  939.       GLuint count = IM->Count;                \
  940.       GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];    \
  941.       ASSIGN_4V(tc, s, t, u, 1.0F);            \
  942.       IM->Flag[count] |= VERT_BIT_TEX(texunit);        \
  943.       IM->TexSize |= TEX_SIZE_3(texunit);        \
  944.    }                            \
  945. }
  946.  
  947. #define MULTI_TEXCOORD4(target, s, t, u, v)        \
  948. {                            \
  949.    GET_IMMEDIATE;                    \
  950.    GLuint texunit = target - GL_TEXTURE0_ARB;        \
  951.    if (texunit < IM->MaxTextureUnits) {            \
  952.       GLuint count = IM->Count;                \
  953.       GLfloat *tc = IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];    \
  954.       ASSIGN_4V(tc, s, t, u, v);            \
  955.       IM->Flag[count] |= VERT_BIT_TEX(texunit);        \
  956.       IM->TexSize |= TEX_SIZE_4(texunit);        \
  957.    }                            \
  958. }
  959.  
  960. #if defined(USE_IEEE)
  961. #define MULTI_TEXCOORD2F(target, s, t)                \
  962. {                                \
  963.    GET_IMMEDIATE;                        \
  964.    GLuint texunit = target - GL_TEXTURE0_ARB;            \
  965.    if (texunit < IM->MaxTextureUnits) {                \
  966.       GLuint count = IM->Count;                    \
  967.       fi_type *tc = (fi_type *)IM->Attrib[VERT_ATTRIB_TEX0 + texunit][count];\
  968.       IM->Flag[count] |= VERT_BIT_TEX(texunit);            \
  969.       tc[0].i = ((fi_type *)&(s))->i;                \
  970.       tc[1].i = ((fi_type *)&(t))->i;                \
  971.       tc[2].i = 0;                        \
  972.       tc[3].i = IEEE_ONE;                    \
  973.    }                                \
  974. }
  975. #else
  976. #define MULTI_TEXCOORD2F MULTI_TEXCOORD2
  977. #endif
  978.  
  979. static void
  980. _tnl_MultiTexCoord1fARB(GLenum target, GLfloat s)
  981. {
  982.    MULTI_TEXCOORD1( target, s );
  983. }
  984.  
  985. static void
  986. _tnl_MultiTexCoord1fvARB(GLenum target, const GLfloat *v)
  987. {
  988.    MULTI_TEXCOORD1( target, v[0] );
  989. }
  990.  
  991. static void
  992. _tnl_MultiTexCoord2fARB(GLenum target, GLfloat s, GLfloat t)
  993. {
  994.    MULTI_TEXCOORD2F( target, s, t );
  995. }
  996.  
  997. static void
  998. _tnl_MultiTexCoord2fvARB(GLenum target, const GLfloat *v)
  999. {
  1000.    MULTI_TEXCOORD2F( target, v[0], v[1] );
  1001. }
  1002.  
  1003. static void
  1004. _tnl_MultiTexCoord3fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r)
  1005. {
  1006.    MULTI_TEXCOORD3( target, s, t, r );
  1007. }
  1008.  
  1009. static void
  1010. _tnl_MultiTexCoord3fvARB(GLenum target, const GLfloat *v)
  1011. {
  1012.    MULTI_TEXCOORD3( target, v[0], v[1], v[2] );
  1013. }
  1014.  
  1015. static void
  1016. _tnl_MultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
  1017. {
  1018.    MULTI_TEXCOORD4( target, s, t, r, q );
  1019. }
  1020.  
  1021. static void
  1022. _tnl_MultiTexCoord4fvARB(GLenum target, const GLfloat *v)
  1023. {
  1024.    MULTI_TEXCOORD4( target, v[0], v[1], v[2], v[3] );
  1025. }
  1026.  
  1027.  
  1028.  
  1029. /* KW: Because the eval values don't become 'current', fixup will flow
  1030.  *     through these vertices, and then evaluation will write on top
  1031.  *     of the fixup results.
  1032.  *
  1033.  *     Note: using Obj to hold eval coord data.
  1034.  */
  1035. #define EVALCOORD1(IM, x)                \
  1036. {                            \
  1037.    GLuint count = IM->Count++;                \
  1038.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  1039.    IM->Flag[count] |= VERT_BIT_EVAL_C1;            \
  1040.    ASSIGN_4V(dest, x, 0, 0, 1);                \
  1041.    if (count == IMM_MAXDATA-1)                \
  1042.       _tnl_flush_immediate( NULL, IM );            \
  1043. }
  1044.  
  1045. #define EVALCOORD2(IM, x, y)                \
  1046. {                            \
  1047.    GLuint count = IM->Count++;                \
  1048.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  1049.    IM->Flag[count] |= VERT_BIT_EVAL_C2;            \
  1050.    ASSIGN_4V(dest, x, y, 0, 1);                \
  1051.    if (count == IMM_MAXDATA-1)                \
  1052.       _tnl_flush_immediate( NULL, IM );            \
  1053. }
  1054.  
  1055. #define EVALPOINT1(IM, x)                \
  1056. {                            \
  1057.    GLuint count = IM->Count++;                \
  1058.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  1059.    IM->Flag[count] |= VERT_BIT_EVAL_P1;            \
  1060.    ASSIGN_4V(dest, x, 0, 0, 1);                \
  1061.    if (count == IMM_MAXDATA-1)                \
  1062.       _tnl_flush_immediate( NULL, IM );            \
  1063. }
  1064.  
  1065. #define EVALPOINT2(IM, x, y)                \
  1066. {                            \
  1067.    GLuint count = IM->Count++;                \
  1068.    GLfloat *dest = IM->Attrib[VERT_ATTRIB_POS][count];    \
  1069.    IM->Flag[count] |= VERT_BIT_EVAL_P2;            \
  1070.    ASSIGN_4V(dest, x, y, 0, 1);                \
  1071.    if (count == IMM_MAXDATA-1)                \
  1072.       _tnl_flush_immediate( NULL, IM );            \
  1073. }
  1074.  
  1075. static void
  1076. _tnl_EvalCoord1f( GLfloat u )
  1077. {
  1078.    GET_IMMEDIATE;
  1079.    EVALCOORD1( IM, u );
  1080. }
  1081.  
  1082. static void
  1083. _tnl_EvalCoord1fv( const GLfloat *u )
  1084. {
  1085.    GET_IMMEDIATE;
  1086.    EVALCOORD1( IM, (GLfloat) *u );
  1087. }
  1088.  
  1089. static void
  1090. _tnl_EvalCoord2f( GLfloat u, GLfloat v )
  1091. {
  1092.    GET_IMMEDIATE;
  1093.    EVALCOORD2( IM, u, v );
  1094. }
  1095.  
  1096. static void
  1097. _tnl_EvalCoord2fv( const GLfloat *u )
  1098. {
  1099.    GET_IMMEDIATE;
  1100.    EVALCOORD2( IM, u[0], u[1] );
  1101. }
  1102.  
  1103.  
  1104. static void
  1105. _tnl_EvalPoint1( GLint i )
  1106. {
  1107.    GET_IMMEDIATE;
  1108.    EVALPOINT1( IM, (GLfloat) i );
  1109. }
  1110.  
  1111.  
  1112. static void
  1113. _tnl_EvalPoint2( GLint i, GLint j )
  1114. {
  1115.    GET_IMMEDIATE;
  1116.    EVALPOINT2( IM, (GLfloat) i, (GLfloat) j );
  1117. }
  1118.  
  1119.  
  1120. /* Need to use the default array-elt outside begin/end for strict
  1121.  * conformance.
  1122.  */
  1123. #define ARRAY_ELT( IM, i )            \
  1124. {                        \
  1125.    GLuint count = IM->Count;            \
  1126.    IM->Elt[count] = i;                \
  1127.    IM->Flag[count] &= IM->ArrayEltFlags;    \
  1128.    IM->Flag[count] |= VERT_BIT_ELT;        \
  1129.    IM->FlushElt = IM->ArrayEltFlush;        \
  1130.    IM->Count += IM->ArrayEltIncr;        \
  1131.    if (IM->Count == IMM_MAXDATA)        \
  1132.       _tnl_flush_immediate( NULL, IM );        \
  1133. }
  1134.  
  1135.  
  1136. static void
  1137. _tnl_ArrayElement( GLint i )
  1138. {
  1139.    GET_IMMEDIATE;
  1140.    ARRAY_ELT( IM, i );
  1141. }
  1142.  
  1143.  
  1144. /* Internal functions.  These are safe to use providing either:
  1145.  *
  1146.  *    - It is determined that a display list is not being compiled, or
  1147.  *    if so that these commands won't be compiled into the list (see
  1148.  *    t_eval.c for an example).
  1149.  *
  1150.  *    - _tnl_hard_begin() is used instead of _tnl_[bB]egin, and tested
  1151.  *    for a GL_TRUE return value.  See _tnl_Rectf, below.
  1152.  */
  1153. void
  1154. _tnl_eval_coord1f( GLcontext *CC, GLfloat u )
  1155. {
  1156.    struct immediate *i = TNL_CURRENT_IM(CC);
  1157.    EVALCOORD1( i, u );
  1158. }
  1159.  
  1160. void
  1161. _tnl_eval_coord2f( GLcontext *CC, GLfloat u, GLfloat v )
  1162. {
  1163.    struct immediate *i = TNL_CURRENT_IM(CC);
  1164.    EVALCOORD2( i, u, v );
  1165. }
  1166.  
  1167.  
  1168.  
  1169.  
  1170. /*
  1171.  * NV_vertex_program
  1172.  */
  1173.  
  1174. static void
  1175. _tnl_VertexAttrib4fNV( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
  1176. {
  1177.    if (index < 16) {
  1178.       GET_IMMEDIATE;
  1179.       const GLuint count = IM->Count;
  1180.       GLfloat *attrib = IM->Attrib[index][count];
  1181.       ASSIGN_4V(attrib, x, y, z, w);
  1182.       IM->Flag[count] |= (1 << index);
  1183.       if (index == 0) {
  1184.          IM->Count++;
  1185.          if (count == IMM_MAXDATA - 1)
  1186.             _tnl_flush_immediate( NULL, IM );
  1187.       }
  1188.    }
  1189.    else {
  1190.       GET_CURRENT_CONTEXT(ctx);
  1191.       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
  1192.    }
  1193. }   
  1194.  
  1195. static void
  1196. _tnl_VertexAttrib4fvNV( GLuint index, const GLfloat *v )
  1197. {
  1198.    if (index < 16) {
  1199.       GET_IMMEDIATE;
  1200.       const GLuint count = IM->Count;
  1201.       GLfloat *attrib = IM->Attrib[index][count];
  1202.       COPY_4V(attrib, v);
  1203.       IM->Flag[count] |= (1 << index);
  1204.       if (index == 0) {
  1205.          IM->Count++;
  1206.          if (count == IMM_MAXDATA - 1)
  1207.             _tnl_flush_immediate( NULL, IM );
  1208.       }
  1209.    }
  1210.    else {
  1211.       GET_CURRENT_CONTEXT(ctx);
  1212.       _mesa_error(ctx, GL_INVALID_VALUE, "glVertexAttribNV(index > 15)");
  1213.    }
  1214. }   
  1215.  
  1216.  
  1217. /* Execute a glRectf() function.  _tnl_hard_begin() ensures the check
  1218.  * on outside_begin_end is executed even in compiled lists.  These
  1219.  * vertices can now participate in the same immediate as regular ones,
  1220.  * even in most display lists.  
  1221.  */
  1222. static void
  1223. _tnl_Rectf( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
  1224. {
  1225.    GET_CURRENT_CONTEXT(ctx);
  1226.  
  1227.    if (_tnl_hard_begin( ctx, GL_QUADS )) {
  1228.       glVertex2f( x1, y1 );
  1229.       glVertex2f( x2, y1 );
  1230.       glVertex2f( x2, y2 );
  1231.       glVertex2f( x1, y2 );
  1232.       glEnd();
  1233.    }
  1234. }
  1235.  
  1236. static void
  1237. _tnl_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
  1238. {
  1239.    GET_CURRENT_CONTEXT(ctx);
  1240.    TNLcontext *tnl = TNL_CONTEXT(ctx);
  1241.    struct immediate *IM = TNL_CURRENT_IM(ctx);
  1242.    GLuint count = IM->Count;
  1243.    struct gl_material *mat;
  1244.    GLuint bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, "Materialfv");
  1245.  
  1246.    if (bitmask == 0)
  1247.       return;
  1248.    
  1249.    if (MESA_VERBOSE & VERBOSE_API)
  1250.       _mesa_debug(ctx, "_tnl_Materialfv\n");
  1251.  
  1252.    if (tnl->IsolateMaterials &&
  1253.        !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
  1254.    {
  1255.       _tnl_flush_immediate( ctx, IM );      
  1256.       IM = TNL_CURRENT_IM(ctx);
  1257.       count = IM->Count;
  1258.    }
  1259.  
  1260.    if (!(IM->Flag[count] & VERT_BIT_MATERIAL)) {
  1261.       if (!IM->Material) {
  1262.      IM->Material = (struct gl_material (*)[2])
  1263.             MALLOC( sizeof(struct gl_material) * IMM_SIZE * 2 );
  1264.      IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * IMM_SIZE );
  1265.      IM->MaterialMask[IM->LastMaterial] = 0;
  1266.       }
  1267.       else if (IM->MaterialOrMask & ~bitmask) {
  1268.      _mesa_copy_material_pairs( IM->Material[count],
  1269.                     IM->Material[IM->LastMaterial],
  1270.                     IM->MaterialOrMask & ~bitmask );
  1271.       }
  1272.  
  1273.       IM->Flag[count] |= VERT_BIT_MATERIAL;
  1274.       IM->MaterialMask[count] = 0;
  1275.       IM->MaterialAndMask &= IM->MaterialMask[IM->LastMaterial];
  1276.       IM->LastMaterial = count;
  1277.    }
  1278.  
  1279.    IM->MaterialOrMask |= bitmask;
  1280.    IM->MaterialMask[count] |= bitmask;
  1281.    mat = IM->Material[count];
  1282.  
  1283.    if (bitmask & FRONT_AMBIENT_BIT) {
  1284.       COPY_4FV( mat[0].Ambient, params );
  1285.    }
  1286.    if (bitmask & BACK_AMBIENT_BIT) {
  1287.       COPY_4FV( mat[1].Ambient, params );
  1288.    }
  1289.    if (bitmask & FRONT_DIFFUSE_BIT) {
  1290.       COPY_4FV( mat[0].Diffuse, params );
  1291.    }
  1292.    if (bitmask & BACK_DIFFUSE_BIT) {
  1293.       COPY_4FV( mat[1].Diffuse, params );
  1294.    }
  1295.    if (bitmask & FRONT_SPECULAR_BIT) {
  1296.       COPY_4FV( mat[0].Specular, params );
  1297.    }
  1298.    if (bitmask & BACK_SPECULAR_BIT) {
  1299.       COPY_4FV( mat[1].Specular, params );
  1300.    }
  1301.    if (bitmask & FRONT_EMISSION_BIT) {
  1302.       COPY_4FV( mat[0].Emission, params );
  1303.    }
  1304.    if (bitmask & BACK_EMISSION_BIT) {
  1305.       COPY_4FV( mat[1].Emission, params );
  1306.    }
  1307.    if (bitmask & FRONT_SHININESS_BIT) {
  1308.       GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
  1309.       mat[0].Shininess = shininess;
  1310.    }
  1311.    if (bitmask & BACK_SHININESS_BIT) {
  1312.       GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
  1313.       mat[1].Shininess = shininess;
  1314.    }
  1315.    if (bitmask & FRONT_INDEXES_BIT) {
  1316.       mat[0].AmbientIndex = params[0];
  1317.       mat[0].DiffuseIndex = params[1];
  1318.       mat[0].SpecularIndex = params[2];
  1319.    }
  1320.    if (bitmask & BACK_INDEXES_BIT) {
  1321.       mat[1].AmbientIndex = params[0];
  1322.       mat[1].DiffuseIndex = params[1];
  1323.       mat[1].SpecularIndex = params[2];
  1324.    }
  1325.  
  1326.    if (tnl->IsolateMaterials && 
  1327.        !(IM->BeginState & VERT_BEGIN_1)) /* heuristic */
  1328.    {
  1329.       _tnl_flush_immediate( ctx, IM );
  1330.    }
  1331. }
  1332.  
  1333. void _tnl_imm_vtxfmt_init( GLcontext *ctx )
  1334. {
  1335.    GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);
  1336.  
  1337.    /* All begin/end operations are handled by this vertex format:
  1338.     */
  1339.    vfmt->ArrayElement = _tnl_ArrayElement;
  1340.    vfmt->Begin = _tnl_Begin;
  1341.    vfmt->Color3f = _tnl_Color3f;
  1342.    vfmt->Color3fv = _tnl_Color3fv;
  1343.    vfmt->Color3ub = _tnl_Color3ub;
  1344.    vfmt->Color3ubv = _tnl_Color3ubv;
  1345.    vfmt->Color4f = _tnl_Color4f;
  1346.    vfmt->Color4fv = _tnl_Color4fv;
  1347.    vfmt->Color4ub = _tnl_Color4ub;
  1348.    vfmt->Color4ubv = _tnl_Color4ubv;
  1349.    vfmt->EdgeFlag = _tnl_EdgeFlag;
  1350.    vfmt->EdgeFlagv = _tnl_EdgeFlagv;
  1351.    vfmt->End = _tnl_End;
  1352.    vfmt->EvalCoord1f = _tnl_EvalCoord1f;
  1353.    vfmt->EvalCoord1fv = _tnl_EvalCoord1fv;
  1354.    vfmt->EvalCoord2f = _tnl_EvalCoord2f;
  1355.    vfmt->EvalCoord2fv = _tnl_EvalCoord2fv;
  1356.    vfmt->EvalPoint1 = _tnl_EvalPoint1;
  1357.    vfmt->EvalPoint2 = _tnl_EvalPoint2;
  1358.    vfmt->FogCoordfEXT = _tnl_FogCoordfEXT;
  1359.    vfmt->FogCoordfvEXT = _tnl_FogCoordfvEXT;
  1360.    vfmt->Indexi = _tnl_Indexi;
  1361.    vfmt->Indexiv = _tnl_Indexiv;
  1362.    vfmt->Materialfv = _tnl_Materialfv;
  1363.    vfmt->MultiTexCoord1fARB = _tnl_MultiTexCoord1fARB;
  1364.    vfmt->MultiTexCoord1fvARB = _tnl_MultiTexCoord1fvARB;
  1365.    vfmt->MultiTexCoord2fARB = _tnl_MultiTexCoord2fARB;
  1366.    vfmt->MultiTexCoord2fvARB = _tnl_MultiTexCoord2fvARB;
  1367.    vfmt->MultiTexCoord3fARB = _tnl_MultiTexCoord3fARB;
  1368.    vfmt->MultiTexCoord3fvARB = _tnl_MultiTexCoord3fvARB;
  1369.    vfmt->MultiTexCoord4fARB = _tnl_MultiTexCoord4fARB;
  1370.    vfmt->MultiTexCoord4fvARB = _tnl_MultiTexCoord4fvARB;
  1371.    vfmt->Normal3f = _tnl_Normal3f;
  1372.    vfmt->Normal3fv = _tnl_Normal3fv;
  1373.    vfmt->SecondaryColor3fEXT = _tnl_SecondaryColor3fEXT;
  1374.    vfmt->SecondaryColor3fvEXT = _tnl_SecondaryColor3fvEXT;
  1375.    vfmt->SecondaryColor3ubEXT = _tnl_SecondaryColor3ubEXT;
  1376.    vfmt->SecondaryColor3ubvEXT = _tnl_SecondaryColor3ubvEXT;
  1377.    vfmt->TexCoord1f = _tnl_TexCoord1f;
  1378.    vfmt->TexCoord1fv = _tnl_TexCoord1fv;
  1379.    vfmt->TexCoord2f = _tnl_TexCoord2f;
  1380.    vfmt->TexCoord2fv = _tnl_TexCoord2fv;
  1381.    vfmt->TexCoord3f = _tnl_TexCoord3f;
  1382.    vfmt->TexCoord3fv = _tnl_TexCoord3fv;
  1383.    vfmt->TexCoord4f = _tnl_TexCoord4f;
  1384.    vfmt->TexCoord4fv = _tnl_TexCoord4fv;
  1385.    vfmt->Vertex2f = _tnl_Vertex2f;
  1386.    vfmt->Vertex2fv = _tnl_Vertex2fv;
  1387.    vfmt->Vertex3f = _tnl_Vertex3f;
  1388.    vfmt->Vertex3fv = _tnl_Vertex3fv;
  1389.    vfmt->Vertex4f = _tnl_Vertex4f;
  1390.    vfmt->Vertex4fv = _tnl_Vertex4fv;
  1391.    vfmt->VertexAttrib4fNV = _tnl_VertexAttrib4fNV;
  1392.    vfmt->VertexAttrib4fvNV = _tnl_VertexAttrib4fvNV;
  1393.  
  1394.    /* Outside begin/end functions (from t_varray.c, t_eval.c, ...):
  1395.     */
  1396.    vfmt->Rectf = _tnl_Rectf;
  1397.  
  1398.    /* Just use the core function:
  1399.     */
  1400.    vfmt->CallList = _mesa_CallList;
  1401.  
  1402.    vfmt->prefer_float_colors = GL_FALSE;
  1403. }
  1404.