fragment program execution
[mesa.git] / src / mesa / tnl / t_eval_api.c
index 0a351eed894c87d6fb18ab4d2560117c5b97a408..feddf2619a18c0c2a88f593b7296150163e61916 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id: t_eval_api.c,v 1.2 2001/01/08 21:56:00 keithw Exp $ */
+/* $Id: t_eval_api.c,v 1.12 2002/10/24 23:57:25 brianp Exp $ */
 
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  4.1
  *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2002  Brian Paul   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"),
  * BRIAN PAUL 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.
+ *
+ * Authors:
+ *    Keith Whitwell - original code
+ *    Brian Paul - vertex program updates
  */
 
 
@@ -29,7 +33,7 @@
 #include "colormac.h"
 #include "context.h"
 #include "macros.h"
-#include "mem.h"
+#include "imports.h"
 #include "mmath.h"
 #include "mtypes.h"
 #include "math/m_eval.h"
@@ -40,9 +44,6 @@
 #include "t_imm_exec.h"
 
 
-
-
-
 /* KW: If are compiling, we don't know whether eval will produce a
  *     vertex when it is run in the future.  If this is pure immediate
  *     mode, eval is a noop if neither vertex map is enabled.
@@ -50,7 +51,7 @@
  *     Thus we need to have a check in the display list code or
  *     elsewhere for eval(1,2) vertices in the case where
  *     map(1,2)_vertex is disabled, and to purge those vertices from
- *     the vb.  
+ *     the vb.
  */
 void
 _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
@@ -61,6 +62,9 @@ _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
    GLenum prim;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glEvalMesh1()");
+
    switch (mode) {
       case GL_POINT:
          prim = GL_POINTS;
@@ -69,13 +73,14 @@ _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
          prim = GL_LINE_STRIP;
          break;
       default:
-         gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
+         _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh1(mode)" );
          return;
    }
 
    /* No effect if vertex maps disabled.
     */
-   if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3)
+   if (!ctx->Eval.Map1Vertex4 && !ctx->Eval.Map1Vertex3 &&
+       (!ctx->VertexProgram.Enabled || !ctx->Eval.Map1Attrib[VERT_ATTRIB_POS]))
       return;
 
    du = ctx->Eval.MapGrid1du;
@@ -83,31 +88,51 @@ _tnl_exec_EvalMesh1( GLenum mode, GLint i1, GLint i2 )
 
    /* Need to turn off compilation -- this is already saved, and the
     * coordinates generated and the test above depend on state that
-    * may change before the list is executed.  
-    * 
+    * may change before the list is executed.
+    *
     * TODO: Anaylse display lists to determine if this state is
     * constant.
+    *
+    * State to watch:
+    *       - enabled maps
+    *       - map state for each enabled map, including control points
+    *       - grid state
+    *
+    * Could alternatively cache individual maps in arrays, rather than
+    * building immediates.  
     */
    {
       GLboolean compiling = ctx->CompileFlag;
+      TNLcontext *tnl = TNL_CONTEXT(ctx);
       struct immediate *im = TNL_CURRENT_IM(ctx);
+      GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
+
+      NotifyBegin = tnl->Driver.NotifyBegin;
+      tnl->Driver.NotifyBegin = 0;
 
       if (compiling) {
+        struct immediate *tmp = _tnl_alloc_immediate( ctx );
         FLUSH_VERTICES( ctx, 0 );
-        SET_IMMEDIATE( ctx, _tnl_alloc_immediate( ctx ) );
+        SET_IMMEDIATE( ctx, tmp );
+        TNL_CURRENT_IM(ctx)->ref_count++;       
         ctx->CompileFlag = GL_FALSE;
       }
 
-      _tnl_hard_begin( ctx, prim );
+      _tnl_Begin( prim );
       for (i=i1;i<=i2;i++,u+=du) {
         _tnl_eval_coord1f( ctx, u );
       }
       _tnl_end(ctx);
 
+      /* Need this for replay *and* compile:
+       */
+      FLUSH_VERTICES( ctx, 0 );
+      tnl->Driver.NotifyBegin = NotifyBegin;
+
       if (compiling) {
-        FLUSH_VERTICES( ctx, 0 );
+        TNL_CURRENT_IM(ctx)->ref_count--;
         ASSERT( TNL_CURRENT_IM(ctx)->ref_count == 0 );
-        _tnl_free_immediate( TNL_CURRENT_IM(ctx) );
+        _tnl_free_immediate( ctx, TNL_CURRENT_IM(ctx) );
         SET_IMMEDIATE( ctx, im );
         ctx->CompileFlag = GL_TRUE;
       }
@@ -124,12 +149,15 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
    GLfloat u, du, v, dv, v1, u1;
    ASSERT_OUTSIDE_BEGIN_END(ctx);
 
+   if (MESA_VERBOSE & VERBOSE_API)
+      _mesa_debug(ctx, "glEvalMesh2()");
+
    /* No effect if vertex maps disabled.
     */
-   if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3)
+   if (!ctx->Eval.Map2Vertex4 && !ctx->Eval.Map2Vertex3 &&
+       (!ctx->VertexProgram.Enabled || !ctx->Eval.Map2Attrib[VERT_ATTRIB_POS]))
       return;
 
