Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / mesa / tnl / t_vb_vertex.c
index 0279d13d378ec3d1eb928e0dd54024c28fa2031d..30aa7c4086835b880466844b06e312e373b5aa4a 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: t_vb_vertex.c,v 1.5 2001/03/03 20:57:00 brianp Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  6.5
  *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2006  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"),
  * 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.
  *
- * Author:
- *    Keith Whitwell <keithw@valinux.com>
+ * Authors:
+ *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
 
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "macros.h"
-#include "mem.h"
-#include "mmath.h"
-#include "mtypes.h"
+#include "main/glheader.h"
+#include "main/colormac.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/mtypes.h"
 
 #include "math/m_xform.h"
 
 struct vertex_stage_data {
    GLvector4f eye;
    GLvector4f clip;
-   GLvector4f proj;    
+   GLvector4f proj;
    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_projptr;
 };
 
-#define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->private)
+#define VERTEX_STAGE_DATA(stage) ((struct vertex_stage_data *)stage->privatePtr)
 
 
 
 
 /* This function implements cliptesting for user-defined clip planes.
  * The clipping of primitives to these planes is implemented in
- * t_render_clip.h.  
+ * t_render_clip.h.
  */
 #define USER_CLIPTEST(NAME, SZ)                                        \
 static void NAME( GLcontext *ctx,                              \
@@ -79,7 +68,7 @@ static void NAME( GLcontext *ctx,                             \
    GLuint p;                                                   \
                                                                \
    for (p = 0; p < ctx->Const.MaxClipPlanes; p++)              \
-      if (ctx->Transform.ClipEnabled[p]) {                     \
+      if (ctx->Transform.ClipPlanesEnabled & (1 << p)) {       \
         GLuint nr, i;                                          \
         const GLfloat a = ctx->Transform._ClipUserPlane[p][0]; \
         const GLfloat b = ctx->Transform._ClipUserPlane[p][1]; \
@@ -113,16 +102,16 @@ static void NAME( GLcontext *ctx,                         \
 }
 
 
-USER_CLIPTEST(userclip2, 2)            
-USER_CLIPTEST(userclip3, 3)            
-USER_CLIPTEST(userclip4, 4)            
+USER_CLIPTEST(userclip2, 2)
+USER_CLIPTEST(userclip3, 3)
+USER_CLIPTEST(userclip4, 4)
 
 static void (*(usercliptab[5]))( GLcontext *,
                                 GLvector4f *, GLubyte *,
-                                GLubyte *, GLubyte * ) = 
+                                GLubyte *, GLubyte * ) =
 {
-   0,
-   0,
+   NULL,
+   NULL,
    userclip2,
    userclip3,
    userclip4
@@ -130,162 +119,125 @@ static void (*(usercliptab[5]))( GLcontext *,
 
 
 
-static GLboolean run_vertex_stage( GLcontext *ctx, 
-                                  struct gl_pipeline_stage *stage )
+static GLboolean run_vertex_stage( GLcontext *ctx,
+                                  struct tnl_pipeline_stage *stage )
 {
-   struct vertex_stage_data *store = (struct vertex_stage_data *)stage->private;
-   TNLcontext *tnl = TNL_CONTEXT(ctx); 
-   struct vertex_buffer *VB = &tnl->vb; 
-   
-   if (stage->changed_inputs) 
-   {
-/*        VB->ObjPtr->size = 4; */
-
-      if (ctx->_NeedEyeCoords) {
-        /* Seperate modelview and project transformations:
-         */
-        if (ctx->ModelView.type == MATRIX_IDENTITY)
-           VB->EyePtr = VB->ObjPtr;
-        else
-           VB->EyePtr = TransformRaw( &store->eye, &ctx->ModelView, 
-                                      VB->ObjPtr);
-
-        if (ctx->ProjectionMatrix.type == MATRIX_IDENTITY)
-           VB->ClipPtr = VB->EyePtr;
-        else
-           VB->ClipPtr = TransformRaw( &store->clip, &ctx->ProjectionMatrix, 
-                                       VB->EyePtr );
-      } 
-      else 
-      {
-        /* Combined modelviewproject transform:
-         */
-        if (ctx->_ModelProjectMatrix.type == MATRIX_IDENTITY) 
-           VB->ClipPtr = VB->ObjPtr;
-        else
-           VB->ClipPtr = TransformRaw( &store->clip, &ctx->_ModelProjectMatrix,
-                                       VB->ObjPtr );
-      }
-
-      /* Drivers expect this to be clean to element 4...
-       */
-      if (VB->ClipPtr->size < 4) {
-        if (VB->ClipPtr->flags & VEC_NOT_WRITEABLE) {
-           ASSERT(VB->ClipPtr == VB->ObjPtr);
-           VB->import_data( ctx, VERT_OBJ, VEC_NOT_WRITEABLE );
-           VB->ClipPtr = VB->ObjPtr;
-        }
-        if (VB->ClipPtr->size == 2) 
-           _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 );
-        _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
-      }
-
-      /* Cliptest and perspective divide.  Clip functions must clear
-       * the clipmask.  
-       */
-      store->ormask = 0;
-      store->andmask = CLIP_ALL_BITS;
-
-      if (tnl->NeedProjCoords) {
-        VB->ProjectedClipPtr = 
-           _mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                               &store->proj,
-                                               store->clipmask,
-                                               &store->ormask,
-                                               &store->andmask );
-
-      } else {
-        VB->ProjectedClipPtr = 0;
-        _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                               0,
-                                               store->clipmask,
-                                               &store->ormask,
-                                               &store->andmask );
-      }
-
-      if (store->andmask) 
-        return GL_FALSE;
+   struct vertex_stage_data *store = (struct vertex_stage_data *)stage->privatePtr;
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
 
+   if (ctx->VertexProgram._Current) 
+      return GL_TRUE;
 
-      /* Test userclip planes.  This contributes to VB->ClipMask, so
-       * is essentially required to be in this stage.
+   if (ctx->_NeedEyeCoords) {
+      /* Separate modelview transformation:
+       * Use combined ModelProject to avoid some depth artifacts
        */
-      if (ctx->Transform._AnyClip) {
-        usercliptab[VB->ClipPtr->size]( ctx,
-                                        VB->ClipPtr,
-                                        store->clipmask,
-                                        &store->ormask,
-                                        &store->andmask );
-
-        if (store->andmask)
-           return GL_FALSE;
-      }
-      
-      VB->ClipOrMask = store->ormask;
-      VB->ClipMask = store->clipmask;
-
-      if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ))
-        VB->importable_data |= VERT_CLIP;
-
-      store->save_eyeptr = VB->EyePtr;
-      store->save_clipptr = VB->ClipPtr;
-      store->save_projptr = VB->ProjectedClipPtr;
-   } 
+      if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
+        VB->EyePtr = VB->ObjPtr;
+      else
+        VB->EyePtr = TransformRaw( &store->eye,
+                                   ctx->ModelviewMatrixStack.Top,
+                                   VB->ObjPtr);
+   }
+
+   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;
+   }
+
+
+   /* Cliptest and perspective divide.  Clip functions must clear
+    * the clipmask.
+    */
+   store->ormask = 0;
+   store->andmask = CLIP_FRUSTUM_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->ProjectedClipPtr = store->save_projptr;
-      VB->ClipMask = store->clipmask;
-      VB->ClipOrMask = store->ormask;
-      if (VB->ClipPtr == VB->ObjPtr && (VB->importable_data & VERT_OBJ))
-        VB->importable_data |= VERT_CLIP;
+      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 gl_pipeline_stage *stage )
+static GLboolean init_vertex_stage( GLcontext *ctx,
+                                   struct tnl_pipeline_stage *stage )
 {
-   (void) ctx; 
-   (void) stage;
-}
-
-static GLboolean init_vertex_stage( GLcontext *ctx, 
-                                   struct gl_pipeline_stage *stage )
-{
-   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 
+   struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
    struct vertex_stage_data *store;
    GLuint size = VB->Size;
 
-   stage->private = CALLOC(sizeof(*store));
+   stage->privatePtr = CALLOC(sizeof(*store));
    store = VERTEX_STAGE_DATA(stage);
    if (!store)
       return GL_FALSE;
-   
+
    _mesa_vector4f_alloc( &store->eye, 0, size, 32 );
    _mesa_vector4f_alloc( &store->clip, 0, size, 32 );
-   _mesa_vector4f_alloc( &store->proj, 0, size, 32 );  
+   _mesa_vector4f_alloc( &store->proj, 0, size, 32 );
 
    store->clipmask = (GLubyte *) ALIGN_MALLOC(sizeof(GLubyte)*size, 32 );
 
    if (!store->clipmask ||
-       !store->eye.data || 
-       !store->clip.data || 
-       !store->proj.data) 
+       !store->eye.data ||
+       !store->clip.data ||
+       !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 gl_pipeline_stage *stage )
+static void dtr( struct tnl_pipeline_stage *stage )
 {
    struct vertex_stage_data *store = VERTEX_STAGE_DATA(stage);
 
@@ -295,26 +247,18 @@ static void dtr( struct gl_pipeline_stage *stage )
       _mesa_vector4f_free( &store->proj );
       ALIGN_FREE( store->clipmask );
       FREE(store);
-      stage->private = 0;
+      stage->privatePtr = NULL;
       stage->run = init_vertex_stage;
    }
 }
 
 
-const struct gl_pipeline_stage _tnl_vertex_transform_stage = 
-{ 
+const struct tnl_pipeline_stage _tnl_vertex_transform_stage =
+{
    "modelview/project/cliptest/divide",
-   0,                          /* re-check -- always on */
-   _NEW_MODELVIEW|
-   _NEW_PROJECTION|
-   _NEW_TRANSFORM,             /* re-run */
-   GL_TRUE,                    /* active */
-   VERT_OBJ,           /* inputs */
-   VERT_EYE|VERT_CLIP,         /* outputs */
-   0, 0,                       /* changed_inputs, private */
+   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 */
 };
-
-