gallivm: Add a lp_build_const_func_pointer() helper.
[mesa.git] / src / mesa / vbo / vbo_exec.c
index 4499803b8c70d6ad6a925dda61eff21b4043c17c..fd5e0f8911b40b86644bd69286d5c410018fd724 100644 (file)
  */
 
 
-#include "api_arrayelt.h"
-#include "glheader.h"
-#include "imports.h"
-#include "context.h"
-#include "macros.h"
-#include "mtypes.h"
-#include "dlist.h"
-#include "vtxfmt.h"
-
+#include "main/api_arrayelt.h"
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/vtxfmt.h"
 #include "vbo_context.h"
 
 
-#define NR_LEGACY_ATTRIBS 16
-#define NR_GENERIC_ATTRIBS 16
-#define NR_MAT_ATTRIBS 12
-
-static void init_legacy_currval(GLcontext *ctx)
-{
-   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
-   struct gl_client_array *arrays = exec->legacy_currval;
-   GLuint i;
-
-   memset(arrays, 0, sizeof(*arrays) * NR_LEGACY_ATTRIBS);
-
-   /* Set up a constant (StrideB == 0) array for each current
-    * attribute:
-    */
-   for (i = 0; i < NR_LEGACY_ATTRIBS; i++) {
-      struct gl_client_array *cl = &arrays[i];
-
-      switch (i) {
-      case VBO_ATTRIB_EDGEFLAG:
-        cl->Type = GL_UNSIGNED_BYTE;
-        cl->Ptr = (const void *)&ctx->Current.EdgeFlag;
-        break;
-      case VBO_ATTRIB_INDEX:
-        cl->Type = GL_FLOAT;
-        cl->Ptr = (const void *)&ctx->Current.Index;
-        break;
-      default:
-        cl->Type = GL_FLOAT;
-        cl->Ptr = (const void *)ctx->Current.Attrib[i];
-        break;
-      }
-
-      /* This will have to be determined at runtime:
-       */
-      cl->Size = 1;
-      cl->Stride = 0;
-      cl->StrideB = 0;
-      cl->Enabled = 1;
-      cl->BufferObj = ctx->Array.NullBufferObj;
-   }
-}
-
-
-static void init_generic_currval(GLcontext *ctx)
-{
-   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
-   struct gl_client_array *arrays = exec->generic_currval;
-   GLuint i;
-
-   memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS);
-
-   for (i = 0; i < NR_GENERIC_ATTRIBS; i++) {
-      struct gl_client_array *cl = &arrays[i];
-
-      /* This will have to be determined at runtime:
-       */
-      cl->Size = 1;
-
-      cl->Type = GL_FLOAT;
-      cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i];
-      cl->Stride = 0;
-      cl->StrideB = 0;
-      cl->Enabled = 1;
-      cl->BufferObj = ctx->Array.NullBufferObj;
-   }
-}
-
-
-static void init_mat_currval(GLcontext *ctx)
-{
-   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
-   struct gl_client_array *arrays = exec->mat_currval;
-   GLuint i;
-
-   memset(arrays, 0, sizeof(*arrays) * NR_GENERIC_ATTRIBS);
-
-   /* Set up a constant (StrideB == 0) array for each current
-    * attribute:
-    */
-   for (i = 0; i < NR_GENERIC_ATTRIBS; i++) {
-      struct gl_client_array *cl = &arrays[i];
-
-      /* Size is fixed for the material attributes, for others will
-       * be determined at runtime:
-       */
-      switch (i - VERT_ATTRIB_GENERIC0) {
-      case MAT_ATTRIB_FRONT_SHININESS:
-      case MAT_ATTRIB_BACK_SHININESS:
-        cl->Size = 1;
-        break;
-      case MAT_ATTRIB_FRONT_INDEXES:
-      case MAT_ATTRIB_BACK_INDEXES:
-        cl->Size = 3;
-        break;
-      default:
-        cl->Size = 4;
-        break;
-      }
-
-      if (i < MAT_ATTRIB_MAX)
-        cl->Ptr = (const void *)ctx->Light.Material.Attrib[i];
-      else 
-        cl->Ptr = (const void *)ctx->Current.Attrib[VERT_ATTRIB_GENERIC0 + i];
-
-      cl->Type = GL_FLOAT;
-      cl->Stride = 0;
-      cl->StrideB = 0;
-      cl->Enabled = 1;
-      cl->BufferObj = ctx->Array.NullBufferObj;
-   }
-}
-
 
