mesa: Add dd_function_table::PrepareExecBegin
authorChad Versace <chad@chad-versace.us>
Thu, 29 Sep 2011 00:06:35 +0000 (17:06 -0700)
committerChad Versace <chad@chad-versace.us>
Tue, 18 Oct 2011 18:42:53 +0000 (11:42 -0700)
This hook allows the driver to prepare for a glBegin/glEnd.

i965 will use the hook to avoid avoid recursive calls to FLUSH_VERTICES
during a buffer resolve meta-op.

Detailed Justification
----------------------
When vertices are queued during a glBegin/glEnd block, those vertices must
of course be drawn before any rendering state changes. To enusure this,
Mesa calls FLUSH_VERTICES as a prehook to such state changes. Therefore,
FLUSH_VERTICES itself cannot change rendering state without falling into
a recursive trap.

This precludes meta-ops, namely i965 buffer resolves, from occuring while
any vertices are queued. To avoid that situation, i965 must satisfy the
following condition: that it queues no vertex if a buffer needs resolving.
To satisfy this, i965 will use the PrepareExecBegin hook to resolve all
buffers on entering a glBegin/glEnd block.

--------
v2: Don't add dd_function_table::CleanupExecEnd. Anholt and I discovered
    that hook to be unnecessary.

Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Chad Versace <chad@chad-versace.us>
src/mesa/drivers/common/driverfuncs.c
src/mesa/main/dd.h
src/mesa/vbo/vbo_exec_api.c

index 33da9346caf914d7379a27cb9ec943b0d45e6e39..263d4025ff3ad5bb0a17512323d0fa3f412839df 100644 (file)
@@ -208,6 +208,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->ProgramStringNotify = _tnl_program_string;
    driver->FlushVertices = NULL;
    driver->SaveFlushVertices = NULL;
+   driver->PrepareExecBegin = NULL;
    driver->NotifySaveBegin = NULL;
    driver->LightingSpaceChange = NULL;
 
index 4e017ae3843922bf7561cbfb1411de95628d3bd6..8607008dee6a47543713914fc38a0ab9530bc3a9 100644 (file)
@@ -860,6 +860,14 @@ struct dd_function_table {
    void (*FlushVertices)( struct gl_context *ctx, GLuint flags );
    void (*SaveFlushVertices)( struct gl_context *ctx );
 
+   /**
+    * \brief Hook for drivers to prepare for a glBegin/glEnd block
+    *
+    * This hook is called in vbo_exec_Begin() before any action, including
+    * state updates, occurs.
+    */
+   void (*PrepareExecBegin)( struct gl_context *ctx );
+
    /**
     * Give the driver the opportunity to hook in its own vtxfmt for
     * compiling optimized display lists.  This is called on each valid
index 150589bec5ee45cc7c9a714ef4a22245c8105039..5f3ed9d5db474528dccea462f3349f78176eb12c 100644 (file)
@@ -570,6 +570,9 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
          return;
       }
 
+      if (ctx->Driver.PrepareExecBegin)
+        ctx->Driver.PrepareExecBegin(ctx);
+
       if (ctx->NewState) {
         _mesa_update_state( ctx );