Simplify the pipeline_stage structure
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 22 Apr 2005 12:51:19 +0000 (12:51 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 22 Apr 2005 12:51:19 +0000 (12:51 +0000)
- remove input/output fields, input tracking removed.
- remove state fields, the validate function now called
  on every statechange.
- add an explicit 'create' function.

Add in code to build vertex program to implement current t&l state.  Still
disabled, but turn on with a #define in t_vp_build.h.

24 files changed:
src/mesa/main/mtypes.h
src/mesa/sources
src/mesa/tnl/t_array_api.c
src/mesa/tnl/t_array_import.c
src/mesa/tnl/t_context.c
src/mesa/tnl/t_context.h
src/mesa/tnl/t_pipeline.c
src/mesa/tnl/t_pipeline.h
src/mesa/tnl/t_save_playback.c
src/mesa/tnl/t_vb_arbprogram.c
src/mesa/tnl/t_vb_cull.c
src/mesa/tnl/t_vb_fog.c
src/mesa/tnl/t_vb_light.c
src/mesa/tnl/t_vb_lighttmp.h
src/mesa/tnl/t_vb_normals.c
src/mesa/tnl/t_vb_points.c
src/mesa/tnl/t_vb_program.c
src/mesa/tnl/t_vb_render.c
src/mesa/tnl/t_vb_texgen.c
src/mesa/tnl/t_vb_texmat.c
src/mesa/tnl/t_vb_vertex.c
src/mesa/tnl/t_vp_build.c
src/mesa/tnl/t_vp_build.h [new file with mode: 0644]
src/mesa/tnl/t_vtx_exec.c

index ac9fc87..4ece984 100644 (file)
@@ -2649,6 +2649,9 @@ struct __GLcontextRec
    struct gl_fragment_program_state FragmentProgram;  /**< GL_NV_fragment_program */
    struct gl_ati_fragment_shader_state ATIFragmentShader;  /**< GL_ATI_fragment_shader */
 
+   struct fragment_program _TexEnvProgram;     /**< Texture state as fragment program */
+   struct vertex_program _TnlProgram;          /**< Fixed func TNL state as vertex program */
+
    struct gl_occlusion_state Occlusion;  /**< GL_ARB_occlusion_query */
 
    struct gl_shader_objects_state ShaderObjects;       /* GL_ARB_shader_objects */
index 1a68057..e461840 100644 (file)
@@ -118,16 +118,18 @@ TNL_SOURCES = \
        tnl/t_save_api.c \
        tnl/t_save_loopback.c \
        tnl/t_save_playback.c \
-       tnl/t_vb_cull.c \
-       tnl/t_vb_fog.c \
-       tnl/t_vb_light.c \
-       tnl/t_vb_normals.c \
-       tnl/t_vb_points.c \
+       tnl/t_vb_arbprogram.c \
        tnl/t_vb_program.c \
        tnl/t_vb_render.c \
        tnl/t_vb_texgen.c \
        tnl/t_vb_texmat.c \
        tnl/t_vb_vertex.c \
+       tnl/t_vb_cull.c \
+       tnl/t_vb_fog.c \
+       tnl/t_vb_light.c \
+       tnl/t_vb_normals.c \
+       tnl/t_vb_points.c \
+       tnl/t_vp_build.c \
        tnl/t_vertex.c \
        tnl/t_vertex_c.c \
        tnl/t_vertex_codegen.c \
@@ -137,6 +139,8 @@ TNL_SOURCES = \
        tnl/t_vtx_eval.c \
        tnl/t_vtx_exec.c 
 
+
+
 SHADER_SOURCES = \
        shader/arbfragparse.c \
        shader/arbprogparse.c \
index 3aa91f9..c8cd22f 100644 (file)
@@ -91,9 +91,6 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
    struct tnl_prim prim;
    FLUSH_CURRENT( ctx, 0 );
    
-   if (tnl->pipeline.build_state_changes)
-      _tnl_validate_pipeline( ctx );
-
    _tnl_vb_bind_arrays( ctx, 0, max_index );
 
    tnl->vb.Primitive = &prim;
@@ -104,20 +101,7 @@ static void _tnl_draw_range_elements( GLcontext *ctx, GLenum mode,
 
    tnl->vb.Elts = (GLuint *)indices;
 
-   if (ctx->Array.LockCount)
-      tnl->Driver.RunPipeline( ctx );
-   else {
-      /* The lower 16 bits represent the conventional arrays while the
-       * upper 16 bits represent the generic arrays.  OR those bits
-       * together to indicate which vertex attribs are in effect.
-       */
-      GLuint enabledArrays = ctx->Array._Enabled | (ctx->Array._Enabled >> 16);
-      /* Note that arrays may have changed before/after execution.
-       */
-      tnl->pipeline.run_input_changes |= enabledArrays & 0xffff;
-      tnl->Driver.RunPipeline( ctx );
-      tnl->pipeline.run_input_changes |= enabledArrays & 0xffff;
-   }
+   tnl->Driver.RunPipeline( ctx );
 }
 
 
@@ -131,7 +115,6 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
    GET_CURRENT_CONTEXT(ctx);
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    GLuint thresh = (ctx->Driver.NeedFlush & FLUSH_STORED_VERTICES) ? 30 : 10;
-   GLuint enabledArrays;
    
    if (MESA_VERBOSE & VERBOSE_API)
       _mesa_debug(NULL, "_tnl_DrawArrays %d %d\n", start, count); 
@@ -141,9 +124,6 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
    if (!_mesa_validate_DrawArrays( ctx, mode, start, count ))
       return;
 
-   if (tnl->pipeline.build_state_changes)
-      _tnl_validate_pipeline( ctx );
-
    assert(!ctx->CompileFlag);
 
    if (!ctx->Array.LockCount && (GLuint) count < thresh) {
@@ -266,16 +246,7 @@ _tnl_DrawArrays(GLenum mode, GLint start, GLsizei count)
         tnl->vb.Primitive[0].count = nr + minimum;
         tnl->vb.PrimitiveCount = 1;
 
-         /* The lower 16 bits represent the conventional arrays while the
-          * upper 16 bits represent the generic arrays.  OR those bits
-          * together to indicate which vertex attribs are in effect.
-          */
-         enabledArrays = ctx->Array._Enabled | (ctx->Array._Enabled >> 16);
-         /* Note that arrays may have changed before/after execution.
-          */
-        tnl->pipeline.run_input_changes |= enabledArrays;
         tnl->Driver.RunPipeline( ctx );
-        tnl->pipeline.run_input_changes |= enabledArrays;
       }
    }
 }
index 00a933e..09b3013 100644 (file)
@@ -244,7 +244,6 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   GLuint inputs = tnl->pipeline.inputs;
    struct tnl_vertex_arrays *tmp = &tnl->array_inputs;
    GLuint i, index;
 
@@ -269,77 +268,61 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
       }
       /* use conventional arrays... */
       else if (index == VERT_ATTRIB_POS) {
-         if (inputs & _TNL_BIT_POS) {
-            _tnl_import_vertex( ctx, 0, 0 );
-            tmp->Obj.count = VB->Count;
-            VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
-         }
+        _tnl_import_vertex( ctx, 0, 0 );
+        tmp->Obj.count = VB->Count;
+        VB->AttribPtr[_TNL_ATTRIB_POS] = &tmp->Obj;
       }
       else if (index == VERT_ATTRIB_NORMAL) {
-         if (inputs & _TNL_BIT_NORMAL) {
-            _tnl_import_normal( ctx, 0, 0 );
-            tmp->Normal.count = VB->Count;
-            VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
-         }
+        _tnl_import_normal( ctx, 0, 0 );
+        tmp->Normal.count = VB->Count;
+        VB->AttribPtr[_TNL_ATTRIB_NORMAL] = &tmp->Normal;
       }
       else if (index == VERT_ATTRIB_COLOR0) {
-         if (inputs & _TNL_BIT_COLOR0) {
-            _tnl_import_color( ctx, 0, 0 );
-            tmp->Color.count = VB->Count;
-            VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
-         }
+        _tnl_import_color( ctx, 0, 0 );
+        tmp->Color.count = VB->Count;
+        VB->AttribPtr[_TNL_ATTRIB_COLOR0] = &tmp->Color;
       }
       else if (index == VERT_ATTRIB_COLOR1) {
-         if (inputs & _TNL_BIT_COLOR1) {
-            _tnl_import_secondarycolor( ctx, 0, 0 );
-            tmp->SecondaryColor.count = VB->Count;
-            VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
-         }
+        _tnl_import_secondarycolor( ctx, 0, 0 );
+        tmp->SecondaryColor.count = VB->Count;
+        VB->AttribPtr[_TNL_ATTRIB_COLOR1] = &tmp->SecondaryColor;
       }
       else if (index == VERT_ATTRIB_FOG) {
-         if (inputs & _TNL_BIT_FOG) {
-            _tnl_import_fogcoord( ctx, 0, 0 );
-            tmp->FogCoord.count = VB->Count;
-            VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
-         }
+        _tnl_import_fogcoord( ctx, 0, 0 );
+        tmp->FogCoord.count = VB->Count;
+        VB->AttribPtr[_TNL_ATTRIB_FOG] = &tmp->FogCoord;
       }
       else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
