mesa: add gl_context::NewDriverState and use it for vertex arrays
authorMarek Olšák <maraeo@gmail.com>
Mon, 16 Apr 2012 02:56:12 +0000 (04:56 +0200)
committerMarek Olšák <maraeo@gmail.com>
Tue, 8 May 2012 13:57:51 +0000 (15:57 +0200)
The vbo module recomputes its states if _NEW_ARRAY is set, so it shouldn't use
the same flag to notify the driver. Since we've run out of bits in NewState
and NewState is for core Mesa anyway, we need to find another way.

This patch is the first to start decoupling the state flags meant only
for core Mesa and those only for drivers.

The idea is to have two flag sets:
- gl_context::NewState - used by core Mesa only
- gl_context::NewDriverState - used by drivers only (the flags are defined
                               by the driver and opaque to core Mesa)

It makes perfect sense to use NewState|=_NEW_ARRAY to notify the vbo module
that the user changed vertex arrays, and the vbo module in turn sets
a driver-specific flag to notify the driver that it should update its vertex
array bindings.

The driver decides which bits of NewDriverState should be set and stores them
in gl_context::DriverFlags. Then, Core Mesa can do this:
ctx->NewDriverState |= ctx->DriverFlags.NewArray;

This patch implements this behavior and adapts st/mesa.
DriverFlags.NewArray is set to ST_NEW_VERTEX_ARRAYS.

Core Mesa only sets NewDriverState. It's the driver's responsibility to read
it whenever it wants and reset it to 0.

Reviewed-by: Brian Paul <brianp@vmware.com>
13 files changed:
src/mesa/main/context.c
src/mesa/main/mtypes.h
src/mesa/state_tracker/st_cb_rasterpos.c
src/mesa/state_tracker/st_context.c
src/mesa/state_tracker/st_context.h
src/mesa/state_tracker/st_draw.c
src/mesa/vbo/vbo_context.h
src/mesa/vbo/vbo_exec_array.c
src/mesa/vbo/vbo_exec_draw.c
src/mesa/vbo/vbo_rebase.c
src/mesa/vbo/vbo_save_draw.c
src/mesa/vbo/vbo_split_copy.c
src/mesa/vbo/vbo_split_inplace.c

index d75351c8598429636fdb8b1a11ee43152c72c723..7e2ac98b9a0d5d872f2b02f31cd77f412fa05209 100644 (file)
@@ -792,6 +792,7 @@ init_attrib_groups(struct gl_context *ctx)
 
    /* Miscellaneous */
    ctx->NewState = _NEW_ALL;
+   ctx->NewDriverState = ~0;
    ctx->ErrorValue = (GLenum) GL_NO_ERROR;
    ctx->ResetStatus = (GLenum) GL_NO_ERROR;
    ctx->varying_vp_inputs = VERT_BIT_ALL;
@@ -1290,6 +1291,7 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst,
    /* XXX FIXME:  Call callbacks?
     */
    dst->NewState = _NEW_ALL;
+   dst->NewDriverState = ~0;
 }
 #endif
 
index 9f1a2263f547b4fc1c39752ed1e90b2128e93a83..06ca0d5df169bf73da37c762df9872e85f53e97e 100644 (file)
@@ -3257,6 +3257,17 @@ typedef enum
    API_OPENGLES2
 } gl_api;
 
+/**
+ * Driver-specific state flags.
+ *
+ * These are or'd with gl_context::NewDriverState to notify a driver about
+ * a state change. The driver sets the flags at context creation and
+ * the meaning of the bits set is opaque to core Mesa.
+ */
+struct gl_driver_flags
+{
+   GLbitfield NewArray;             /**< Vertex array state */
+};
 
 /**
  * Mesa rendering context.
@@ -3416,6 +3427,9 @@ struct gl_context
 
    GLenum RenderMode;        /**< either GL_RENDER, GL_SELECT, GL_FEEDBACK */
    GLbitfield NewState;      /**< bitwise-or of _NEW_* flags */
+   GLbitfield NewDriverState;/**< bitwise-or of flags from DriverFlags */
+
+   struct gl_driver_flags DriverFlags;
 
    GLboolean ViewportInitialized;  /**< has viewport size been initialized? */
 
index 7fef031f0132ea0afea8d19811936a11fd329d00..8337f4624186fd0abe1a503dc56c2988f263efcf 100644 (file)
@@ -251,7 +251,10 @@ st_RasterPos(struct gl_context *ctx, const GLfloat v[4])
     */
    rs->array[0].Ptr = (GLubyte *) v;
 
-   /* draw the point */
+   /* Draw the point.
+    *
+    * Don't set DriverFlags.NewArray.
+    * st_feedback_draw_vbo doesn't check for that flag. */
    ctx->Array._DrawArrays = rs->arrays;
    st_feedback_draw_vbo(ctx, &rs->prim, 1, NULL, GL_TRUE, 0, 1,
                         NULL);
index 19d9da131f3f7018114411842f5ec27af6ddaeca..ce7dbb3f39a198cdd3472cd5ce0475fe8c18c470 100644 (file)
@@ -203,6 +203,10 @@ st_create_context_priv( struct gl_context *ctx, struct pipe_context *pipe )
    return st;
 }
 
+static void st_init_driver_flags(struct gl_driver_flags *f)
+{
+   f->NewArray = ST_NEW_VERTEX_ARRAYS;
+}
 
 struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
                                      const struct gl_config *visual,
@@ -225,6 +229,8 @@ struct st_context *st_create_context(gl_api api, struct pipe_context *pipe,
       return NULL;
    }
 
+   st_init_driver_flags(&ctx->DriverFlags);
+
    /* XXX: need a capability bit in gallium to query if the pipe
     * driver prefers DP4 or MUL/MAD for vertex transformation.
     */