-
    du = ctx->Eval.MapGrid2du;
    dv = ctx->Eval.MapGrid2dv;
    v1 = ctx->Eval.MapGrid2v1 + j1 * dv;
@@ -137,21 +165,28 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
 
    /* Need to turn off compilation -- this is already saved, and the
     * coordinates generated and the test above depend on state that
-    * may change before the list is executed.  
+    * may change before the list is executed.
     */
    {
       GLboolean compiling = ctx->CompileFlag;
       struct immediate *im = TNL_CURRENT_IM(ctx);
+      TNLcontext *tnl = TNL_CONTEXT(ctx);
+      GLboolean (*NotifyBegin)(GLcontext *ctx, GLenum p);
+
+      NotifyBegin = tnl->Driver.NotifyBegin;
+      tnl->Driver.NotifyBegin = 0;
 
       if (compiling) {
+        struct immediate *tmp = _tnl_alloc_immediate( ctx );
         FLUSH_VERTICES( ctx, 0 );
-        SET_IMMEDIATE( ctx, _tnl_alloc_immediate( ctx ) );
+        SET_IMMEDIATE( ctx, tmp );
+        TNL_CURRENT_IM(ctx)->ref_count++;       
         ctx->CompileFlag = GL_FALSE;
       }
 
       switch (mode) {
       case GL_POINT:
-        _tnl_hard_begin( ctx, GL_POINTS );
+        _tnl_Begin( GL_POINTS );
         for (v=v1,j=j1;j<=j2;j++,v+=dv) {
            for (u=u1,i=i1;i<=i2;i++,u+=du) {
               _tnl_eval_coord2f( ctx, u, v );
@@ -161,14 +196,14 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
         break;
       case GL_LINE:
         for (v=v1,j=j1;j<=j2;j++,v+=dv) {
-           _tnl_hard_begin( ctx, GL_LINE_STRIP );
+           _tnl_Begin( GL_LINE_STRIP );
            for (u=u1,i=i1;i<=i2;i++,u+=du) {
               _tnl_eval_coord2f( ctx, u, v );
            }
            _tnl_end(ctx);
         }
         for (u=u1,i=i1;i<=i2;i++,u+=du) {
-           _tnl_hard_begin( ctx, GL_LINE_STRIP );
+           _tnl_Begin( GL_LINE_STRIP );
            for (v=v1,j=j1;j<=j2;j++,v+=dv) {
               _tnl_eval_coord2f( ctx, u, v );
            }
@@ -177,7 +212,7 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
         break;
       case GL_FILL:
         for (v=v1,j=j1;j<j2;j++,v+=dv) {
-           _tnl_hard_begin( ctx, GL_TRIANGLE_STRIP );
+           _tnl_Begin( GL_TRIANGLE_STRIP );
            for (u=u1,i=i1;i<=i2;i++,u+=du) {
               _tnl_eval_coord2f( ctx, u, v );
               _tnl_eval_coord2f( ctx, u, v+dv );
@@ -186,13 +221,18 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
         }
         break;
       default:
-        gl_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
+        _mesa_error( ctx, GL_INVALID_ENUM, "glEvalMesh2(mode)" );
         return;
       }
 
+      /* Need this for replay *and* compile:
+       */
+      FLUSH_VERTICES( ctx, 0 );
+      tnl->Driver.NotifyBegin = NotifyBegin;
+        
       if (compiling) {
-        FLUSH_VERTICES( ctx, 0 );
-        _tnl_free_immediate( TNL_CURRENT_IM( ctx ) );
+        TNL_CURRENT_IM(ctx)->ref_count--;
+        _tnl_free_immediate( ctx, TNL_CURRENT_IM( ctx ) );
         SET_IMMEDIATE( ctx, im );
         ctx->CompileFlag = GL_TRUE;
       }
@@ -200,7 +240,6 @@ _tnl_exec_EvalMesh2( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
 }
 
 
-
 void _tnl_eval_init( GLcontext *ctx )
 {
    GLvertexformat *vfmt = &(TNL_CONTEXT(ctx)->vtxfmt);