vbo: clean-ups, reformatting
[mesa.git] / src / mesa / vbo / vbo_exec_api.c
index 1ba39c8aa20b8c087e539b833c4fe43083e84da0..bfa6d76886a36ad5c207895d51638e133befe5e8 100644 (file)
@@ -35,9 +35,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/context.h"
 #include "main/macros.h"
 #include "main/vtxfmt.h"
-#if FEATURE_dlist
 #include "main/dlist.h"
-#endif
+#include "main/eval.h"
 #include "main/state.h"
 #include "main/light.h"
 #include "main/api_arrayelt.h"
@@ -51,6 +50,10 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #endif
 
 
+/** ID/name for immediate-mode VBO */
+#define IMM_BUFFER_NAME 0xaabbccdd
+
+
 static void reset_attrfv( struct vbo_exec_context *exec );
 
 
@@ -156,7 +159,6 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
          if (memcmp(current, tmp, sizeof(tmp)) != 0)
          { 
             memcpy(current, tmp, sizeof(tmp));
-
         
             /* Given that we explicitly state size here, there is no need
              * for the COPY_CLEAN above, could just copy 16 bytes and be
@@ -184,8 +186,6 @@ static void vbo_exec_copy_to_current( struct vbo_exec_context *exec )
       _mesa_update_color_material(ctx, 
                                  ctx->Current.Attrib[VBO_ATTRIB_COLOR0]);
    }
-
-   ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
 }
 
 
@@ -205,8 +205,6 @@ static void vbo_exec_copy_from_current( struct vbo_exec_context *exec )
         break;
       }
    }
-
-   ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
 }
 
 
@@ -347,12 +345,10 @@ static void vbo_exec_fixup_vertex( GLcontext *ctx,
     */
    if (attr == 0) 
       exec->ctx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
-   else 
-      exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
 }
 
 
-
+#if FEATURE_beginend
 
 /* 
  */
@@ -395,6 +391,7 @@ do {                                                                \
 
 
 
+#if FEATURE_evaluators
 /* Eval
  */
 static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u )
@@ -488,22 +485,11 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )
    vbo_exec_EvalCoord2f( u, v );
 }
 
+/* use noop eval mesh */
+#define vbo_exec_EvalMesh1 _mesa_noop_EvalMesh1
+#define vbo_exec_EvalMesh2 _mesa_noop_EvalMesh2
 
-/**
- * Check if programs/shaders are enabled and valid at glBegin time.
- */
-GLboolean 
-vbo_validate_shaders(GLcontext *ctx)
-{
-   if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
-       (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
-      return GL_FALSE;
-   }
-   if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) {
-      return GL_FALSE;
-   }
-   return GL_TRUE;
-}
+#endif /* FEATURE_evaluators */
 
 
 /* Build a list of primitives on the fly.  Keep
@@ -524,9 +510,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
         return;
       }
 
-      if (!vbo_validate_shaders(ctx)) {
-         _mesa_error(ctx, GL_INVALID_OPERATION,
-                     "glBegin (invalid vertex/fragment program)");
+      if (!_mesa_valid_to_render(ctx, "glBegin")) {
          return;
       }
 
@@ -579,24 +563,15 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
 {
    GLvertexformat *vfmt = &exec->vtxfmt;
 
-   vfmt->ArrayElement = _ae_loopback_array_elt;                /* generic helper */
+   _MESA_INIT_ARRAYELT_VTXFMT(vfmt, _ae_);
+
    vfmt->Begin = vbo_exec_Begin;
-#if FEATURE_dlist
-   vfmt->CallList = _mesa_CallList;
-   vfmt->CallLists = _mesa_CallLists;
-#endif
    vfmt->End = vbo_exec_End;
-   vfmt->EvalCoord1f = vbo_exec_EvalCoord1f;
-   vfmt->EvalCoord1fv = vbo_exec_EvalCoord1fv;
-   vfmt->EvalCoord2f = vbo_exec_EvalCoord2f;
-   vfmt->EvalCoord2fv = vbo_exec_EvalCoord2fv;
-   vfmt->EvalPoint1 = vbo_exec_EvalPoint1;
-   vfmt->EvalPoint2 = vbo_exec_EvalPoint2;
 
