Mesa (master): i965: Reduce fast-pathiness of brw_try_draw_prims, bringing in important checks.

Eric Anholt anholt at kemper.freedesktop.org
Sat Nov 29 01:26:40 UTC 2008


Module: Mesa
Branch: master
Commit: 7855b2aef6bd9e9c2d73260b5cd166159b2525c6
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7855b2aef6bd9e9c2d73260b5cd166159b2525c6

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Nov 26 19:22:37 2008 -0800

i965: Reduce fast-pathiness of brw_try_draw_prims, bringing in important checks.

Later primitives, even if they caused a full state validate, wouldn't check
that there was enough space in the batchbuffer, occasionally triggering the
sanity check.  We also skipped the aperture space check, even if it would
mean bringing in new programs and associated state.

---

 src/mesa/drivers/dri/i965/brw_draw.c |  103 +++++++++++++++++-----------------
 1 files changed, 52 insertions(+), 51 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index f893dd6..c3a26fc 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -49,7 +49,7 @@
 
 #define FILE_DEBUG_FLAG DEBUG_BATCH
 
-static GLuint hw_prim[GL_POLYGON+1] = {
+static GLuint prim_to_hw_prim[GL_POLYGON+1] = {
    _3DPRIM_POINTLIST,
    _3DPRIM_LINELIST,
    _3DPRIM_LINELOOP,
@@ -103,12 +103,9 @@ static GLuint brw_set_prim(struct brw_context *brw, GLenum prim)
 	 brw->intel.reduced_primitive = reduced_prim[prim];
 	 brw->state.dirty.brw |= BRW_NEW_REDUCED_PRIMITIVE;
       }
-
-      brw_validate_state(brw);
-      brw_upload_state(brw);
    }
 
-   return hw_prim[prim];
+   return prim_to_hw_prim[prim];
 }
 
 
@@ -123,9 +120,9 @@ static GLuint trim(GLenum prim, GLuint length)
 }
 
 
-static void brw_emit_prim( struct brw_context *brw, 
-			   const struct _mesa_prim *prim )
-
+static void brw_emit_prim(struct brw_context *brw,
+			  const struct _mesa_prim *prim,
+			  uint32_t hw_prim)
 {
    struct brw_3d_primitive prim_packet;
 
@@ -136,7 +133,7 @@ static void brw_emit_prim( struct brw_context *brw,
    prim_packet.header.opcode = CMD_3D_PRIM;
    prim_packet.header.length = sizeof(prim_packet)/4 - 2;
    prim_packet.header.pad = 0;
-   prim_packet.header.topology = brw_set_prim(brw, prim->mode);
+   prim_packet.header.topology = hw_prim;
    prim_packet.header.indexed = prim->indexed;
 
    prim_packet.verts_per_instance = trim(prim->mode, prim->count);
@@ -258,11 +255,15 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
    struct brw_context *brw = brw_context(ctx);
    GLboolean retval = GL_FALSE;
    GLboolean warn = GL_FALSE;
+   GLboolean first_time = GL_TRUE;
    GLuint i;
 
    if (ctx->NewState)
       _mesa_update_state( ctx );
 
+   if (check_fallbacks(brw, prim, nr_prims))
+      return GL_FALSE;
+
    brw_validate_textures( brw );
 
    /* Bind all inputs, derive varying and size information:
@@ -275,6 +276,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
    brw->vb.min_index = min_index;
    brw->vb.max_index = max_index;
    brw->state.dirty.brw |= BRW_NEW_VERTICES;
+
    /* Have to validate state quite late.  Will rebuild tnl_program,
     * which depends on varying information.  
     * 
@@ -289,59 +291,58 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
       return GL_TRUE;
    }
 
-   /* Flush the batch if it's approaching full, so that we don't wrap while
-    * we've got validated state that needs to be in the same batch as the
-    * primitives.  This fraction is just a guess (minimal full state plus
-    * a primitive is around 512 bytes), and would be better if we had
-    * an upper bound of how much we might emit in a single
-    * brw_try_draw_prims().
-    */
-   intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
-				   LOOP_CLIPRECTS);
-   {
-      /* Set the first primitive early, ahead of validate_state:
+   for (i = 0; i < nr_prims; i++) {
+      uint32_t hw_prim;
+
+      /* Flush the batch if it's approaching full, so that we don't wrap while
+       * we've got validated state that needs to be in the same batch as the
+       * primitives.  This fraction is just a guess (minimal full state plus
+       * a primitive is around 512 bytes), and would be better if we had
+       * an upper bound of how much we might emit in a single
+       * brw_try_draw_prims().
        */
-      brw_set_prim(brw, prim[0].mode);
+      intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
+				      LOOP_CLIPRECTS);
 
-      brw_validate_state( brw );
+      hw_prim = brw_set_prim(brw, prim[i].mode);
 
-      /* Various fallback checks:
-       */
-      if (brw->intel.Fallback) 
-	 goto out;
+      if (first_time || (brw->state.dirty.brw & BRW_NEW_PRIMITIVE)) {
+	 first_time = GL_FALSE;
 
-      if (check_fallbacks( brw, prim, nr_prims ))
-	 goto out;
+	 /* Various fallback checks:  */
+	 if (brw->intel.Fallback)
+	    goto out;
 
-      /* Check that we can fit our state in with our existing batchbuffer, or
-       * flush otherwise.
-       */
-      if (dri_bufmgr_check_aperture_space(brw->state.validated_bos,
-					  brw->state.validated_bo_count)) {
-	 static GLboolean warned;
-	 intel_batchbuffer_flush(intel->batch);
-
-	 /* Validate the state after we flushed the batch (which would have
-	  * changed the set of dirty state).  If we still fail to
-	  * check_aperture, warn of what's happening, but attempt to continue
-	  * on since it may succeed anyway, and the user would probably rather
-	  * see a failure and a warning than a fallback.
-	  */
 	 brw_validate_state(brw);
-	 if (!warned &&
-	     dri_bufmgr_check_aperture_space(brw->state.validated_bos,
+
+	 /* Check that we can fit our state in with our existing batchbuffer, or
+	  * flush otherwise.
+	  */
+	 if (dri_bufmgr_check_aperture_space(brw->state.validated_bos,
 					     brw->state.validated_bo_count)) {
-	    warn = GL_TRUE;
-	    warned = GL_TRUE;
+	    static GLboolean warned;
+	    intel_batchbuffer_flush(intel->batch);
+
+	    /* Validate the state after we flushed the batch (which would have
+	     * changed the set of dirty state).  If we still fail to
+	     * check_aperture, warn of what's happening, but attempt to continue
+	     * on since it may succeed anyway, and the user would probably rather
+	     * see a failure and a warning than a fallback.
+	     */
+	    brw_validate_state(brw);
+	    if (!warned &&
+		dri_bufmgr_check_aperture_space(brw->state.validated_bos,
+						brw->state.validated_bo_count)) {
+	       warn = GL_TRUE;
+	       warned = GL_TRUE;
+	    }
 	 }
-      }
-
-      brw_upload_state(brw);
 
-      for (i = 0; i < nr_prims; i++) {
-	 brw_emit_prim(brw, &prim[i]);
+	 brw_upload_state(brw);
       }
 
+      brw_emit_prim(brw, &prim[i], hw_prim);
+
       retval = GL_TRUE;
    }
 




More information about the mesa-commit mailing list