Cell: generalize the batch buffer code for vertex buffers...
[mesa.git] / src / mesa / vbo / vbo_exec_api.c
index c30fd18e2d656ba42a48020ed25c6c7d6b9dc691..b7f4d8a3075ffd82b3b6fe31f97533b87e74f2e6 100644 (file)
@@ -30,19 +30,24 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  *   Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "macros.h"
-#include "vtxfmt.h"
-#include "dlist.h"
-#include "state.h"
-#include "light.h"
-#include "api_arrayelt.h"
-#include "api_noop.h"
-#include "dispatch.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/macros.h"
+#include "main/vtxfmt.h"
+#include "main/dlist.h"
+#include "main/state.h"
+#include "main/light.h"
+#include "main/api_arrayelt.h"
+#include "main/api_noop.h"
+#include "glapi/dispatch.h"
 
 #include "vbo_context.h"
 
+#ifdef ERROR
+#undef ERROR
+#endif
+
+
 static void reset_attrfv( struct vbo_exec_context *exec );
 
 
@@ -390,7 +395,7 @@ static void GLAPIENTRY vbo_exec_EvalCoord1f( GLfloat u )
       if (exec->eval.recalculate_maps) 
         vbo_exec_eval_update( exec );
 
-      for (i = 0 ; i <= VBO_ATTRIB_INDEX ; i++) {
+      for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
         if (exec->eval.map1[i].map) 
            if (exec->vtx.active_sz[i] != exec->eval.map1[i].sz)
               vbo_exec_fixup_vertex( ctx, i, exec->eval.map1[i].sz );
@@ -417,7 +422,7 @@ static void GLAPIENTRY vbo_exec_EvalCoord2f( GLfloat u, GLfloat v )
       if (exec->eval.recalculate_maps) 
         vbo_exec_eval_update( exec );
 
-      for (i = 0 ; i <= VBO_ATTRIB_INDEX ; i++) {
+      for (i = 0; i <= VBO_ATTRIB_TEX7; i++) {
         if (exec->eval.map2[i].map) 
            if (exec->vtx.active_sz[i] != exec->eval.map2[i].sz)
               vbo_exec_fixup_vertex( ctx, i, exec->eval.map2[i].sz );
@@ -626,6 +631,41 @@ static void vbo_exec_vtxfmt_init( struct vbo_exec_context *exec )
 }
 
 
+/**
+ * Tell the VBO module to use a real OpenGL vertex buffer object to
+ * store accumulated immediate-mode vertex data.
+ * This replaces the malloced buffer which was created in
+ * vb_exec_vtx_init() below.
+ */
+void vbo_use_buffer_objects(GLcontext *ctx)
+{
+   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
+   /* Any buffer name but 0 can be used here since this bufferobj won't
+    * go into the bufferobj hashtable.
+    */
+   GLuint bufName = 0xaabbccdd;
+   GLenum target = GL_ARRAY_BUFFER_ARB;
+   GLenum access = GL_READ_WRITE_ARB;
+   GLenum usage = GL_STREAM_DRAW_ARB;
+   GLsizei size = VBO_VERT_BUFFER_SIZE * sizeof(GLfloat);
+
+   /* Make sure this func is only used once */
+   assert(exec->vtx.bufferobj == ctx->Array.NullBufferObj);
+   if (exec->vtx.buffer_map) {
+      _mesa_align_free(exec->vtx.buffer_map);
+   }
+
+   /* Allocate a real buffer object now */
+   exec->vtx.bufferobj = ctx->Driver.NewBufferObject(ctx, bufName, target);
+   ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
+
+   /* and map it */
+   exec->vtx.buffer_map
+      = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
+}
+
+
+
 void vbo_exec_vtx_init( struct vbo_exec_context *exec )
 {
    GLcontext *ctx = exec->ctx;
@@ -633,7 +673,8 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
    GLuint i;
 
    /* Allocate a buffer object.  Will just reuse this object
-    * continuously.
+    * continuously, unless vbo_use_buffer_objects() is called to enable
+    * use of real VBOs.
     */
    exec->vtx.bufferobj = ctx->Array.NullBufferObj;
    exec->vtx.buffer_map = ALIGN_MALLOC(VBO_VERT_BUFFER_SIZE * sizeof(GLfloat), 64);
@@ -662,9 +703,17 @@ void vbo_exec_vtx_init( struct vbo_exec_context *exec )
 
 void vbo_exec_vtx_destroy( struct vbo_exec_context *exec )
 {
-   if (exec->vtx.buffer_map) {
-      ALIGN_FREE(exec->vtx.buffer_map);
-      exec->vtx.buffer_map = NULL;
+   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) {
+         ALIGN_FREE(exec->vtx.buffer_map);
+         exec->vtx.buffer_map = NULL;
+      }
    }
 }