-         if (inputs & _TNL_BITS_TEX_ANY) {
-            for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-               if (inputs & _TNL_BIT_TEX(i)) {
-                  _tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
-                  tmp->TexCoord[i].count = VB->Count;
-                  VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &tmp->TexCoord[i];
-               }
-            }
-         }
+        for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+           _tnl_import_texcoord( ctx, i, GL_FALSE, GL_FALSE );
+           tmp->TexCoord[i].count = VB->Count;
+           VB->AttribPtr[_TNL_ATTRIB_TEX0 + i] = &tmp->TexCoord[i];
+        }
       }
    }
 
    /* odd-ball vertex attributes */
-   if (inputs & _TNL_BIT_INDEX) {
+   {
       _tnl_import_index( ctx, 0, 0 );
       tmp->Index.count = VB->Count;
       VB->AttribPtr[_TNL_ATTRIB_INDEX] = &tmp->Index;
    }
 
-   if (inputs & _TNL_BIT_EDGEFLAG) {
+   {
       _tnl_import_edgeflag( ctx, GL_TRUE, sizeof(GLboolean) );
       VB->EdgeFlag = (GLboolean *) tmp->EdgeFlag;
    }
 
    /* These are constant & can be precalculated:
     */
-   if (inputs & _TNL_BITS_MAT_ANY) {
-      for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
-        tmp->Attribs[i].count = 1;
-        tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
-        tmp->Attribs[i].start = tnl->vtx.current[i];
-        tmp->Attribs[i].size = 4; 
-        tmp->Attribs[i].stride = 0;
-        VB->AttribPtr[i] = &tmp->Attribs[i];
-      }      
-   }
+   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; i < _TNL_ATTRIB_INDEX; i++) {
+      tmp->Attribs[i].count = 1;
+      tmp->Attribs[i].data = (GLfloat (*)[4]) tnl->vtx.current[i];
+      tmp->Attribs[i].start = tnl->vtx.current[i];
+      tmp->Attribs[i].size = 4; 
+      tmp->Attribs[i].stride = 0;
+      VB->AttribPtr[i] = &tmp->Attribs[i];
+   }      
 
 
    /* Legacy pointers -- remove one day.
@@ -357,5 +340,4 @@ void _tnl_vb_bind_arrays( GLcontext *ctx, GLint start, GLint end)
    for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
       VB->TexCoordPtr[i] = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i];
    }
-
 }
index 531e639..ef23784 100644 (file)
@@ -124,7 +124,7 @@ _tnl_CreateContext( GLcontext *ctx )
    tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts;
    tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts;
    tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables;
-   
+
    return GL_TRUE;
 }
 
@@ -156,16 +156,9 @@ _tnl_InvalidateState( GLcontext *ctx, GLuint new_state )
          || !tnl->AllowPixelFog;
    }
 
-   if (new_state & _NEW_ARRAY) {
-      tnl->pipeline.run_input_changes |= ctx->Array.NewState; /* overkill */
-   }
-
    _ae_invalidate_state(ctx, new_state);
 
-   tnl->pipeline.run_state_changes |= new_state;
-   tnl->pipeline.build_state_changes |= (new_state &
-                                        tnl->pipeline.build_state_trigger);
-
+   tnl->pipeline.new_state |= new_state;
    tnl->vtx.eval.new_state |= new_state;
 
    /* Calculate tnl->render_inputs:
@@ -217,7 +210,6 @@ _tnl_wakeup_exec( GLcontext *ctx )
    /* Assume we haven't been getting state updates either:
     */
    _tnl_InvalidateState( ctx, ~0 );
-   tnl->pipeline.run_input_changes = ~0;
 
    if (ctx->Light.ColorMaterialEnabled) {
       _mesa_update_color_material( ctx, 
index 5adde5f..905933a 100644 (file)
 
 #define MAX_PIPELINE_STAGES     30
 
-
 /*
  * Note: The first attributes match the VERT_ATTRIB_* definitions
  * in mtypes.h.  However, the tnl module has additional attributes
  * for materials, color indexes, edge flags, etc.
  */
-/* Note: These are currently being used to define both inputs and
- * outputs from the tnl pipeline.  A better solution (which would also
- * releive the congestion to slightly prolong the life of the bitmask
- * below) is to have the fixed function pipeline populate a set of
- * arrays named after those produced by the vertex program stage, and
- * have the rest the mesa backend work on those.
+/* Although it's nice to use these as bit indexes in a DWORD flag, we
+ * could manage without if necessary.  Another limit currently is the
+ * number of bits allocated for these numbers in places like vertex
+ * program instruction formats and register layouts.
  */
 enum {
        _TNL_ATTRIB_POS = 0,
@@ -463,43 +460,23 @@ struct vertex_buffer
 struct tnl_pipeline_stage
 {
    const char *name;
-   GLuint check_state;         /* All state referenced in check() --
-                                * When is the pipeline_stage struct
-                                * itself invalidated?  Must be
-                                * constant.
-                                */
-
-   /* Usually constant or set by the 'check' callback:
-    */
-   GLuint run_state;           /* All state referenced in run() --
-                                * When is the cached output of the
-                                * stage invalidated?
-                                */
-
-   GLboolean active;           /* True if runnable in current state */
-   GLuint inputs;              /* VERT_* inputs to the stage */
-   GLuint outputs;             /* VERT_* outputs of the stage */
-
-   /* Set in _tnl_run_pipeline():
-    */
-   GLuint changed_inputs;      /* Generated value -- inputs to the
-                                * stage that have changed since last
-                                * call to 'run'.
-                                */
-
 
    /* Private data for the pipeline stage:
     */
    void *privatePtr;
 
-   /* Free private data.  May not be null.
+   /* Allocate private data
+    */
+   GLboolean (*create)( GLcontext *ctx, struct tnl_pipeline_stage * );
+
+   /* Free private data.
     */
    void (*destroy)( struct tnl_pipeline_stage * );
 
-   /* Called from _tnl_validate_pipeline().  Must update all fields in
-    * the pipeline_stage struct for the current state.
+   /* Called on any statechange or input array size change or
+    * input array change to/from zero stride.
     */
-   void (*check)( GLcontext *ctx, struct tnl_pipeline_stage * );
+   void (*validate)( GLcontext *ctx, struct tnl_pipeline_stage * );
 
    /* Called from _tnl_run_pipeline().  The stage.changed_inputs value
     * encodes all inputs to thee struct which have changed.  If
@@ -512,15 +489,18 @@ struct tnl_pipeline_stage
    GLboolean (*run)( GLcontext *ctx, struct tnl_pipeline_stage * );
 };
 
+
+
 /** Contains the array of all pipeline stages.
- * The default values are defined at the end of t_pipeline.c */
+ * The default values are defined at the end of t_pipeline.c 
+ */
 struct tnl_pipeline {
-   GLuint build_state_trigger;   /**< state changes which require build */
-   GLuint build_state_changes;    /**< state changes since last build */
-   GLuint run_state_changes;     /**< state changes since last run */
-   GLuint run_input_changes;     /**< VERT_* changes since last run */
-   GLuint inputs;                /**< VERT_* inputs to pipeline */
-   /** This array has to end with a NULL-pointer. */
+   
+   GLuint last_attrib_stride[_TNL_ATTRIB_MAX];
+   GLuint last_attrib_size[_TNL_ATTRIB_MAX];
+   GLuint input_changes;
+   GLuint new_state;
+
    struct tnl_pipeline_stage stages[MAX_PIPELINE_STAGES+1];
    GLuint nr_stages;
 };
index 1e9b686..9141219 100644 (file)
 
 #include "t_context.h"
 #include "t_pipeline.h"
-
+#include "t_vp_build.h"
 
 void _tnl_install_pipeline( GLcontext *ctx,
                            const struct tnl_pipeline_stage **stages )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct tnl_pipeline *pipe = &tnl->pipeline;
    GLuint i;
 
-   ASSERT(pipe->nr_stages == 0);
-
-   pipe->run_state_changes = ~0;
-   pipe->run_input_changes = ~0;
-   pipe->build_state_changes = ~0;
-   pipe->build_state_trigger = 0;
-   pipe->inputs = 0;
+   tnl->pipeline.new_state = ~0;
 
    /* Create a writeable copy of each stage.
     */
    for (i = 0 ; i < MAX_PIPELINE_STAGES && stages[i] ; i++) {
-      MEMCPY( &pipe->stages[i], stages[i], sizeof( **stages ));
-      pipe->build_state_trigger |= pipe->stages[i].check_state;
+      struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i];
+      MEMCPY(s, stages[i], sizeof(*s));
+      if (s->create)
+        s->create(ctx, s);
    }
 
-   MEMSET( &pipe->stages[i], 0, sizeof( **stages ));
-
-   pipe->nr_stages = i;
+   tnl->pipeline.nr_stages = i;
 }
 
 void _tnl_destroy_pipeline( GLcontext *ctx )
@@ -71,100 +64,89 @@ void _tnl_destroy_pipeline( GLcontext *ctx )
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    GLuint i;
 
-   for (i = 0 ; i < tnl->pipeline.nr_stages ; i++)
-      tnl->pipeline.stages[i].destroy( &tnl->pipeline.stages[i] );
+   for (i = 0 ; i < tnl->pipeline.nr_stages ; i++) {
+      struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i];
+      if (s->destroy)
+        s->destroy(s);
+   }
 
    tnl->pipeline.nr_stages = 0;
 }
 
