i965: Avoid calloc/free in the CURBE upload process.
authorEric Anholt <eric@anholt.net>
Tue, 8 Jun 2010 20:55:53 +0000 (13:55 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 9 Jun 2010 21:17:52 +0000 (14:17 -0700)
In exchange we end up with an extra memcpy, but that seems better than
calloc/free.  Each buffer is 4k maximum, and on the i965-streaming
branch this allocation was showing up as the top entry in
brw_validate_state profiling for cairo-gl.

src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_curbe.c
src/mesa/drivers/dri/i965/brw_state_cache.c
src/mesa/drivers/dri/i965/brw_vtbl.c

index dc4bd5802d4ccd126cc4a69552c3a9dc380726ac..0be60ad83c03079c0b211dd8ca2c75233ca89989 100644 (file)
@@ -184,6 +184,9 @@ GLboolean brwCreateContext( int api,
 
    brw_init_state( brw );
 
+   brw->curbe.last_buf = calloc(1, 4096);
+   brw->curbe.next_buf = calloc(1, 4096);
+
    brw->state.dirty.mesa = ~0;
    brw->state.dirty.brw = ~0;
 
index 14552fa2724f005d6a77fce31b74667554b2de12..d97634c1c6080462bdfb7fb37b2cdedda954ab57 100644 (file)
@@ -573,7 +573,18 @@ struct brw_context
       /** Offset within curbe_bo of space for next curbe entry */
       GLuint curbe_next_offset;
 
+      /**
+       * Copy of the last set of CURBEs uploaded.  Frequently we'll end up
+       * in brw_curbe.c with the same set of constant data to be uploaded,
+       * so we'd rather not upload new constants in that case (it can cause
+       * a pipeline bubble since only up to 4 can be pipelined at a time).
+       */
       GLfloat *last_buf;
+      /**
+       * Allocation for where to calculate the next set of CURBEs.
+       * It's a hot enough path that malloc/free of that data matters.
+       */
+      GLfloat *next_buf;
       GLuint last_bufsz;
    } curbe;
 
index 06053d5bcb7774c38122540e6be4d940da890131..c79b0a79e5ca5b5b89f0e972a5365dfd7cb4e964 100644 (file)
@@ -190,15 +190,11 @@ static void prepare_constant_buffer(struct brw_context *brw)
    GLuint i;
 
    if (sz == 0) {
-      if (brw->curbe.last_buf) {
-        free(brw->curbe.last_buf);
-        brw->curbe.last_buf = NULL;
-        brw->curbe.last_bufsz  = 0;
-      }
+      brw->curbe.last_bufsz  = 0;
       return;
    }
 
-   buf = (GLfloat *) calloc(1, bufsz);
+   buf = brw->curbe.next_buf;
 
    /* fragment shader constants */
    if (brw->curbe.wm_size) {
@@ -289,18 +285,15 @@ static void prepare_constant_buffer(struct brw_context *brw)
    }
 
    if (brw->curbe.curbe_bo != NULL &&
-       brw->curbe.last_buf &&
        bufsz == brw->curbe.last_bufsz &&
        memcmp(buf, brw->curbe.last_buf, bufsz) == 0) {
       /* constants have not changed */
-      free(buf);
-   } 
-   else {
-      /* constants have changed */
-      if (brw->curbe.last_buf)
-        free(brw->curbe.last_buf);
-
-      brw->curbe.last_buf = buf;
+   } else {
+      /* Update the record of what our last set of constants was.  We
+       * don't just flip the pointers because we don't fill in the
+       * data in the padding between the entries.
+       */
+      memcpy(brw->curbe.last_buf, buf, bufsz);
       brw->curbe.last_bufsz = bufsz;
 
       if (brw->curbe.curbe_bo != NULL &&
@@ -319,6 +312,7 @@ static void prepare_constant_buffer(struct brw_context *brw)
                                                  4096, 1 << 6);
         brw->curbe.curbe_next_offset = 0;
         drm_intel_gem_bo_map_gtt(brw->curbe.curbe_bo);
+        assert(bufsz < 4096);
       }
 
       brw->curbe.curbe_offset = brw->curbe.curbe_next_offset;
index 415b6456652be7040a52fe0d5095adf8325128c6..ea81ad13417dd4ce829a743bc12cb476fe69f804 100644 (file)
@@ -447,11 +447,6 @@ brw_clear_cache(struct brw_context *brw, struct brw_cache *cache)
 
    cache->n_items = 0;
 
-   if (brw->curbe.last_buf) {
-      free(brw->curbe.last_buf);
-      brw->curbe.last_buf = NULL;
-   }
-
    brw->state.dirty.mesa |= ~0;
    brw->state.dirty.brw |= ~0;
    brw->state.dirty.cache |= ~0;
index c8ebb4a4f1e0d94978dea07391fab68b6805ec0a..a02e958c5e6637af306d7adc1ee164a2a50a6551 100644 (file)
@@ -105,6 +105,9 @@ static void brw_destroy_context( struct intel_context *intel )
    dri_bo_release(&brw->cc.blend_state_bo);
    dri_bo_release(&brw->cc.depth_stencil_state_bo);
    dri_bo_release(&brw->cc.color_calc_state_bo);
+
+   free(brw->curbe.last_buf);
+   free(brw->curbe.next_buf);
 }