i965: Avoid calloc/free in the CURBE upload process.

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.
This commit is contained in:
Eric Anholt 2010-06-08 13:55:53 -07:00
parent 45fb47d50c
commit 503eb57a00
5 changed files with 26 additions and 20 deletions

View 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;

View 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;

View 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;

View 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;

View 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);
}