Cell: generalize the batch buffer code for vertex buffers...
[mesa.git] / src / mesa / vbo / vbo_exec_draw.c
index 846d5dc196cee4f59d2261c438907fda282405e8..23a3658386c2cd270610e3b7d99585548b529d49 100644 (file)
  *    Keith Whitwell <keith@tungstengraphics.com>
  */
 
-#include "glheader.h"
-#include "context.h"
-#include "enums.h"
-#include "state.h"
-#include "macros.h"
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/enums.h"
+#include "main/state.h"
+#include "main/macros.h"
 
 #include "vbo_context.h"
 
@@ -114,6 +114,11 @@ static GLuint vbo_copy_vertices( struct vbo_exec_context *exec )
         return 2;
       }
    case GL_TRIANGLE_STRIP:
+      /* no parity issue, but need to make sure the tri is not drawn twice */
+      if (nr & 1) {
+        exec->vtx.prim[exec->vtx.prim_count-1].count--;
+      }
+      /* fallthrough */
    case GL_QUAD_STRIP:
       switch (nr) {
       case 0: ovf = 0; break;
@@ -170,16 +175,27 @@ static void vbo_exec_bind_arrays( GLcontext *ctx )
     * arrays of floats.
     */
    for (attr = 0; attr < VERT_ATTRIB_MAX ; attr++) {
-      GLuint src = map[attr];
+      const GLuint src = map[attr];
 
       if (exec->vtx.attrsz[src]) {
-        arrays[attr].Ptr = (void *)data;
+         if (exec->vtx.bufferobj->Name) {
+            /* a real buffer obj: Ptr is an offset, not a pointer*/
+            int offset;
+            assert(exec->vtx.bufferobj->Pointer);  /* buf should be mapped */
+            offset = (GLbyte *) data - (GLbyte *) exec->vtx.bufferobj->Pointer;
+            assert(offset >= 0);
+            arrays[attr].Ptr = (void *) offset;
+         }
+         else {
+            /* Ptr into ordinary app memory */
+            arrays[attr].Ptr = (void *) data;
+         }
         arrays[attr].Size = exec->vtx.attrsz[src];
         arrays[attr].StrideB = exec->vtx.vertex_size * sizeof(GLfloat);
         arrays[attr].Stride = exec->vtx.vertex_size * sizeof(GLfloat);
         arrays[attr].Type = GL_FLOAT;
         arrays[attr].Enabled = 1;
-        arrays[attr].BufferObj = exec->vtx.bufferobj; /* NullBufferObj */
+        arrays[attr].BufferObj = exec->vtx.bufferobj;
         arrays[attr]._MaxElement = count; /* ??? */
 
         data += exec->vtx.attrsz[attr] * sizeof(GLfloat);
@@ -205,15 +221,31 @@ void vbo_exec_vtx_flush( struct vbo_exec_context *exec )
       if (exec->vtx.copied.nr != exec->vtx.vert_count) {
         GLcontext *ctx = exec->ctx;
 
+        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);
+        
+        /* Before the unmap (why?)
+         */
         vbo_exec_bind_arrays( ctx );
 
+        ctx->Driver.UnmapBuffer(ctx, target, exec->vtx.bufferobj);
+        exec->vtx.buffer_map = NULL;
+
         vbo_context(ctx)->draw_prims( ctx, 
                                       exec->vtx.inputs, 
                                       exec->vtx.prim, 
                                       exec->vtx.prim_count,
                                       NULL,
                                       0,
-                                      exec->vtx.vert_count );
+                                      exec->vtx.vert_count - 1);
+
+        /* Get new data:
+         */
+        ctx->Driver.BufferData(ctx, target, size, NULL, usage, exec->vtx.bufferobj);
+        exec->vtx.buffer_map
+           = ctx->Driver.MapBuffer(ctx, target, access, exec->vtx.bufferobj);
       }
    }