vbo: fix another GL_LINE_LOOP bug
authorBrian Paul <brianp@vmware.com>
Sat, 31 Oct 2015 13:02:36 +0000 (07:02 -0600)
committerBrian Paul <brianp@vmware.com>
Wed, 4 Nov 2015 18:51:59 +0000 (11:51 -0700)
Very long line loops which spanned 3 or more vertex buffers were not
handled correctly and could result in stray lines.

The piglit lineloop test draws 10000 vertices by default, and is not
long enough to trigger this.  Even 'lineloop -count 100000' doesn't
trigger the bug.

For future reference, the issue can be reproduced by changing Mesa's
VBO_VERT_BUFFER_SIZE to 4096 and changing the piglit lineloop test to
use glVertex2f(), draw 3 loops instead of 1, and specifying -count
1023.

Acked-by: Sinclair Yeh <syeh@vmware.com>
Reviewed-by: Roland Scheidegger <sroland@vmware.com>
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_draw.c

index a614b26cae4a3b02e749425896e6009b5ac8b2d5..7534599c3134b1dce00aaf581c1f41ac462b59b9 100644 (file)
@@ -114,6 +114,7 @@ static void vbo_exec_wrap_buffers( struct vbo_exec_context *exec )
       if (_mesa_inside_begin_end(exec->ctx)) {
         exec->vtx.prim[0].mode = exec->ctx->Driver.CurrentExecPrimitive;
         exec->vtx.prim[0].begin = 0;
+         exec->vtx.prim[0].end = 0;
         exec->vtx.prim[0].start = 0;
         exec->vtx.prim[0].count = 0;
         exec->vtx.prim_count++;
@@ -846,17 +847,23 @@ static void GLAPIENTRY vbo_exec_End( void )
          /* We're finishing drawing a line loop.  Append 0th vertex onto
           * end of vertex buffer so we can draw it as a line strip.
           */
-         const fi_type *src = exec->vtx.buffer_map;
+         const fi_type *src = exec->vtx.buffer_map +
+            last_prim->start * exec->vtx.vertex_size;
          fi_type *dst = exec->vtx.buffer_map +
             exec->vtx.vert_count * exec->vtx.vertex_size;
 
          /* copy 0th vertex to end of buffer */
          memcpy(dst, src, exec->vtx.vertex_size * sizeof(fi_type));
 
-         assert(last_prim->start == 0);
          last_prim->start++;  /* skip vertex0 */
          /* note that last_prim->count stays unchanged */
          last_prim->mode = GL_LINE_STRIP;
+
+         /* Increment the vertex count so the next primitive doesn't
+          * overwrite the last vertex which we just added.
+          */
+         exec->vtx.vert_count++;
+         exec->vtx.buffer_ptr += exec->vtx.vertex_size;
       }
 
       try_vbo_merge(exec);
index ed5d9e947b07580fcf38565a45c566cef76b4451..0d42618f2469f2992025d82ee511c1898a859261 100644 (file)
@@ -117,6 +117,7 @@ vbo_copy_vertices( struct vbo_exec_context *exec )
           * 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 */