index 3ec98ada196d5f718e188a821ed2342ccc756021..4786ed22fe9696c33df4a7f853b2fd4e74bcac73 100644 (file)
@@ -50,6 +50,7 @@ struct u_vbuf;
 #define ST_NEW_FRAMEBUFFER             (1 << 3)
 #define ST_NEW_EDGEFLAGS_DATA          (1 << 4)
 #define ST_NEW_GEOMETRY_PROGRAM        (1 << 5)
+#define ST_NEW_VERTEX_ARRAYS           (1 << 6)
 
 
 struct st_state_flags {
index 01ba09d656739711a852f8d3b9d6de7a2fd3eef2..42dc3757615744da3c92cb0134ef0a90ef7dd903 100644 (file)
@@ -981,13 +981,19 @@ st_draw_vbo(struct gl_context *ctx,
    const struct gl_client_array **arrays = ctx->Array._DrawArrays;
    unsigned i, num_instances = 1;
    unsigned max_index_plus_base;
-   GLboolean new_array =
-      st->dirty.st &&
-      (st->dirty.mesa & (_NEW_ARRAY | _NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
+   GLboolean new_array;
 
    /* Mesa core state should have been validated already */
    assert(ctx->NewState == 0x0);
 
+   /* Get Mesa driver state. */
+   st->dirty.st |= ctx->NewDriverState;
+   ctx->NewDriverState = 0;
+
+   new_array =
+      (st->dirty.st & (ST_NEW_VERTEX_ARRAYS | ST_NEW_VERTEX_PROGRAM)) ||
+      (st->dirty.mesa & (_NEW_PROGRAM | _NEW_BUFFER_OBJECT)) != 0;
+
    if (ib) {
       int max_base_vertex = 0;
 
index 93c48cd029b587049881ab2f97ef34ef75e7b30c..1c49de0ca2ffc6b2813bc6ff6a553ebdbd10c3dc 100644 (file)
@@ -146,7 +146,7 @@ vbo_draw_method(struct vbo_context *vbo, enum draw_method method)
          ASSERT(0);
       }
 
-      ctx->Driver.UpdateState(ctx, _NEW_ARRAY);
+      ctx->NewDriverState |= ctx->DriverFlags.NewArray;
       vbo->last_draw_method = method;
    }
 }
index d39324d12bc17358dbe6339f294e9723e4c9eccc..cc94e761bc189aa397737b84f51011657d63762c 100644 (file)
@@ -506,7 +506,7 @@ recalculate_input_bindings(struct gl_context *ctx)
    }
 
    _mesa_set_varying_vp_inputs( ctx, VERT_BIT_ALL & (~const_inputs) );
-   ctx->Driver.UpdateState(ctx, _NEW_ARRAY);
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 }
 
 
index 6e8bb15d1e2aa4d2196a44ad16c6deaa7f3090f3..77db8ec7f3eb92161d4f84b0746cca1b709e631b 100644 (file)
@@ -257,7 +257,7 @@ vbo_exec_bind_arrays( struct gl_context *ctx )
    }
 
    _mesa_set_varying_vp_inputs( ctx, varying_inputs );
-   ctx->Driver.UpdateState(ctx, _NEW_ARRAY);
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 }
 
 
index 9a98ef7d44975cbd7cf015b775120ffde91790b8..fff9df0c29dbafc3409ab0281c6819fad2a16173 100644 (file)
@@ -228,6 +228,7 @@ void vbo_rebase_prims( struct gl_context *ctx,
    /* Re-issue the draw call.
     */
    ctx->Array._DrawArrays = tmp_array_pointers;
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 
    draw( ctx, 
         prim,
@@ -239,6 +240,7 @@ void vbo_rebase_prims( struct gl_context *ctx,
         NULL );
 
    ctx->Array._DrawArrays = saved_arrays;
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
    
    if (tmp_indices)
       free(tmp_indices);
index bb5961549ef6fb4da2cd6a6bcc4d7b8b7bb3615d..c6425ab1b79022c8a9cb8667012df02ce5b1678d 100644 (file)
@@ -213,7 +213,7 @@ static void vbo_bind_vertex_list(struct gl_context *ctx,
    }
 
    _mesa_set_varying_vp_inputs( ctx, varying_inputs );
-   ctx->Driver.UpdateState(ctx, _NEW_ARRAY);
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 }
 
 
index 9665c4fcd2f0d7467d68127fcc685984e3698515..528fcfd7f802a10a29cf0873a4f40ff8de5bfd4e 100644 (file)
@@ -192,6 +192,7 @@ flush( struct copy_context *copy )
 #endif
 
    ctx->Array._DrawArrays = copy->dstarray_ptr;
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 
    copy->draw( ctx,
               copy->dstprim,
@@ -203,6 +204,7 @@ flush( struct copy_context *copy )
               NULL );
 
    ctx->Array._DrawArrays = saved_arrays;
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 
    /* Reset all pointers: 
     */
index 7c2cc3ece5a41be569a94193ecbecd6f91edd6fe..00464049dddf62a77890cfa3fa838178745ab956 100644 (file)
@@ -85,6 +85,7 @@ static void flush_vertex( struct split_context *split )
    assert(split->max_index >= split->min_index);
 
    ctx->Array._DrawArrays = split->array;
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 
    split->draw(ctx,
               split->dstprim,
@@ -96,6 +97,7 @@ static void flush_vertex( struct split_context *split )
               NULL);
 
    ctx->Array._DrawArrays = saved_arrays;
+   ctx->NewDriverState |= ctx->DriverFlags.NewArray;
 
    split->dstprim_nr = 0;
    split->min_index = ~0;