-void vbo_exec_init( GLcontext *ctx )
+void vbo_exec_init( struct gl_context *ctx )
 {
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
@@ -167,19 +49,20 @@ void vbo_exec_init( GLcontext *ctx )
    vbo_exec_vtx_init( exec );
    vbo_exec_array_init( exec );
 
-   init_legacy_currval( ctx );
-   init_generic_currval( ctx );
-   init_mat_currval( ctx );
+   /* Hook our functions into exec and compile dispatch tables.
+    */
+   _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt );
 
    ctx->Driver.NeedFlush = 0;
    ctx->Driver.CurrentExecPrimitive = PRIM_OUTSIDE_BEGIN_END;
+   ctx->Driver.BeginVertices = vbo_exec_BeginVertices;
    ctx->Driver.FlushVertices = vbo_exec_FlushVertices;
 
-   exec->eval.recalculate_maps = 1;
+   vbo_exec_invalidate_state( ctx, ~0 );
 }
 
 
-void vbo_exec_destroy( GLcontext *ctx )
+void vbo_exec_destroy( struct gl_context *ctx )
 {
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
@@ -192,14 +75,20 @@ void vbo_exec_destroy( GLcontext *ctx )
    vbo_exec_array_destroy( exec );
 }
 
-/* Really want to install these callbacks to a central facility to be
+
+/**
+ * Really want to install these callbacks to a central facility to be
  * invoked according to the state flags.  That will have to wait for a
  * mesa rework:
  */ 
-void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state )
+void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state )
 {
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
+   if (new_state & (_NEW_PROGRAM|_NEW_ARRAY)) {
+      exec->array.recalculate_inputs = GL_TRUE;
+   }
+
    if (new_state & (_NEW_PROGRAM|_NEW_EVAL))
       exec->eval.recalculate_maps = 1;
 
@@ -207,21 +96,49 @@ void vbo_exec_invalidate_state( GLcontext *ctx, GLuint new_state )
 }
 
 
-void vbo_exec_wakeup( GLcontext *ctx )
+/**
+ * Figure out the number of transform feedback primitives that will be output
+ * by the given _mesa_prim command, assuming that no geometry shading is done
+ * and primitive restart is not used.
+ *
+ * This is intended for use by driver back-ends in implementing the
+ * PRIMITIVES_GENERATED and TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN queries.
+ */
+size_t
+count_tessellated_primitives(const struct _mesa_prim *prim)
 {
-   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
-
-   ctx->Driver.FlushVertices = vbo_exec_FlushVertices;
-   ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
-
-   /* Hook our functions into exec and compile dispatch tables.
-    */
-   _mesa_install_exec_vtxfmt( ctx, &exec->vtxfmt );
-
-   /* Assume we haven't been getting state updates either:
-    */
-   vbo_exec_invalidate_state( ctx, ~0 );
+   size_t num_primitives;
+   switch (prim->mode) {
+   case GL_POINTS:
+      num_primitives = prim->count;
+      break;
+   case GL_LINE_STRIP:
+      num_primitives = prim->count >= 2 ? prim->count - 1 : 0;
+      break;
+   case GL_LINE_LOOP:
+      num_primitives = prim->count >= 2 ? prim->count : 0;
+      break;
+   case GL_LINES:
+      num_primitives = prim->count / 2;
+      break;
+   case GL_TRIANGLE_STRIP:
+   case GL_TRIANGLE_FAN:
+   case GL_POLYGON:
+      num_primitives = prim->count >= 3 ? prim->count - 2 : 0;
+      break;
+   case GL_TRIANGLES:
+      num_primitives = prim->count / 3;
+      break;
+   case GL_QUAD_STRIP:
+      num_primitives = prim->count >= 4 ? ((prim->count / 2) - 1) * 2 : 0;
+      break;
+   case GL_QUADS:
+      num_primitives = (prim->count / 4) * 2;
+      break;
+   default:
+      assert(!"Unexpected primitive type in count_tessellated_primitives");
+      num_primitives = 0;
+      break;
+   }
+   return num_primitives * prim->num_instances;
 }
-
-
-