[Mesa-dev] [PATCH 5/6] mesa: Add dd_function_table::PrepareExecBegin and CleanupExecEnd

Chad Versace chad at chad-versace.us
Mon Oct 17 07:27:10 PDT 2011


These hooks allow drivers to prepare for and cleanup after a glBegin/glEnd
block.

i965 will use the hooks 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 two
dual conditions:
   1. 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.
   2. That it mark no buffer as needing a resolve if a vertex is
      queued. To satisfy this, i965 will immediately flush vertices on
      exiting the glBegin/glEnd block.

Signed-off-by: Chad Versace <chad at chad-versace.us>
---
 src/mesa/drivers/common/driverfuncs.c |    2 ++
 src/mesa/main/dd.h                    |   15 +++++++++++++++
 src/mesa/vbo/vbo_exec_api.c           |    6 ++++++
 3 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 33da934..6261df8 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -208,6 +208,8 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
    driver->ProgramStringNotify = _tnl_program_string;
    driver->FlushVertices = NULL;
    driver->SaveFlushVertices = NULL;
+   driver->PrepareExecBegin = NULL;
+   driver->CleanupExecEnd = NULL;
    driver->NotifySaveBegin = NULL;
    driver->LightingSpaceChange = NULL;
 
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 4e017ae..5571343 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -861,6 +861,21 @@ struct dd_function_table {
    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 );
+
+   /**
+    * \brief Hook for drivers to cleanup after a glBegin/glEnd block
+    *
+    * This hook is the last action taken in vbo_exec_End().
+    */
+   void (*CleanupExecEnd)( 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
     * glBegin() during list compilation.
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index 150589b..b4e3b80 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -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 );
 
@@ -629,6 +632,9 @@ static void GLAPIENTRY vbo_exec_End( void )
 
       if (exec->vtx.prim_count == VBO_MAX_PRIM)
 	 vbo_exec_vtx_flush( exec, GL_FALSE );
+
+      if(ctx->Driver.CleanupExecEnd)
+   	 ctx->Driver.CleanupExecEnd(ctx);
    }
    else 
       _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" );
-- 
1.7.6.4



More information about the mesa-dev mailing list