Merge branch 'master' into opengl-es-v2
[mesa.git] / src / mesa / tnl / t_vb_vertex.c
index 63dc653245df98afbb00872e5766838e415962cb..bc7e0951ec8c93c47bf011d586ceda5c6816df62 100644 (file)
@@ -1,9 +1,8 @@
-
 /*
  * Mesa 3-D graphics library
- * Version:  5.0
+ * Version:  6.5
  *
- * Copyright (C) 1999-2001  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"),
  */
 
 
-#include "glheader.h"
-#include "colormac.h"
-#include "context.h"
-#include "macros.h"
-#include "imports.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"
 
@@ -48,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)
@@ -119,14 +110,30 @@ static void (*(usercliptab[5]))( GLcontext *,
                                 GLvector4f *, GLubyte *,
                                 GLubyte *, GLubyte * ) =
 {
-   0,
-   0,
+   NULL,
+   NULL,
    userclip2,
    userclip3,
    userclip4
 };
 
 
+void
+tnl_clip_prepare(GLcontext *ctx)
+{
+   /* Neither the x86 nor sparc asm cliptest functions have been updated
+    * for ARB_depth_clamp, so force the C paths.
+    */
+   if (ctx->Transform.DepthClamp) {
+      static GLboolean c_funcs_installed = GL_FALSE;
+      if (!c_funcs_installed) {
+         init_c_cliptest();
+         c_funcs_installed = GL_TRUE;
+      }
+   }
+}
+
+
 
 static GLboolean run_vertex_stage( GLcontext *ctx,
                                   struct tnl_pipeline_stage *stage )
@@ -135,108 +142,94 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
 
-   ASSERT(!ctx->VertexProgram.Enabled);
+   if (ctx->VertexProgram._Current) 
+      return GL_TRUE;
 
-   if (stage->changed_inputs) {
+   tnl_clip_prepare(ctx);
 
-      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 (ctx->_NeedEyeCoords) {
+      /* Separate modelview transformation:
+       * Use combined ModelProject to avoid some depth artifacts
+       */
+      if (ctx->ModelviewMatrixStack.Top->type == MATRIX_IDENTITY)
+        VB->EyePtr = VB->AttribPtr[_TNL_ATTRIB_POS];
+      else
+        VB->EyePtr = TransformRaw( &store->eye,
+                                   ctx->ModelviewMatrixStack.Top,
+                                   VB->AttribPtr[_TNL_ATTRIB_POS]);
+   }
 
-      VB->ClipPtr = TransformRaw( &store->clip,
-                                 &ctx->_ModelProjectMatrix,
-                                 VB->ObjPtr );
+   VB->ClipPtr = TransformRaw( &store->clip,
+                              &ctx->_ModelProjectMatrix,
+                              VB->AttribPtr[_TNL_ATTRIB_POS] );
 
-      /* 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 );
-      case 3:
-        _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 );
-      case 4:
-        break;
-      }
+   /* 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_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 = 0;
-        _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
-                                               0,
-                                               store->clipmask,
-                                               &store->ormask,
-                                               &store->andmask );
-      }
 
-      if (store->andmask)
-        return GL_FALSE;
+   /* 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,
+                                           !ctx->Transform.DepthClamp );
+   }
+   else {
+      VB->NdcPtr = NULL;
+      _mesa_clip_np_tab[VB->ClipPtr->size]( VB->ClipPtr,
+                                           NULL,
+                                           store->clipmask,
+                                           &store->ormask,
+                                           &store->andmask,
+                                           !ctx->Transform.DepthClamp );
+   }
 
+   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->ClipOrMask = store->ormask;
-      VB->ClipMask = store->clipmask;
+   /* 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 );
 
-      store->save_eyeptr = VB->EyePtr;
-      store->save_clipptr = VB->ClipPtr;
-      store->save_ndcptr = VB->NdcPtr;
-   }
-   else {
-      /* Replay the sideeffects.
-       */
-      VB->EyePtr = store->save_eyeptr;
-      VB->ClipPtr = store->save_clipptr;
-      VB->NdcPtr = store->save_ndcptr;
-      VB->ClipMask = store->clipmask;
-      VB->ClipOrMask = store->ormask;
       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 )
 {
@@ -261,10 +254,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 )
@@ -286,18 +276,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 */
 };