vbo: signal _NEW_ARRAY when transitioning between glBegin/End, glDrawArrays
authorBrian Paul <brianp@vmware.com>
Mon, 26 Dec 2011 21:43:07 +0000 (14:43 -0700)
committerBrian Paul <brianp@vmware.com>
Mon, 26 Dec 2011 22:21:32 +0000 (15:21 -0700)
This fixes a regression seen with the isosurf demo when switching between
glBegin/End and glDrawArrays (do it several times).  The problem was the
driver wasn't getting _NEW_ARRAY when the arrays were subtly changed:
(vertex3f, normal3f) vs. (normal3f, vertex3f).

This patch fixes that by signaling _NEW_ARRAY whenever we transition
between glBegin/End and glDrawArrays mode and display lists.

The patch also fixes up the initialization of the map_vp_none[] array
to stop putting strange values in the last five elements of the array.

v2: remove DRAW_ELEMENTS, don't distinguish between glDrawArrays and
glDrawElements

v3: add DRAW_DISPLAY_LIST for the display list case, just to be safe.

Reviewed-by: Mathias Froehlich <Mathias.Froehlich@web.de>
Tested-by: Mathias Froehlich <Mathias.Froehlich@web.de>
src/mesa/vbo/vbo_context.c
src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_api.c
src/mesa/vbo/vbo_exec_array.c
src/mesa/vbo/vbo_save_draw.c

index b2e6bbc12fb7aa4ad0a7f0c3d1680148066f71b8..d83f2fd23a5088382853ee2025d4839e034a12cd 100644 (file)
@@ -176,17 +176,14 @@ GLboolean _vbo_CreateContext( struct gl_context *ctx )
    {
       GLuint i;
 
-      /* When no vertex program, pull in the material attributes in
-       * the generic range.
-       */
-      for (i = 0; i < VERT_ATTRIB_FF_MAX; i++) 
+      /* identity mapping */
+      for (i = 0; i < Elements(vbo->map_vp_none); i++) 
         vbo->map_vp_none[i] = i;
+      /* map material attribs to generic slots */
       for (i = 0; i < NR_MAT_ATTRIBS; i++) 
         vbo->map_vp_none[VERT_ATTRIB_GENERIC(i)]
             = VBO_ATTRIB_MAT_FRONT_AMBIENT + i;
-      for (i = NR_MAT_ATTRIBS; i < VERT_ATTRIB_GENERIC_MAX; i++)
-        vbo->map_vp_none[VERT_ATTRIB_GENERIC(i)] = i;
-      
+
       for (i = 0; i < Elements(vbo->map_vp_arb); i++)
         vbo->map_vp_arb[i] = i;
    }
index cfed8e86dc0a24105201ea542b5a38ffebe6e444..e85798da4c4dc7280b2d9020333e2c122c5985a3 100644 (file)
@@ -78,12 +78,26 @@ struct vbo_exec_copied_vtx {
 };
 
 
+/** Used to signal when transitioning from one kind of drawing method
+ * to another.
+ */
+enum draw_method
+{
+   DRAW_NONE,          /**< Initial value only */
+   DRAW_BEGIN_END,
+   DRAW_DISPLAY_LIST,
+   DRAW_ARRAYS
+};
+
+
 struct vbo_exec_context
 {
    struct gl_context *ctx;   
    GLvertexformat vtxfmt;
    GLvertexformat vtxfmt_noop;
 
+   enum draw_method last_draw_method;
+
    struct {
       struct gl_buffer_object *bufferobj;
 
@@ -164,6 +178,28 @@ void vbo_exec_array_destroy( struct vbo_exec_context *exec );
 void vbo_exec_vtx_init( struct vbo_exec_context *exec );
 void vbo_exec_vtx_destroy( struct vbo_exec_context *exec );
 
+
+/**
+ * This is called by glBegin, glDrawArrays and glDrawElements (and
+ * variations of those calls).  When we transition from immediate mode
+ * drawing to array drawing we need to invalidate the array state.
+ *
+ * glBegin/End builds vertex arrays.  Those arrays may look identical
+ * to glDrawArrays arrays except that the position of the elements may
+ * be different.  For example, arrays of (position3v, normal3f) vs. arrays
+ * of (normal3f, position3f).  So we need to make sure we notify drivers
+ * that arrays may be changing.
+ */
+static inline void
+vbo_draw_method(struct vbo_exec_context *exec, enum draw_method method)
+{
+   if (exec->last_draw_method != method) {
+      exec->ctx->NewState |= _NEW_ARRAY;
+      exec->last_draw_method = method;
+   }
+}
+
+
 #if FEATURE_beginend
 
 void vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap );
index 4be016925c960d1c9d292e15b56182d6c60db976..cb5f9ae522b2673b91778193f3f7599ad07a503b 100644 (file)
@@ -701,6 +701,8 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
          return;
       }
 
+      vbo_draw_method(exec, DRAW_BEGIN_END);
+
       if (ctx->Driver.PrepareExecBegin)
         ctx->Driver.PrepareExecBegin(ctx);
 
index a6e41e9c5e5a4ab23d0b5aed4a8d3bc6b603ff07..6ffdff330d771e08b49ab4e002d838293e74959e 100644 (file)
@@ -558,6 +558,8 @@ vbo_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start,
 
    vbo_bind_arrays(ctx);
 
+   vbo_draw_method(exec, DRAW_ARRAYS);
+
    /* Again... because we may have changed the bitmask of per-vertex varying
     * attributes.  If we regenerate the fixed-function vertex program now
     * we may be able to prune down the number of vertex attributes which we
@@ -773,6 +775,8 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
 
    vbo_bind_arrays( ctx );
 
+   vbo_draw_method(exec, DRAW_ARRAYS);
+
    /* check for dirty state again */
    if (ctx->NewState)
       _mesa_update_state( ctx );
index fa93ca48f438b3ff0891991c76c35a072b8c005a..9f0290561e8e9c99025624348cb921bff69ffb8e 100644 (file)
@@ -248,6 +248,7 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
    const struct vbo_save_vertex_list *node =
       (const struct vbo_save_vertex_list *) data;
    struct vbo_save_context *save = &vbo_context(ctx)->save;
+   struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
    FLUSH_CURRENT(ctx, 0);
 
@@ -286,6 +287,8 @@ vbo_save_playback_vertex_list(struct gl_context *ctx, void *data)
 
       vbo_bind_vertex_list( ctx, node );
 
+      vbo_draw_method(exec, DRAW_DISPLAY_LIST);
+
       /* Again...
        */
       if (ctx->NewState)