-   vfmt->Rectf = _mesa_noop_Rectf;
-   vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
-   vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
+   _MESA_INIT_DLIST_VTXFMT(vfmt, _mesa_);
+   _MESA_INIT_EVAL_VTXFMT(vfmt, vbo_exec_);
 
+   vfmt->Rectf = _mesa_noop_Rectf;
 
    /* from attrib_tmp.h:
     */
@@ -660,6 +635,98 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
 }
 
 
+#else /* FEATURE_beginend */
+
+
+#define ATTR( A, N, V0, V1, V2, V3 )                           \
+do {                                                           \
+   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;    \
+                                                               \
+   /* FLUSH_UPDATE_CURRENT needs to be set manually */         \
+   exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;                \
+                                                               \
+   if (exec->vtx.active_sz[A] != N)                            \
+      vbo_exec_fixup_vertex(ctx, A, N);                                \
+                                                               \
+   {                                                           \
+      GLfloat *dest = exec->vtx.attrptr[A];                    \
+      if (N>0) dest[0] = V0;                                   \
+      if (N>1) dest[1] = V1;                                   \
+      if (N>2) dest[2] = V2;                                   \
+      if (N>3) dest[3] = V3;                                   \
+   }                                                           \
+} while (0)
+
+#define ERROR() _mesa_error( ctx, GL_INVALID_ENUM, __FUNCTION__ )
+#define TAG(x) vbo_##x
+
+#include "vbo_attrib_tmp.h"
+
+static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
+{
+   /* silence warnings */
+   (void) vbo_Color3f;
+   (void) vbo_Color3fv;
+   (void) vbo_Color4f;
+   (void) vbo_Color4fv;
+   (void) vbo_FogCoordfEXT;
+   (void) vbo_FogCoordfvEXT;
+   (void) vbo_MultiTexCoord1f;
+   (void) vbo_MultiTexCoord1fv;
+   (void) vbo_MultiTexCoord2f;
+   (void) vbo_MultiTexCoord2fv;
+   (void) vbo_MultiTexCoord3f;
+   (void) vbo_MultiTexCoord3fv;
+   (void) vbo_MultiTexCoord4f;
+   (void) vbo_MultiTexCoord4fv;
+   (void) vbo_Normal3f;
+   (void) vbo_Normal3fv;
+   (void) vbo_SecondaryColor3fEXT;
+   (void) vbo_SecondaryColor3fvEXT;
+   (void) vbo_TexCoord1f;
+   (void) vbo_TexCoord1fv;
+   (void) vbo_TexCoord2f;
+   (void) vbo_TexCoord2fv;
+   (void) vbo_TexCoord3f;
+   (void) vbo_TexCoord3fv;
+   (void) vbo_TexCoord4f;
+   (void) vbo_TexCoord4fv;
+   (void) vbo_Vertex2f;
+   (void) vbo_Vertex2fv;
+   (void) vbo_Vertex3f;
+   (void) vbo_Vertex3fv;
+   (void) vbo_Vertex4f;
+   (void) vbo_Vertex4fv;
+
+   (void) vbo_VertexAttrib1fARB;
+   (void) vbo_VertexAttrib1fvARB;
+   (void) vbo_VertexAttrib2fARB;
+   (void) vbo_VertexAttrib2fvARB;
+   (void) vbo_VertexAttrib3fARB;
+   (void) vbo_VertexAttrib3fvARB;
+   (void) vbo_VertexAttrib4fARB;
+   (void) vbo_VertexAttrib4fvARB;
+
+   (void) vbo_VertexAttrib1fNV;
+   (void) vbo_VertexAttrib1fvNV;
+   (void) vbo_VertexAttrib2fNV;
+   (void) vbo_VertexAttrib2fvNV;
+   (void) vbo_VertexAttrib3fNV;
+   (void) vbo_VertexAttrib3fvNV;
+   (void) vbo_VertexAttrib4fNV;
+   (void) vbo_VertexAttrib4fvNV;
+
+   (void) vbo_Materialfv;
+
+   (void) vbo_EdgeFlag;
+   (void) vbo_Indexf;
+   (void) vbo_Indexfv;
+}
+
+
+#endif /* FEATURE_beginend */
+
+
 /**
  * Tell the VBO module to use a real OpenGL vertex buffer object to
  * store accumulated immediate-mode vertex data.
@@ -672,16 +739,17 @@ void vbo_use_buffer_objects(GLcontext *ctx)
    /* Any buffer name but 0 can be used here since this bufferobj won't
     * go into the bufferobj hashtable.
     */