-/* TODO: merge validate with run.
- */
-void _tnl_validate_pipeline( GLcontext *ctx )
+
+
+static GLuint check_input_changes( GLcontext *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct tnl_pipeline *pipe = &tnl->pipeline;
-   struct tnl_pipeline_stage *s = pipe->stages;
-   GLuint newstate = pipe->build_state_changes;
-   GLuint generated = 0;
-   GLuint changed_inputs = 0;
-
-   pipe->inputs = 0;
-   pipe->build_state_changes = 0;
-
-   for ( ; s->check ; s++) {
-
-      s->changed_inputs |= s->inputs & changed_inputs;
-
-      if (s->check_state & newstate) {
-        if (s->active) {
-           GLuint old_outputs = s->outputs;
-           s->check(ctx, s);
-           if (!s->active)
-              changed_inputs |= old_outputs;
-        }
-        else
-           s->check(ctx, s);
+   GLuint i;
+   
+   for (i = 0; i < _TNL_ATTRIB_EDGEFLAG; i++) {
+      if (tnl->vb.AttribPtr[i]->size != tnl->pipeline.last_attrib_size[i] ||
+         tnl->vb.AttribPtr[i]->stride != tnl->pipeline.last_attrib_stride[i]) {
+        tnl->pipeline.last_attrib_size[i] = tnl->vb.AttribPtr[i]->size;
+        tnl->pipeline.last_attrib_stride[i] = tnl->vb.AttribPtr[i]->stride;
+        tnl->pipeline.input_changes |= 1<<i;
       }
+   }
+
+   return tnl->pipeline.input_changes;
+}
+
 
-      if (s->active) {
-        pipe->inputs |= s->inputs & ~generated;
-        generated |= s->outputs;
+static void check_output_changes( GLcontext *ctx )
+{
+#if 0
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   
+   for (i = 0; i < VERT_RESULT_MAX; i++) {
+      if (tnl->vb.ResultPtr[i]->size != tnl->last_result_size[i] ||
+         tnl->vb.ResultPtr[i]->stride != tnl->last_result_stride[i]) {
+        tnl->last_result_size[i] = tnl->vb.ResultPtr[i]->size;
+        tnl->last_result_stride[i] = tnl->vb.ResultPtr[i]->stride;
+        tnl->pipeline.output_changes |= 1<<i;
       }
    }
-}
 
+   if (tnl->pipeline.output_changes) 
+      tnl->Driver.NotifyOutputChanges( ctx, tnl->pipeline.output_changes );
+#endif
+}
 
 
 void _tnl_run_pipeline( GLcontext *ctx )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
-   struct tnl_pipeline *pipe = &tnl->pipeline;
-   struct tnl_pipeline_stage *s = pipe->stages;
-   GLuint changed_state = pipe->run_state_changes;
-   GLuint changed_inputs = pipe->run_input_changes;
-   GLboolean running = GL_TRUE;
-#ifdef HAVE_FAST_MATH
    unsigned short __tmp;
-#endif
+   GLuint i;
 
    if (!tnl->vb.Count)
       return;
 
-   pipe->run_state_changes = 0;
-   pipe->run_input_changes = 0;
-
-   /* Done elsewhere.
-    */
-   ASSERT(pipe->build_state_changes == 0);
-
-#ifdef HAVE_FAST_MATH
-   START_FAST_MATH(__tmp);
-#endif
-
-   /* If something changes in the pipeline, tag all subsequent stages
-    * using this value for recalculation.  Inactive stages have their
-    * state and inputs examined to try to keep cached data alive over
-    * state-changes.
+   /* Check for changed input sizes or change in stride to/from zero
+    * (ie const or non-const).
     */
-   for ( ; s->run ; s++) {
-      s->changed_inputs |= s->inputs & changed_inputs;
-
-      if (s->run_state & changed_state)
-        s->changed_inputs = s->inputs;
+   if (check_input_changes( ctx ) || tnl->pipeline.new_state) {
+      for (i = 0; i < tnl->pipeline.nr_stages ; i++) {
+        struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i];
+        if (s->validate)
+           s->validate( ctx, s );
+      }
+      
+      tnl->pipeline.new_state = 0;
+      tnl->pipeline.input_changes = 0;
+      check_output_changes( ctx );
+   }
 
-      if (s->active && running) {
-        if (s->changed_inputs)
-           changed_inputs |= s->outputs;
 
-        running = s->run( ctx, s );
+   START_FAST_MATH(__tmp);
 
-        s->changed_inputs = 0;
-      }
+   for (i = 0; i < tnl->pipeline.nr_stages ; i++) {
+      struct tnl_pipeline_stage *s = &tnl->pipeline.stages[i];
+      if (!s->run( ctx, s ))
+        break;
    }
 
-#ifdef HAVE_FAST_MATH
    END_FAST_MATH(__tmp);
-#endif
 }
 
 
@@ -201,6 +183,9 @@ void _tnl_run_pipeline( GLcontext *ctx )
  * case, if it becomes necessary to do so.
  */
 const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
+#if TNL_FIXED_FUNCTION_PROGRAM
+   &_tnl_arb_vertex_program_stage,
+#else
    &_tnl_vertex_transform_stage,
    &_tnl_normal_transform_stage,
    &_tnl_lighting_stage,
@@ -211,6 +196,7 @@ const struct tnl_pipeline_stage *_tnl_default_pipeline[] = {
 #if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program)
    &_tnl_vertex_program_stage,
 #endif
+#endif
    &_tnl_render_stage,
    NULL 
 };
index 9efb5b8..a9d8c7e 100644 (file)
@@ -36,8 +36,6 @@
 
 extern void _tnl_run_pipeline( GLcontext *ctx );
 
-extern void _tnl_validate_pipeline( GLcontext *ctx );
-
 extern void _tnl_destroy_pipeline( GLcontext *ctx );
 
 extern void _tnl_install_pipeline( GLcontext *ctx,
@@ -54,6 +52,7 @@ extern const struct tnl_pipeline_stage _tnl_fog_coordinate_stage;
 extern const struct tnl_pipeline_stage _tnl_texgen_stage;
 extern const struct tnl_pipeline_stage _tnl_texture_transform_stage;
 extern const struct tnl_pipeline_stage _tnl_point_attenuation_stage;
+extern const struct tnl_pipeline_stage _tnl_arb_vertex_program_stage;
 extern const struct tnl_pipeline_stage _tnl_vertex_program_stage;
 extern const struct tnl_pipeline_stage _tnl_render_stage;
 
index c271ba7..995964c 100644 (file)
@@ -204,16 +204,9 @@ void _tnl_playback_vertex_list( GLcontext *ctx, void *data )
          return;
       }
 
-      if (tnl->pipeline.build_state_changes)
-        _tnl_validate_pipeline( ctx );
-
       _tnl_bind_vertex_list( ctx, node );
 
-      /* Invalidate all stored data before and after run:
-       */
-      tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
       tnl->Driver.RunPipeline( ctx );
-      tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
    }
 
    /* Copy to current?
index af91546..d541293 100644 (file)
@@ -40,6 +40,7 @@
 #include "math/m_translate.h"
 #include "t_context.h"
 #include "t_pipeline.h"
+#include "t_vp_build.h"
 
 
 
@@ -416,7 +417,7 @@ static void do_PAR( struct arb_vp_machine *m, union instruction op )
 }
 
 
-#define RELADDR_MASK MAX_NV_VERTEX_PROGRAM_PARAMS
+#define RELADDR_MASK (MAX_NV_VERTEX_PROGRAM_PARAMS-1)
 
 static void do_PRL( struct arb_vp_machine *m, union instruction op )
 {
@@ -1458,17 +1459,25 @@ static void
 validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage )
 {
    struct arb_vp_machine *m = ARB_VP_MACHINE(stage);
-   struct vertex_program *program = (ctx->VertexProgram._Enabled ?
-                                    ctx->VertexProgram.Current :
-                                    &ctx->_TnlProgram);
+   struct vertex_program *program = 
+      (ctx->VertexProgram._Enabled ? ctx->VertexProgram.Current : 0);
 
-   compile_vertex_program( m, program );
+#if TNL_FIXED_FUNCTION_PROGRAM
+   if (!program) {
+      _tnl_UpdateFixedFunctionProgram( ctx );
+      program = &ctx->_TnlProgram;
+   }
+#endif
 
-   /* Grab the state GL state and put into registers:
-    */
-   m->File[PROGRAM_LOCAL_PARAM] = program->Base.LocalParams;
-   m->File[PROGRAM_ENV_PARAM] = ctx->VertexProgram.Parameters;
-   m->File[PROGRAM_STATE_VAR] = 0;
+   if (program) {
+      compile_vertex_program( m, program );
+      
+      /* Grab the state GL state and put into registers:
+       */
+      m->File[PROGRAM_LOCAL_PARAM] = program->Base.LocalParams;
+      m->File[PROGRAM_ENV_PARAM] = ctx->VertexProgram.Parameters;
+      m->File[PROGRAM_STATE_VAR] = 0;
+   }
 }
 
 
