mesa/i965/i915/r200: eliminate gl_vertex_program
[mesa.git] / src / mesa / vbo / vbo_exec_draw.c
index 174cbc37c269567403207a66e628e67943ad4675..19114daa6ad08679ac7aad48fcac26324a6808d0 100644 (file)
@@ -25,6 +25,7 @@
  *    Keith Whitwell <keithw@vmware.com>
  */
 
+#include <stdbool.h>
 #include <stdio.h>
 #include "main/glheader.h"
 #include "main/bufferobj.h"
@@ -64,20 +65,23 @@ vbo_exec_debug_verts( struct vbo_exec_context *exec )
 }
 
 
-/*
- * NOTE: Need to have calculated primitives by this point -- do it on the fly.
- * NOTE: Old 'parity' issue is gone.
+/**
+ * Copy zero, one or two vertices from the current vertex buffer into
+ * the temporary "copy" buffer.
+ * This is used when a single primitive overflows a vertex buffer and
+ * we need to continue the primitive in a new vertex buffer.
+ * The temporary "copy" buffer holds the vertices which need to get
+ * copied from the old buffer to the new one.
  */
 static GLuint
 vbo_copy_vertices( struct vbo_exec_context *exec )
 {
-   GLuint nr = exec->vtx.prim[exec->vtx.prim_count-1].count;
+   struct _mesa_prim *last_prim = &exec->vtx.prim[exec->vtx.prim_count - 1];
+   const GLuint nr = last_prim->count;
    GLuint ovf, i;
-   GLuint sz = exec->vtx.vertex_size;
+   const GLuint sz = exec->vtx.vertex_size;
    fi_type *dst = exec->vtx.copied.buffer;
-   const fi_type *src = (exec->vtx.buffer_map +
-                         exec->vtx.prim[exec->vtx.prim_count-1].start * 
-                         exec->vtx.vertex_size);
+   const fi_type *src = exec->vtx.buffer_map + last_prim->start * sz;
 
    switch (exec->ctx->Driver.CurrentExecPrimitive) {
    case GL_POINTS:
@@ -106,6 +110,18 @@ vbo_copy_vertices( struct vbo_exec_context *exec )
         return 1;
       }
    case GL_LINE_LOOP:
+      if (last_prim->begin == 0) {
+         /* We're dealing with the second or later section of a split/wrapped
+          * GL_LINE_LOOP.  Since we're converting line loops to line strips,
+          * we've already increment the last_prim->start counter by one to
+          * skip the 0th vertex in the loop.  We need to undo that (effectively
+          * subtract one from last_prim->start) so that we copy the 0th vertex
+          * to the next vertex buffer.
+          */
+         assert(last_prim->start > 0);
+         src -= sz;
+      }
+      /* fall-through */
    case GL_TRIANGLE_FAN:
    case GL_POLYGON:
       if (nr == 0) {
@@ -123,7 +139,7 @@ vbo_copy_vertices( struct vbo_exec_context *exec )
    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--;
+        last_prim->count--;
       }
       /* fallthrough */
    case GL_QUAD_STRIP:
@@ -162,6 +178,7 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
    const GLuint *map;
    GLuint attr;
    GLbitfield64 varying_inputs = 0x0;
+   bool swap_pos = false;
 
    /* Install the default (ie Current) attributes first, then overlay
     * all active ones.
@@ -192,11 +209,14 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
       /* check if VERT_ATTRIB_POS is not read but VERT_BIT_GENERIC0 is read.
        * In that case we effectively need to route the data from
        * glVertexAttrib(0, val) calls to feed into the GENERIC0 input.
+       * The original state gets essentially restored below.
        */
-      if ((ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_POS) == 0 &&
-          (ctx->VertexProgram._Current->Base.InputsRead & VERT_BIT_GENERIC0)) {
+      if ((ctx->VertexProgram._Current->InputsRead & VERT_BIT_POS) == 0 &&
+          (ctx->VertexProgram._Current->InputsRead & VERT_BIT_GENERIC0)) {
+         swap_pos = true;
          exec->vtx.inputs[VERT_ATTRIB_GENERIC0] = exec->vtx.inputs[0];
          exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = exec->vtx.attrsz[0];
+         exec->vtx.attrtype[VERT_ATTRIB_GENERIC0] = exec->vtx.attrtype[0];
          exec->vtx.attrptr[VERT_ATTRIB_GENERIC0] = exec->vtx.attrptr[0];
          exec->vtx.attrsz[0] = 0;
       }
@@ -230,12 +250,10 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
          }
         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 = exec->vtx.attrtype[src];
         arrays[attr].Integer =
                vbo_attrtype_to_integer_flag(exec->vtx.attrtype[src]);
          arrays[attr].Format = GL_RGBA;
-        arrays[attr].Enabled = 1;
          arrays[attr]._ElementSize = arrays[attr].Size * sizeof(GLfloat);
          _mesa_reference_buffer_object(ctx,
                                        &arrays[attr].BufferObj,
@@ -245,6 +263,16 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
       }
    }
 
+   /* In case we swapped the position and generic0 attribute.
+    * Restore the original setting of the vtx.* variables.
+    * They are still needed with the original order and settings in case
+    * of a split primitive.
+    */
+   if (swap_pos) {
+      exec->vtx.attrsz[0] = exec->vtx.attrsz[VERT_ATTRIB_GENERIC0];
+      exec->vtx.attrsz[VERT_ATTRIB_GENERIC0] = 0;
+   }
+
    _mesa_set_varying_vp_inputs( ctx, varying_inputs );
    ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 }
@@ -432,8 +460,7 @@ vbo_exec_vtx_flush(struct vbo_exec_context *exec, GLboolean keepUnmapped)
    if (keepUnmapped || exec->vtx.vertex_size == 0)
       exec->vtx.max_vert = 0;
    else
-      exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
-                            (exec->vtx.vertex_size * sizeof(GLfloat)));
+      exec->vtx.max_vert = vbo_compute_max_verts(exec);
 
    exec->vtx.buffer_ptr = exec->vtx.buffer_map;
    exec->vtx.prim_count = 0;