mesa,vbo: properly detect when vertex arrays need to be recalculated
authorMarek Olšák <maraeo@gmail.com>
Mon, 16 Apr 2012 01:34:22 +0000 (03:34 +0200)
committerMarek Olšák <maraeo@gmail.com>
Thu, 19 Apr 2012 12:47:21 +0000 (14:47 +0200)
This moves the RebindArrays flag into the vbo module, consolidates the code,
and adds missing vbo_draw_method calls.

Also with this change, the vertex arrays are not needlessly recalculated twice.
The issue with the old code was:
- If recalculate_input_bindings updates vp_varying_inputs, _NEW_ARRAY is set.
- _mesa_update_state is called and the vp_varying_inputs change causes
  regeneration of the fixed-function shaders, which also sets _NEW_PROGRAM.
- The occurence of either _NEW_ARRAY or _NEW_PROGRAM sets
  the recalculate_inputs flag to TRUE again.
- The new code sets the flag to FALSE after the second _mesa_update_state,
  because there can't possibly be any change which would require recalculating
  the arrays.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
src/mesa/main/attrib.c
src/mesa/main/mtypes.h
src/mesa/main/state.c
src/mesa/vbo/vbo_exec.c
src/mesa/vbo/vbo_exec.h
src/mesa/vbo/vbo_exec_array.c

index 7042312a8f507299915a0e38f63e3151ce6ba54f..9b90b05f7dd56ee423d6dcdcf45490a692663775 100644 (file)
@@ -1448,9 +1448,6 @@ restore_array_attrib(struct gl_context *ctx,
       _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
                          src->ArrayObj->ElementArrayBufferObj->Name);
 
-   /* Better safe than sorry?! */
-   dest->RebindArrays = GL_TRUE;
-
    /* FIXME: Should some bits in ctx->Array->NewState also be set
     * FIXME: here?  It seems like it should be set to inclusive-or
     * FIXME: of the old ArrayObj->_Enabled and the new _Enabled.
index bfa320a52d7ddb0a1f7b2a60c1ddcd97fae0fd2d..e1afdbc9090982068d03fe6b2849f3bc042d312b 100644 (file)
@@ -1632,7 +1632,6 @@ struct gl_array_attrib
    GLuint RestartIndex;
 
    GLbitfield64 NewState;              /**< mask of VERT_BIT_* values */
-   GLboolean RebindArrays; /**< whether the VBO module should rebind arrays */
 
    /* GL_ARB_vertex_buffer_object */
    struct gl_buffer_object *ArrayBufferObj;
index 2e9f021619f5533b695c49ff447f42bb912fe5d9..c953efc81273baf98cfe1d591b011750cc7ac919 100644 (file)
@@ -582,8 +582,6 @@ _mesa_update_state_locked( struct gl_context *ctx )
    ctx->NewState = 0;
    ctx->Driver.UpdateState(ctx, new_state);
    ctx->Array.NewState = 0;
-   if (!ctx->Array.RebindArrays)
-      ctx->Array.RebindArrays = (new_state & (_NEW_ARRAY | _NEW_PROGRAM)) != 0;
 }
 
 
index 05c3ec1ae9dd9632981061a97f24de6c1637bdc5..fd5e0f8911b40b86644bd69286d5c410018fd724 100644 (file)
@@ -85,6 +85,10 @@ void vbo_exec_invalidate_state( struct gl_context *ctx, GLuint new_state )
 {
    struct vbo_exec_context *exec = &vbo_context(ctx)->exec;
 
+   if (new_state & (_NEW_PROGRAM|_NEW_ARRAY)) {
+      exec->array.recalculate_inputs = GL_TRUE;
+   }
+
    if (new_state & (_NEW_PROGRAM|_NEW_EVAL))
       exec->eval.recalculate_maps = 1;
 
index f6ede99cd75baf5522b778d2fbafa5665f6b2aea..5cdf5ced912c1b9bd5fa2ecafcb21bca71db6561 100644 (file)
@@ -141,6 +141,7 @@ struct vbo_exec_context
        * programs:
        */
       const struct gl_client_array *inputs[VERT_ATTRIB_MAX];
+      GLboolean recalculate_inputs;
    } array;
 
    /* Which flags to set in vbo_exec_BeginVertices() */
index b0a4261e764d6f2cda1ebedb14b16269c1e7afc7..d9003c243b106887c66fc04cebe1c1f7802b6695 100644 (file)
@@ -529,12 +529,25 @@ recalculate_input_bindings(struct gl_context *ctx)
 void
 vbo_bind_arrays(struct gl_context *ctx)
 {
-   if (!ctx->Array.RebindArrays) {
-      return;
-   }
+   struct vbo_context *vbo = vbo_context(ctx);
+   struct vbo_exec_context *exec = &vbo->exec;
+
+   vbo_draw_method(exec, DRAW_ARRAYS);
 
-   recalculate_input_bindings(ctx);
-   ctx->Array.RebindArrays = GL_FALSE;
+   if (exec->array.recalculate_inputs) {
+      recalculate_input_bindings(ctx);
+
+      /* 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
+       * need in the shader.
+       */
+      if (ctx->NewState) {
+         _mesa_update_state(ctx);
+      }
+
+      exec->array.recalculate_inputs = GL_FALSE;
+   }
 }
 
 
@@ -554,16 +567,6 @@ 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
-    * need in the shader.
-    */
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    /* init most fields to zero */
    memset(prim, 0, sizeof(prim));
    prim[0].begin = 1;
@@ -771,13 +774,7 @@ vbo_validated_drawrangeelements(struct gl_context *ctx, GLenum mode,
       return;
    }
 
-   vbo_bind_arrays( ctx );
-
-   vbo_draw_method(exec, DRAW_ARRAYS);
-
-   /* check for dirty state again */
-   if (ctx->NewState)
-      _mesa_update_state( ctx );
+   vbo_bind_arrays(ctx);
 
    ib.count = count;
    ib.type = type;
@@ -1063,15 +1060,7 @@ vbo_validated_multidrawelements(struct gl_context *ctx, GLenum mode,
       return;
    }
 
-   /* Decide if we can do this all as one set of primitives sharing the
-    * same index buffer, or if we have to reset the index pointer per
-    * primitive.
-    */
-   vbo_bind_arrays( ctx );
-
-   /* check for dirty state again */
-   if (ctx->NewState)
-      _mesa_update_state( ctx );
+   vbo_bind_arrays(ctx);
 
    min_index_ptr = (uintptr_t)indices[0];
    max_index_ptr = 0;
@@ -1217,14 +1206,6 @@ vbo_draw_transform_feedback(struct gl_context *ctx, GLenum mode,
 
    vbo_bind_arrays(ctx);
 
-   /* 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
-    * need in the shader.
-    */
-   if (ctx->NewState)
-      _mesa_update_state(ctx);
-
    /* init most fields to zero */
    memset(prim, 0, sizeof(prim));
    prim[0].begin = 1;