@@ -1481,8 +1490,8 @@ validate_vertex_program( GLcontext *ctx, struct tnl_pipeline_stage *stage )
  * Called the first time stage->run is called.  In effect, don't
  * allocate data until the first time the stage is run.
  */
-static void init_vertex_program( GLcontext *ctx,
-                                struct tnl_pipeline_stage *stage )
+static GLboolean init_vertex_program( GLcontext *ctx,
+                                     struct tnl_pipeline_stage *stage )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &(tnl->vb);
@@ -1493,7 +1502,7 @@ static void init_vertex_program( GLcontext *ctx,
    stage->privatePtr = MALLOC(sizeof(*m));
    m = ARB_VP_MACHINE(stage);
    if (!m)
-      return;
+      return GL_FALSE;
 
    /* arb_vertex_machine struct should subsume the VB:
     */
@@ -1509,6 +1518,14 @@ static void init_vertex_program( GLcontext *ctx,
    /* a few other misc allocations */
    _mesa_vector4f_alloc( &m->ndcCoords, 0, size, 32 );
    m->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
+
+
+#if TNL_FIXED_FUNCTION_PROGRAM
+   _mesa_allow_light_in_model( ctx, GL_FALSE );
+#endif
+
+
+   return GL_TRUE;
 }
 
 
index 9527ead..3f12945 100644 (file)
@@ -57,6 +57,10 @@ static GLboolean run_cull_stage( GLcontext *ctx,
    GLuint count = VB->Count;
    GLuint i;
 
+   if (ctx->VertexProgram._Enabled ||
+       !ctx->Transform.CullVertexFlag) 
+      return GL_TRUE;
+
    VB->ClipOrMask &= ~CLIP_CULL_BIT;
    VB->ClipAndMask |= CLIP_CULL_BIT;
 
@@ -81,31 +85,13 @@ static GLboolean run_cull_stage( GLcontext *ctx,
 }
 
 
-static void check_cull( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   stage->active = (!ctx->VertexProgram._Enabled &&
-                   ctx->Transform.CullVertexFlag);
-}
-
-
-static void dtr( struct tnl_pipeline_stage *stage )
-{
-}
-
 
 const struct tnl_pipeline_stage _tnl_vertex_cull_stage =
 {
    "EXT_cull_vertex",
-   _NEW_PROGRAM | 
-   _NEW_TRANSFORM,  
-   _NEW_TRANSFORM,
-   GL_TRUE,                    /* active */
-   _TNL_BIT_NORMAL | 
-   _TNL_BIT_POS,               /* inputs */
-   _TNL_BIT_POS,               /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private data */
-   dtr,                                /* destructor */
-   check_cull,         /* check */
+   NULL,                               /* ctr */
+   NULL,                               /* destructor */
+   NULL,
    run_cull_stage              /* run -- initially set to init */
 };
index 8eb1f78..91c3591 100644 (file)
@@ -148,9 +148,10 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
    struct fog_stage_data *store = FOG_STAGE_DATA(stage);
    GLvector4f *input;
 
-   if (stage->changed_inputs == 0)
+   if (!ctx->Fog.Enabled || ctx->VertexProgram._Enabled)
       return GL_TRUE;
 
+
    if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) {
       /* Fog is computed from vertex or fragment Z values */
       /* source = VB->ObjPtr or VB->EyePtr coords */
@@ -213,17 +214,6 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
 }
 
 
-static void
-check_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage)
-{
-   stage->active = ctx->Fog.Enabled && !ctx->VertexProgram._Enabled;
-
-   if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT)
-      stage->inputs = _TNL_BIT_POS;
-   else
-      stage->inputs = _TNL_BIT_FOG;
-}
-
 
 /* Called the first time stage->run() is invoked.
  */
@@ -243,10 +233,7 @@ alloc_fog_data(GLcontext *ctx, struct tnl_pipeline_stage *stage)
    if (!inited)
       init_static_data();
 
-   /* Now run the stage.
-    */
-   stage->run = run_fog_stage;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
@@ -265,14 +252,9 @@ free_fog_data(struct tnl_pipeline_stage *stage)
 const struct tnl_pipeline_stage _tnl_fog_coordinate_stage =
 {
    "build fog coordinates",    /* name */
-   _NEW_FOG|_NEW_PROGRAM,      /* check_state */
-   _NEW_FOG,                   /* run_state */
-   GL_FALSE,                   /* active? */
-   0,                          /* inputs */
-   _TNL_BIT_FOG,               /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private_data */
+   alloc_fog_data,             /* dtr */
    free_fog_data,              /* dtr */
-   check_fog_stage,            /* check */
-   alloc_fog_data              /* run -- initially set to init. */
+   NULL,               /* check */
+   run_fog_stage               /* run -- initially set to init. */
 };
index 9cf0032..1deab4d 100644 (file)
@@ -180,7 +180,7 @@ static light_func _tnl_light_ci_tab[MAX_LIGHT_FUNC];
 #include "t_vb_lighttmp.h"
 
 