-   GLuint bufName = 0xaabbccdd;
+   GLuint bufName = IMM_BUFFER_NAME;
    GLenum target = GL_ARRAY_BUFFER_ARB;
    GLenum usage = GL_STREAM_DRAW_ARB;
    GLsizei size = VBO_VERT_BUFFER_SIZE;
 
    /* Make sure this func is only used once */
-   assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);
+   assert(exec->vtx.bufferobj == ctx->Shared->NullBufferObj);
    if (exec->vtx.buffer_map) {
       _mesa_align_free(exec->vtx.buffer_map);
       exec->vtx.buffer_map = NULL;
+      exec->vtx.buffer_ptr = NULL;
    }
 
    /* Allocate a real buffer object now */
@@ -703,9 +771,11 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
     */
    _mesa_reference_buffer_object(ctx,
                                  &exec->vtx.bufferobj,
-                                 ctx->Array.NullBufferObj);
+                                 ctx->Shared->NullBufferObj);
 
+   ASSERT(!exec->vtx.buffer_map);
    exec->vtx.buffer_map = (GLfloat *)ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE, 64);
+   exec->vtx.buffer_ptr = exec->vtx.buffer_map;
 
    vbo_exec_vtxfmt_init( exec );
 
@@ -731,18 +801,33 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
 
 void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
 {
+   /* using a real VBO for vertex data */
    GLcontext *ctx = exec->ctx;
-   if (exec->vtx.bufferobj->Name) {
-      ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER_ARB, exec->vtx.bufferobj);
-      ctx->Driver.DeleteBuffer(ctx, exec->vtx.bufferobj);
-      exec->vtx.bufferobj = NULL;
-   }
-   else {
-      if (exec->vtx.buffer_map) {
+   unsigned i;
+
+   /* True VBOs should already be unmapped
+    */
+   if (exec->vtx.buffer_map) {
+      ASSERT(exec->vtx.bufferobj->Name == 0 ||
+             exec->vtx.bufferobj->Name == IMM_BUFFER_NAME);
+      if (exec->vtx.bufferobj->Name == 0) {
          ALIGN_FREE(exec->vtx.buffer_map);
          exec->vtx.buffer_map = NULL;
+         exec->vtx.buffer_ptr = NULL;
       }
    }
+
+   /* Drop any outstanding reference to the vertex buffer
+    */
+   for (i = 0; i < Elements(exec->vtx.arrays); i++) {
+      _mesa_reference_buffer_object(ctx,
+                                    &exec->vtx.arrays[i].BufferObj,
+                                    NULL);
+   }
+
+   /* Free the vertex buffer:
+    */
+   _mesa_reference_buffer_object(ctx, &exec->vtx.bufferobj, NULL);
 }
 
 void vbo_exec_BeginVertices( GLcontext *ctx )
@@ -750,6 +835,9 @@ void vbo_exec_BeginVertices( GLcontext *ctx )
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
    if (0) _mesa_printf("%s\n", __FUNCTION__);
    vbo_exec_vtx_map( exec );
+
+   assert((exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) == 0);
+   exec->ctx->Driver.NeedFlush |= FLUSH_UPDATE_CURRENT;
 }
 
 void vbo_exec_FlushVertices_internal( GLcontext *ctx, GLboolean unmap )
@@ -783,9 +871,12 @@ void vbo_exec_FlushVertices( GLcontext *ctx, GLuint flags )
 
    /* Need to do this to ensure BeginVertices gets called again:
     */
-   _mesa_restore_exec_vtxfmt( ctx );
+   if (exec->ctx->Driver.NeedFlush & FLUSH_UPDATE_CURRENT) {
+      _mesa_restore_exec_vtxfmt( ctx );
+      exec->ctx->Driver.NeedFlush &= ~FLUSH_UPDATE_CURRENT;
+   }
 
-   exec->ctx->Driver.NeedFlush = 0;
+   exec->ctx->Driver.NeedFlush &= ~flags;
 }