-static void init_lighting( void )
+static void init_lighting_tables( void )
 {
    static int done;
 
@@ -203,33 +203,34 @@ static GLboolean run_lighting( GLcontext *ctx,
    GLvector4f *input = ctx->_NeedEyeCoords ? VB->EyePtr : VB->ObjPtr;
    GLuint idx;
 
+   if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled)
+      return GL_TRUE;
+
    /* Make sure we can talk about position x,y and z:
     */
-   if (stage->changed_inputs & _TNL_BIT_POS) {
-      if (input->size <= 2 && input == VB->ObjPtr) {
-
-        _math_trans_4f( store->Input.data,
-                        VB->ObjPtr->data,
-                        VB->ObjPtr->stride,
-                        GL_FLOAT,
-                        VB->ObjPtr->size,
-                        0,
-                        VB->Count );
-
-        if (input->size <= 2) {
-           /* Clean z.
-            */
-           _mesa_vector4f_clean_elem(&store->Input, VB->Count, 2);
-        }
+   if (input->size <= 2 && input == VB->ObjPtr) {
+
+      _math_trans_4f( store->Input.data,
+                     VB->ObjPtr->data,
+                     VB->ObjPtr->stride,
+                     GL_FLOAT,
+                     VB->ObjPtr->size,
+                     0,
+                     VB->Count );
+
+      if (input->size <= 2) {
+        /* Clean z.
+         */
+        _mesa_vector4f_clean_elem(&store->Input, VB->Count, 2);
+      }
         
-        if (input->size <= 1) {
-           /* Clean y.
-            */
-           _mesa_vector4f_clean_elem(&store->Input, VB->Count, 1);
-        }
-
-        input = &store->Input;
+      if (input->size <= 1) {
+        /* Clean y.
+         */
+        _mesa_vector4f_clean_elem(&store->Input, VB->Count, 1);
       }
+
+      input = &store->Input;
    }
    
    idx = 0;
@@ -255,11 +256,14 @@ static GLboolean run_lighting( GLcontext *ctx,
 
 /* Called in place of do_lighting when the light table may have changed.
  */
-static GLboolean run_validate_lighting( GLcontext *ctx,
+static void validate_lighting( GLcontext *ctx,
                                        struct tnl_pipeline_stage *stage )
 {
    light_func *tab;
 
+   if (!ctx->Light.Enabled || ctx->VertexProgram._Enabled)
+      return;
+
    if (ctx->Visual.rgbMode) {
       if (ctx->Light._NeedVertices) {
         if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
@@ -283,11 +287,6 @@ static GLboolean run_validate_lighting( GLcontext *ctx,
    /* This and the above should only be done on _NEW_LIGHT:
     */
    TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange( ctx );
-
-   /* Now run the stage...
-    */
-   stage->run = run_lighting;
-   return stage->run( ctx, stage );
 }
 
 
@@ -295,8 +294,8 @@ static GLboolean run_validate_lighting( GLcontext *ctx,
 /* Called the first time stage->run is called.  In effect, don't
  * allocate data until the first time the stage is run.
  */
-static GLboolean run_init_lighting( GLcontext *ctx,
-                                   struct tnl_pipeline_stage *stage )
+static GLboolean init_lighting( GLcontext *ctx,
+                               struct tnl_pipeline_stage *stage )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct light_stage_data *store;
@@ -309,7 +308,7 @@ static GLboolean run_init_lighting( GLcontext *ctx,
 
    /* Do onetime init.
     */
-   init_lighting();
+   init_lighting_tables();
 
    _mesa_vector4f_alloc( &store->Input, 0, size, 32 );
    _mesa_vector4f_alloc( &store->LitColor[0], 0, size, 32 );
@@ -329,36 +328,11 @@ static GLboolean run_init_lighting( GLcontext *ctx,
    store->LitIndex[1].size = 1;
    store->LitIndex[1].stride = sizeof(GLfloat);
 
-   /* Now validate the stage derived data...
-    */
-   stage->run = run_validate_lighting;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
 
-/*
- * Check if lighting is enabled.  If so, configure the pipeline stage's
- * type, inputs, and outputs.
- */
-static void check_lighting( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   stage->active = ctx->Light.Enabled && !ctx->VertexProgram._Enabled;
-   if (stage->active) {
-      if (stage->privatePtr)
-        stage->run = run_validate_lighting;
-      stage->inputs = _TNL_BIT_NORMAL|_TNL_BITS_MAT_ANY;
-      if (ctx->Light._NeedVertices)
-        stage->inputs |= _TNL_BIT_POS; 
-      if (ctx->Light.ColorMaterialEnabled)
-        stage->inputs |= _TNL_BIT_COLOR0;
-
-      stage->outputs = _TNL_BIT_COLOR0;
-      if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
-        stage->outputs |= _TNL_BIT_COLOR1;
-   }
-}
-
 
 static void dtr( struct tnl_pipeline_stage *stage )
 {
@@ -380,16 +354,9 @@ static void dtr( struct tnl_pipeline_stage *stage )
 const struct tnl_pipeline_stage _tnl_lighting_stage =
 {
    "lighting",                 /* name */
-   _NEW_LIGHT|_NEW_PROGRAM,    /* recheck */
-   _NEW_LIGHT|_NEW_MODELVIEW,  /* recalc -- modelview dependency
-                                * otherwise not captured by inputs
-                                * (which may be _TNL_BIT_POS) */
-   GL_FALSE,                   /* active? */
-   0,                          /* inputs */
-   0,                          /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private_data */
+   init_lighting,
    dtr,                                /* destroy */
-   check_lighting,             /* check */
-   run_init_lighting           /* run -- initially set to ctr */
+   validate_lighting,
+   run_lighting
 };
index 2d33f71..a27f708 100644 (file)
@@ -82,10 +82,6 @@ static void TAG(light_rgba_spec)( GLcontext *ctx,
    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
 #endif
 
-   /* Side-effects done, can we finish now?
-    */
-   if (stage->changed_inputs == 0)
-      return;
 
    store->LitColor[0].stride = 16;
    store->LitColor[1].stride = 16;
@@ -271,9 +267,6 @@ static void TAG(light_rgba)( GLcontext *ctx,
    sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
 #endif
 
-   if (stage->changed_inputs == 0)
-      return;
-
    store->LitColor[0].stride = 16;
    store->LitColor[1].stride = 16;
 
@@ -461,9 +454,6 @@ static void TAG(light_fast_rgba_single)( GLcontext *ctx,
    VB->ColorPtr[1] = &store->LitColor[1];
 #endif
 
-   if (stage->changed_inputs == 0)
-      return;
-
    if (nr > 1) {
       store->LitColor[0].stride = 16;
       store->LitColor[1].stride = 16;
@@ -574,9 +564,6 @@ static void TAG(light_fast_rgba)( GLcontext *ctx,
    VB->ColorPtr[1] = &store->LitColor[1];
 #endif
 
-   if (stage->changed_inputs == 0)
-      return;
-
    if (nr > 1) {
       store->LitColor[0].stride = 16;
       store->LitColor[1].stride = 16;
@@ -683,9 +670,6 @@ static void TAG(light_ci)( GLcontext *ctx,
    VB->IndexPtr[1] = &store->LitIndex[1];
 #endif
 
-   if (stage->changed_inputs == 0)
-      return;
-
    indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;
 #if IDX & LIGHT_TWOSIDE
    indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;
index f8c73c7..c2202be 100644 (file)
@@ -55,31 +55,30 @@ static GLboolean run_normal_stage( GLcontext *ctx,
 {
    struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+   const GLfloat *lengths;
 
-   ASSERT(store->NormalTransform);
-
-   if (stage->changed_inputs) {
-      /* We can only use the display list's saved normal lengths if we've
-       * got a transformation matrix with uniform scaling.
-       */
-      const GLfloat *lengths;
-      if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE)
-         lengths = NULL;
-      else
-         lengths = VB->NormalLengthPtr;
-
-      store->NormalTransform( ctx->ModelviewMatrixStack.Top,
-                             ctx->_ModelViewInvScale,
-                             VB->NormalPtr,  /* input normals */
-                             lengths,
-                             &store->normal ); /* resulting normals */
-
-      if (VB->NormalPtr->count > 1) {
-        store->normal.stride = 16;
-      }
-      else {
-        store->normal.stride = 0;
-      }
+   if (!store->NormalTransform)
+      return GL_TRUE;
+
+   /* We can only use the display list's saved normal lengths if we've
+    * got a transformation matrix with uniform scaling.
+    */
+   if (ctx->ModelviewMatrixStack.Top->flags & MAT_FLAG_GENERAL_SCALE)
+      lengths = NULL;
+   else
+      lengths = VB->NormalLengthPtr;
+
+   store->NormalTransform( ctx->ModelviewMatrixStack.Top,
+                          ctx->_ModelViewInvScale,
+                          VB->NormalPtr,  /* input normals */
+                          lengths,
+                          &store->normal ); /* resulting normals */
+
+   if (VB->NormalPtr->count > 1) {
+      store->normal.stride = 16;
+   }
+   else {
+      store->normal.stride = 0;
    }
 
    VB->NormalPtr = &store->normal;
@@ -90,12 +89,19 @@ static GLboolean run_normal_stage( GLcontext *ctx,
 }
 
 
-static GLboolean run_validate_normal_stage( GLcontext *ctx,
+static void validate_normal_stage( GLcontext *ctx,
                                            struct tnl_pipeline_stage *stage )
 {
    struct normal_stage_data *store = NORMAL_STAGE_DATA(stage);
 
-
+   if (ctx->VertexProgram._Enabled ||
+       (!ctx->Light.Enabled &&
+       !(ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS))) {
+      store->NormalTransform = NULL;
+      return;
+   }
+      
+   
    if (ctx->_NeedEyeCoords) {
       GLuint transform = NORM_TRANSFORM_NO_ROT;
 
@@ -129,29 +135,9 @@ static GLboolean run_validate_normal_stage( GLcontext *ctx,
         store->NormalTransform = NULL;
       }
    }
-
-   if (store->NormalTransform) {
-      stage->run = run_normal_stage;
-      return stage->run( ctx, stage );
-   } else {
-      stage->active = GL_FALSE;        /* !!! */
-      return GL_TRUE;
-   }
 }
 
 
-static void check_normal_transform( GLcontext *ctx,
-                                   struct tnl_pipeline_stage *stage )
-{
-   stage->active = !ctx->VertexProgram._Enabled &&
-      (ctx->Light.Enabled || (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS));
-
-   /* Don't clobber the initialize function:
-    */
-   if (stage->privatePtr)
-      stage->run = run_validate_normal_stage;
-}
-
 
 static GLboolean alloc_normal_data( GLcontext *ctx,
                                 struct tnl_pipeline_stage *stage )
@@ -164,11 +150,7 @@ static GLboolean alloc_normal_data( GLcontext *ctx,
       return GL_FALSE;
 
    _mesa_vector4f_alloc( &store->normal, 0, tnl->vb.Size, 32 );
-
-   /* Now run the stage.
-    */
-   stage->run = run_validate_normal_stage;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
@@ -183,25 +165,13 @@ static void free_normal_data( struct tnl_pipeline_stage *stage )
    }
 }
 
-#define _TNL_NEW_NORMAL_TRANSFORM        (_NEW_MODELVIEW| \
-                                         _NEW_TRANSFORM| \
-                                         _NEW_PROGRAM| \
-                                          _MESA_NEW_NEED_NORMALS| \
-                                          _MESA_NEW_NEED_EYE_COORDS)
-
-
 
 const struct tnl_pipeline_stage _tnl_normal_transform_stage =
 {
    "normal transform",         /* name */
-   _TNL_NEW_NORMAL_TRANSFORM,  /* re-check */
-   _TNL_NEW_NORMAL_TRANSFORM,  /* re-run */
-   GL_FALSE,                   /* active? */
-   _TNL_BIT_NORMAL,            /* inputs */
-   _TNL_BIT_NORMAL,            /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private data */
+   alloc_normal_data,
    free_normal_data,           /* destructor */
-   check_normal_transform,     /* check */
-   alloc_normal_data           /* run -- initially set to alloc */
+   validate_normal_stage,      /* check */
+   run_normal_stage
 };
index de86697..ccceba3 100644 (file)
@@ -44,39 +44,31 @@ struct point_stage_data {
 static GLboolean run_point_stage( GLcontext *ctx,
                                  struct tnl_pipeline_stage *stage )
 {
-   struct point_stage_data *store = POINT_STAGE_DATA(stage);
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
-   const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data;
-   const GLfloat p0 = ctx->Point.Params[0];
-   const GLfloat p1 = ctx->Point.Params[1];
-   const GLfloat p2 = ctx->Point.Params[2];
-   const GLfloat pointSize = ctx->Point._Size;
-   GLfloat (*size)[4] = store->PointSize.data;
-   GLuint i;
-
-   if (stage->changed_inputs) {
-      /* XXX do threshold and min/max clamping here? */
+   if (ctx->Point._Attenuated && !ctx->VertexProgram._Enabled) {
+      struct point_stage_data *store = POINT_STAGE_DATA(stage);
+      struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
+      const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data;
+      const GLfloat p0 = ctx->Point.Params[0];
+      const GLfloat p1 = ctx->Point.Params[1];
+      const GLfloat p2 = ctx->Point.Params[2];
+      const GLfloat pointSize = ctx->Point._Size;
+      GLfloat (*size)[4] = store->PointSize.data;
+      GLuint i;
+
       for (i = 0; i < VB->Count; i++) {
         const GLfloat dist = -eye[i][2];
         /* GLfloat dist = SQRTF(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2]);*/
         size[i][0] = pointSize / (p0 + dist * (p1 + dist * p2));
       }
-   }
 
-   VB->PointSizePtr = &store->PointSize;
-   VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize;
+      VB->PointSizePtr = &store->PointSize;
+      VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize;
+   }
 
    return GL_TRUE;
 }
 
 
-/* If point size attenuation is on we'll compute the point size for
- * each vertex in a special pipeline stage.
- */
-static void check_point_size( GLcontext *ctx, struct tnl_pipeline_stage *d )
-{
-   d->active = ctx->Point._Attenuated && !ctx->VertexProgram._Enabled;
-}
 
 static GLboolean alloc_point_data( GLcontext *ctx,
                                   struct tnl_pipeline_stage *stage )
@@ -89,11 +81,7 @@ static GLboolean alloc_point_data( GLcontext *ctx,
       return GL_FALSE;
 
    _mesa_vector4f_alloc( &store->PointSize, 0, VB->Size, 32 );
-
-   /* Now run the stage.
-    */
-   stage->run = run_point_stage;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
@@ -110,14 +98,9 @@ static void free_point_data( struct tnl_pipeline_stage *stage )
 const struct tnl_pipeline_stage _tnl_point_attenuation_stage =
 {
    "point size attenuation",   /* name */
-   _NEW_POINT|_NEW_PROGRAM,    /* check_state */
-   _NEW_POINT,                 /* run_state */
-   GL_FALSE,                   /* active */
-   _TNL_BIT_POS,               /* inputs */
-   _TNL_BIT_POS,               /* outputs */
-   0,                          /* changed_inputs (temporary value) */
    NULL,                       /* stage private data */
+   alloc_point_data,           /* alloc data */
    free_point_data,            /* destructor */
-   check_point_size,           /* check */
-   alloc_point_data            /* run -- initially set to alloc data */
+   NULL,
+   run_point_stage             /* run */
 };
index 614d537..9cf5df7 100644 (file)
 #include "t_pipeline.h"
 
 
-/**
- * \warning These values _MUST_ match the values in the OutputRegisters[]
- * array in vpparse.c!!!
- */
-#define VERT_RESULT_HPOS 0
-#define VERT_RESULT_COL0 1
-#define VERT_RESULT_COL1 2
-#define VERT_RESULT_BFC0 3
-#define VERT_RESULT_BFC1 4
-#define VERT_RESULT_FOGC 5
-#define VERT_RESULT_PSIZ 6
-#define VERT_RESULT_TEX0 7
-#define VERT_RESULT_TEX1 8
-#define VERT_RESULT_TEX2 9
-#define VERT_RESULT_TEX3 10
-#define VERT_RESULT_TEX4 11
-#define VERT_RESULT_TEX5 12
-#define VERT_RESULT_TEX6 13
-#define VERT_RESULT_TEX7 14
-
 
 /*!
  * Private storage for the vertex program pipeline stage.
@@ -100,6 +80,9 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
    struct vertex_program *program = ctx->VertexProgram.Current;
    GLuint i;
 
+   if (!ctx->VertexProgram._Enabled)
+      return GL_TRUE;
+
    /* load program parameter registers (they're read-only) */
    _mesa_init_vp_per_primitive_registers(ctx);
 
@@ -223,61 +206,14 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
 }
 
 
-/**
- * This function validates stuff.
- */
-static GLboolean run_validate_program( GLcontext *ctx,
-                                       struct tnl_pipeline_stage *stage )
-{
-#if 000
-   /* XXX do we need any validation for vertex programs? */
-   GLuint ind = 0;
-   light_func *tab;
-
-   if (ctx->Visual.rgbMode) {
-      if (ctx->Light._NeedVertices) {
-        if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
-           tab = _tnl_light_spec_tab;
-        else
-           tab = _tnl_light_tab;
-      }
-      else {
-        if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
-           tab = _tnl_light_fast_single_tab;
-        else
-           tab = _tnl_light_fast_tab;
-      }
-   }
-   else
-      tab = _tnl_light_ci_tab;
-
-   if (ctx->Light.ColorMaterialEnabled)
-      ind |= LIGHT_COLORMATERIAL;
-
-   if (ctx->Light.Model.TwoSide)
-      ind |= LIGHT_TWOSIDE;
-
-   VP_STAGE_DATA(stage)->light_func_tab = &tab[ind];
-
-   /* This and the above should only be done on _NEW_LIGHT:
-    */
-   _mesa_validate_all_lighting_tables( ctx );
-#endif
-
-   /* Now run the stage...
-    */
-   stage->run = run_vp;
-   return stage->run( ctx, stage );
-}
-
 
 
 /**
  * Called the first time stage->run is called.  In effect, don't
  * allocate data until the first time the stage is run.
  */
-static GLboolean run_init_vp( GLcontext *ctx,
-                              struct tnl_pipeline_stage *stage )
+static GLboolean init_vp( GLcontext *ctx,
+                         struct tnl_pipeline_stage *stage )
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &(tnl->vb);
@@ -300,29 +236,11 @@ static GLboolean run_init_vp( GLcontext *ctx,
    _mesa_vector4f_alloc( &store->ndcCoords, 0, size, 32 );
    store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
 
-   /* Now validate the stage derived data...
-    */
-   stage->run = run_validate_program;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
 
-/**
- * Check if vertex program mode is enabled. 
- * If so, configure the pipeline stage's type, inputs, and outputs.
- */
-static void check_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   stage->active = ctx->VertexProgram._Enabled;
-
-   if (stage->active) {
-      /* Set stage->inputs equal to the bitmask of vertex attributes
-       * which the program needs for inputs.
-       */
-      stage->inputs = ctx->VertexProgram.Current->InputsRead;
-   }
-}
 
 
 /**
@@ -336,7 +254,7 @@ static void dtr( struct tnl_pipeline_stage *stage )
       GLuint i;
 
       /* free the vertex program result arrays */
-      for (i = 0; i < 15; i++)
+      for (i = 0; i < VERT_RESULT_MAX; i++)
          _mesa_vector4f_free( &store->attribs[i] );
 
       /* free misc arrays */
@@ -354,14 +272,9 @@ static void dtr( struct tnl_pipeline_stage *stage )
 const struct tnl_pipeline_stage _tnl_vertex_program_stage =
 {
    "vertex-program",
-   _NEW_ALL,   /*XXX FIX */    /* recheck */
-   _NEW_ALL,   /*XXX FIX */    /* recalc */
-   GL_FALSE,                   /* active */
-   0,                          /* inputs - calculated on the fly */
-   _TNL_BITS_PROG_ANY,         /* outputs -- could calculate */
-   0,                          /* changed_inputs */
    NULL,                       /* private_data */
+   init_vp,                    /* create */
    dtr,                                /* destroy */
-   check_vp,                   /* check */
-   run_init_vp                 /* run -- initially set to ctr */
+   NULL,                       /* validate */
+   run_vp                      /* run -- initially set to ctr */
 };
index 44a09f5..8c92ac0 100644 (file)
@@ -268,7 +268,6 @@ static GLboolean run_render( GLcontext *ctx,
 {
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   GLuint new_inputs = stage->changed_inputs;
    tnl_render_func *tab;
    GLint pass = 0;
 
@@ -293,7 +292,7 @@ static GLboolean run_render( GLcontext *ctx,
    ASSERT(tnl->Driver.Render.ClippedPolygon);
    ASSERT(tnl->Driver.Render.Finish);
 
-   tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, new_inputs );
+   tnl->Driver.Render.BuildVertices( ctx, 0, VB->Count, ~0 );
 
    if (VB->ClipOrMask) {
       tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
@@ -340,42 +339,14 @@ static GLboolean run_render( GLcontext *ctx,
 
 
 
-/* Quite a bit of work involved in finding out the inputs for the
- * render stage.
- */
-static void check_render( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   stage->inputs = TNL_CONTEXT(ctx)->render_inputs;
-}
-
-
-
-
-static void dtr( struct tnl_pipeline_stage *stage )
-{
-   (void) stage;
-}
 
 
 const struct tnl_pipeline_stage _tnl_render_stage =
 {
    "render",                   /* name */
-   (_NEW_BUFFERS |
-    _DD_NEW_SEPARATE_SPECULAR |
-    _DD_NEW_FLATSHADE |
-    _NEW_TEXTURE|
-    _NEW_LIGHT|
-    _NEW_POINT|
-    _NEW_FOG|
-    _DD_NEW_TRI_UNFILLED |
-    _NEW_RENDERMODE),          /* re-check (new inputs, interp function) */
-   0,                          /* re-run (always runs) */
-   GL_TRUE,                    /* active? */
-   0,                          /* inputs (set in check_render) */
-   0,                          /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private data */
-   dtr,                                /* destructor */
-   check_render,               /* check */
+   NULL,                       /* creator */
+   NULL,                       /* destructor */
+   NULL,                       /* validate */
    run_render                  /* run */
 };
index 3cdd234..1af8e2b 100644 (file)
@@ -480,34 +480,42 @@ static void texgen( GLcontext *ctx,
 
 
 
+
 static GLboolean run_texgen_stage( GLcontext *ctx,
                                   struct tnl_pipeline_stage *stage )
 {
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
-   struct texgen_stage_data *store = TEXGEN_STAGE_DATA( stage );
+   struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
    GLuint i;
 
-   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
-      if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i)) {
-        if (stage->changed_inputs & (_TNL_BIT_POS | _TNL_BIT_NORMAL | _TNL_BIT_TEX(i)))
-           store->TexgenFunc[i]( ctx, store, i );
+   if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Enabled) 
+      return GL_TRUE;
+
+   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
+      struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+
+      if (texUnit->TexGenEnabled) {
+
+        store->TexgenFunc[i]( ctx, store, i );
 
         VB->AttribPtr[VERT_ATTRIB_TEX0+i] = 
            VB->TexCoordPtr[i] = &store->texcoord[i];
       }
+   }
 
    return GL_TRUE;
 }
 
 
-
-
-static GLboolean run_validate_texgen_stage( GLcontext *ctx,
-                                           struct tnl_pipeline_stage *stage )
+static void validate_texgen_stage( GLcontext *ctx,
+                                  struct tnl_pipeline_stage *stage )
 {
    struct texgen_stage_data *store = TEXGEN_STAGE_DATA(stage);
    GLuint i;
 
+   if (!ctx->Texture._TexGenEnabled || ctx->VertexProgram._Enabled) 
+      return;
+
    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
       struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
 
@@ -541,48 +549,9 @@ static GLboolean run_validate_texgen_stage( GLcontext *ctx,
         }
       }
    }
-
-   stage->run = run_texgen_stage;
-   return stage->run( ctx, stage );
 }
 
 
-static void check_texgen( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   GLuint i;
-   stage->active = 0;
-
-   if (ctx->Texture._TexGenEnabled && !ctx->VertexProgram._Enabled) {
-      GLuint inputs = 0;
-      GLuint outputs = 0;
-
-      if (ctx->Texture._GenFlags & (TEXGEN_OBJ_LINEAR | TEXGEN_NEED_EYE_COORD))
-        inputs |= _TNL_BIT_POS;
-
-      if (ctx->Texture._GenFlags & TEXGEN_NEED_NORMALS)
-        inputs |= _TNL_BIT_NORMAL;
-
-      for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
-        if (ctx->Texture._TexGenEnabled & ENABLE_TEXGEN(i))
-        {
-           outputs |= _TNL_BIT_TEX(i);
-
-           /* Need the original input in case it contains a Q coord:
-            * (sigh)
-            */
-           inputs |= _TNL_BIT_TEX(i);
-
-           /* Something for Feedback? */
-        }
-
-      if (stage->privatePtr)
-        stage->run = run_validate_texgen_stage;
-      stage->active = 1;
-      stage->inputs = inputs;
-      stage->outputs = outputs;
-   }
-}
-
 
 
 
@@ -606,10 +575,7 @@ static GLboolean alloc_texgen_data( GLcontext *ctx,
    store->tmp_f = (GLfloat (*)[3]) MALLOC(VB->Size * sizeof(GLfloat) * 3);
    store->tmp_m = (GLfloat *) MALLOC(VB->Size * sizeof(GLfloat));
 
-   /* Now validate and run the stage.
-    */
-   stage->run = run_validate_texgen_stage;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
@@ -637,14 +603,9 @@ static void free_texgen_data( struct tnl_pipeline_stage *stage )
 const struct tnl_pipeline_stage _tnl_texgen_stage =
 {
    "texgen",                   /* name */
-   _NEW_TEXTURE|_NEW_PROGRAM,  /* when to call check() */
-   _NEW_TEXTURE,               /* when to invalidate stored data */
-   GL_FALSE,                   /* active? */
-   0,                          /* inputs */
-   0,                          /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private data */
+   alloc_texgen_data,          /* destructor */
    free_texgen_data,           /* destructor */
-   check_texgen,               /* check */
-   alloc_texgen_data           /* run -- initially set to alloc data */
+   validate_texgen_stage,              /* check */
+   run_texgen_stage            /* run -- initially set to alloc data */
 };
index 00330b6..2347530 100644 (file)
@@ -52,23 +52,7 @@ struct texmat_stage_data {
 
 #define TEXMAT_STAGE_DATA(stage) ((struct texmat_stage_data *)stage->privatePtr)
 
-static void check_texmat( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   GLuint i;
-   stage->active = 0;
-
-   if (ctx->Texture._TexMatEnabled && !ctx->VertexProgram._Enabled) {
-      GLuint flags = 0;
 
-      for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
-        if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i))
-           flags |= _TNL_BIT_TEX(i);
-
-      stage->active = 1;
-      stage->inputs = flags;
-      stage->outputs = flags;
-   }
-}
 
 static GLboolean run_texmat_stage( GLcontext *ctx,
                                   struct tnl_pipeline_stage *stage )
@@ -77,19 +61,23 @@ static GLboolean run_texmat_stage( GLcontext *ctx,
    struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    GLuint i;
 
+   if (!ctx->Texture._TexMatEnabled || ctx->VertexProgram._Enabled) 
+      return GL_TRUE;
+
    /* ENABLE_TEXMAT implies that the texture matrix is not the
     * identity, so we don't have to check that here.
     */
-   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
+   for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) {
       if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) {
-        if (stage->changed_inputs & _TNL_BIT_TEX(i))
-           (void) TransformRaw( &store->texcoord[i],
-                                 ctx->TextureMatrixStack[i].Top,
-                                VB->TexCoordPtr[i]);
+        (void) TransformRaw( &store->texcoord[i],
+                             ctx->TextureMatrixStack[i].Top,
+                             VB->TexCoordPtr[i]);
 
         VB->AttribPtr[VERT_ATTRIB_TEX0+i] = 
            VB->TexCoordPtr[i] = &store->texcoord[i];
       }
+   }
+
    return GL_TRUE;
 }
 
@@ -111,10 +99,7 @@ static GLboolean alloc_texmat_data( GLcontext *ctx,
    for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++)
       _mesa_vector4f_alloc( &store->texcoord[i], 0, VB->Size, 32 );
 
-   /* Now run the stage.
-    */
-   stage->run = run_texmat_stage;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 
@@ -137,14 +122,9 @@ static void free_texmat_data( struct tnl_pipeline_stage *stage )
 const struct tnl_pipeline_stage _tnl_texture_transform_stage =
 {
    "texture transform",                        /* name */
-   _NEW_TEXTURE|_NEW_TEXTURE_MATRIX|_NEW_PROGRAM,      /* check_state */
-   _NEW_TEXTURE|_NEW_TEXTURE_MATRIX,   /* run_state */
-   GL_FALSE,                           /* active? */
-   0,                                  /* inputs */
-   0,                                  /* outputs */
-   0,                                  /* changed_inputs */
    NULL,                               /* private data */
+   alloc_texmat_data,
    free_texmat_data,                   /* destructor */
-   check_texmat,                       /* check */
-   alloc_texmat_data,                  /* run -- initially set to init */
+   NULL,
+   run_texmat_stage,
 };
index ec30318..b3defaa 100644 (file)
@@ -47,14 +47,6 @@ struct vertex_stage_data {
    GLubyte *clipmask;
    GLubyte ormask;
    GLubyte andmask;
-
-
-   /* Need these because it's difficult to replay the sideeffects
-    * analytically.
-    */
-   GLvector4f *save_eyeptr;
-   GLvector4f *save_clipptr;
-   GLvector4f *save_ndcptr;
 };
 
 #define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr)
@@ -134,137 +126,90 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
 
-   ASSERT(!ctx->VertexProgram._Enabled);
-
-   if (stage->changed_inputs) {
-
-      if (ctx->_NeedEyeCoords) {
-        /* Separate modelview transformation:
-         * Use combined ModelProject to avoid some depth artifacts
-         */
-        if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
-           VB->EyePtr = VB->ObjPtr;
-        else
-           VB->EyePtr = TransformRaw( &store->eye,
-                                       ctx->ModelviewMatrixStack.Top,
-                                      VB->ObjPtr);
-#if 0
-         /* examine some eye coordinates */
-         {
-            GLuint i;
-            GLfloat *v = VB->EyePtr->start;
-            for (i = 0; i < 4; i++) {
-               _mesa_printf("eye[%d] = %g, %g, %g, %g\n",
-                            i, v[0], v[1], v[2], v[3]);
-               v += 4;
-            }
-         }
-#endif
-      }
-
-      VB->ClipPtr = TransformRaw( &store->clip,
-                                 &ctx->_ModelProjectMatrix,
-                                 VB->ObjPtr );
-
-      /* Drivers expect this to be clean to element 4...
-       */
-      switch (VB->ClipPtr->size) {
-      case 1:                  
-        /* impossible */
-      case 2:
-        _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
-         /* fall-through */
-      case 3:
-        _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
-         /* fall-through */
-      case 4:
-        break;
-      }
-
-#if 0
-      /* examine some clip coordinates */
-      {
-         GLuint i;
-         GLfloat *v = VB->ClipPtr->start;
-         for (i = 0; i < 4; i++) {
-            _mesa_printf("clip[%d] = %g, %g, %g, %g\n",
-                         i, v[0], v[1], v[2], v[3]);
-            v += 4;
-         }
-      }
-#endif
-
-      /* Cliptest and perspective divide.  Clip functions must clear
-       * the clipmask.
+   if (ctx->VertexProgram._Enabled) 
+      return GL_TRUE;
+
+   if (ctx->_NeedEyeCoords) {
+      /* Separate modelview transformation:
+       * Use combined ModelProject to avoid some depth artifacts
        */
-      store->ormask = 0;
-      store->andmask = CLIP_ALL_BITS;
-
-      if (tnl->NeedNdcCoords) {
-        VB->NdcPtr =
-           _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                               &store->proj,
-                                               store->clipmask,
-                                               &store->ormask,
-                                               &store->andmask );
-      }
-      else {
-        VB->NdcPtr = NULL;
-        _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                               NULL,
-                                               store->clipmask,
-                                               &store->ormask,
-                                               &store->andmask );
-      }
+      if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
+        VB->EyePtr = VB->ObjPtr;
+      else
+        VB->EyePtr = TransformRaw( &store->eye,
+                                   ctx->ModelviewMatrixStack.Top,
+                                   VB->ObjPtr);
+   }
 
-      if (store->andmask)
-        return GL_FALSE;
+   VB->ClipPtr = TransformRaw( &store->clip,
+                              &ctx->_ModelProjectMatrix,
+                              VB->ObjPtr );
 
+   /* Drivers expect this to be clean to element 4...
+    */
+   switch (VB->ClipPtr->size) {
+   case 1:                     
+      /* impossible */
+   case 2:
+      _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
+      /* fall-through */
+   case 3:
+      _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
+      /* fall-through */
+   case 4:
+      break;
+   }
 
-      /* Test userclip planes.  This contributes to VB->ClipMask, so
-       * is essentially required to be in this stage.
-       */
-      if (ctx->Transform.ClipPlanesEnabled) {
-        usercliptab[VB->ClipPtr->size]( ctx,
-                                        VB->ClipPtr,
-                                        store->clipmask,
-                                        &store->ormask,
-                                        &store->andmask );
-
-        if (store->andmask)
-           return GL_FALSE;
-      }
-
-      VB->ClipAndMask = store->andmask;
-      VB->ClipOrMask = store->ormask;
-      VB->ClipMask = store->clipmask;
-
-      store->save_eyeptr = VB->EyePtr;
-      store->save_clipptr = VB->ClipPtr;
-      store->save_ndcptr = VB->NdcPtr;
+
+   /* Cliptest and perspective divide.  Clip functions must clear
+    * the clipmask.
+    */
+   store->ormask = 0;
+   store->andmask = CLIP_ALL_BITS;
+
+   if (tnl->NeedNdcCoords) {
+      VB->NdcPtr =
+        _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
+                                           &store->proj,
+                                           store->clipmask,
+                                           &store->ormask,
+                                           &store->andmask );
    }
    else {
-      /* Replay the sideeffects.
-       */
-      VB->EyePtr = store->save_eyeptr;
-      VB->ClipPtr = store->save_clipptr;
-      VB->NdcPtr = store->save_ndcptr;
-      VB->ClipMask = store->clipmask;
-      VB->ClipAndMask = store->andmask;
-      VB->ClipOrMask = store->ormask;
+      VB->NdcPtr = NULL;
+      _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
+                                           NULL,
+                                           store->clipmask,
+                                           &store->ormask,
+                                           &store->andmask );
+   }
+
+   if (store->andmask)
+      return GL_FALSE;
+
+
+   /* Test userclip planes.  This contributes to VB->ClipMask, so
+    * is essentially required to be in this stage.
+    */
+   if (ctx->Transform.ClipPlanesEnabled) {
+      usercliptab[VB->ClipPtr->size]( ctx,
+                                     VB->ClipPtr,
+                                     store->clipmask,
+                                     &store->ormask,
+                                     &store->andmask );
+
       if (store->andmask)
         return GL_FALSE;
    }
 
+   VB->ClipAndMask = store->andmask;
+   VB->ClipOrMask = store->ormask;
+   VB->ClipMask = store->clipmask;
+
    return GL_TRUE;
 }
 
 
-static void check_vertex( GLcontext *ctx, struct tnl_pipeline_stage *stage )
-{
-   stage->active = !ctx->VertexProgram._Enabled;
-}
-
 static GLboolean init_vertex_stage( GLcontext *ctx,
                                    struct tnl_pipeline_stage *stage )
 {
@@ -289,10 +234,7 @@ static GLboolean init_vertex_stage( GLcontext *ctx,
        !store->proj.data)
       return GL_FALSE;
 
-   /* Now run the stage.
-    */
-   stage->run = run_vertex_stage;
-   return stage->run( ctx, stage );
+   return GL_TRUE;
 }
 
 static void dtr( struct tnl_pipeline_stage *stage )
@@ -314,18 +256,9 @@ static void dtr( struct tnl_pipeline_stage *stage )
 const struct tnl_pipeline_stage _tnl_vertex_transform_stage =
 {
    "modelview/project/cliptest/divide",
-   _NEW_PROGRAM,                /* check_state: only care about vertex prog */
-   _MESA_NEW_NEED_EYE_COORDS |  /* run_state: when to invalidate / re-run */
-   _NEW_MODELVIEW|
-   _NEW_PROJECTION|
-   _NEW_PROGRAM|
-   _NEW_TRANSFORM,
-   GL_TRUE,                    /* active */
-   _TNL_BIT_POS,               /* inputs */
-   _TNL_BIT_POS,               /* outputs */
-   0,                          /* changed_inputs */
    NULL,                       /* private data */
+   init_vertex_stage,
    dtr,                                /* destructor */
-   check_vertex,               /* check */
-   init_vertex_stage           /* run -- initially set to init */
+   NULL,
+   run_vertex_stage            /* run -- initially set to init */
 };
index 7113c33..ab64e70 100644 (file)
@@ -46,7 +46,7 @@
  * generated program with line/function references for each
  * instruction back into this file:
  */
-#define DISASSEM 1
+#define DISASSEM 0
 
 /* Use uregs to represent registers internally, translate to Mesa's
  * expected formats on emit.  
diff --git a/src/mesa/tnl/t_vp_build.h b/src/mesa/tnl/t_vp_build.h
new file mode 100644 (file)
index 0000000..39c0348
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.3
+ *
+ * Copyright (C) 2005  Tungsten Graphics   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * TUNGSTEN GRAPHICS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _T_ARB_BUILD_H
+#define _T_ARB_BUILD_H
+
+#include "mtypes.h"
+
+/* Define to 1 to test fixed-function execution via vertex programs:
+ */
+#define TNL_FIXED_FUNCTION_PROGRAM 0
+
+extern void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx );
+
+#endif
index e71a8fc..ef60978 100644 (file)
@@ -272,16 +272,9 @@ void _tnl_flush_vtx( GLcontext *ctx )
         if (ctx->NewState)
            _mesa_update_state( ctx );
       
-        if (tnl->pipeline.build_state_changes)
-           _tnl_validate_pipeline( ctx );
-
         _tnl_vb_bind_vtx( ctx );
 
-        /* Invalidate all stored data before and after run:
-         */
-        tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
         tnl->Driver.RunPipeline( ctx );
-        tnl->pipeline.run_input_changes |= tnl->pipeline.inputs;
       }
    }