diff options
author | Jakob Bornecrantz <[email protected]> | 2010-12-01 05:45:42 +0100 |
---|---|---|
committer | Jakob Bornecrantz <[email protected]> | 2011-01-21 20:53:29 +0100 |
commit | 0c3352b6df7972fd530a901396b392d0293d27ae (patch) | |
tree | 951a343ab506c1f3c99e2f42dbae5d5be840e2b9 /src/gallium/drivers/i915/i915_state.c | |
parent | 2e60aa511dd232f88697d1cc2091442caaef79b2 (diff) |
i915g: Don't do unnecessary copies of constants
Even tho st/mesa use user buffers for constants align buffers
other state trackers doesn't use user buffers.
Diffstat (limited to 'src/gallium/drivers/i915/i915_state.c')
-rw-r--r-- | src/gallium/drivers/i915/i915_state.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index cc8bd3b0c39..4a1a4a04f6d 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -525,36 +525,40 @@ static void i915_set_constant_buffer(struct pipe_context *pipe, struct pipe_resource *buf) { struct i915_context *i915 = i915_context(pipe); - draw_flush(i915->draw); + unsigned new_num = 0; + boolean diff = TRUE; + /* XXX don't support geom shaders now */ if (shader == PIPE_SHADER_GEOMETRY) return; - /* Make a copy of shader constants. - * During fragment program translation we may add additional - * constants to the array. - * - * We want to consider the situation where some user constants - * (ex: a material color) may change frequently but the shader program - * stays the same. In that case we should only be updating the first - * N constants, leaving any extras from shader translation alone. - */ + /* if we have a new buffer compare it with the old one */ if (buf) { struct i915_buffer *ir = i915_buffer(buf); + struct pipe_resource *old_buf = i915->constants[shader]; + struct i915_buffer *old = old_buf ? i915_buffer(old_buf) : NULL; - if (!memcmp(i915->current.constants[shader], ir->data, ir->b.b.width0)) - return; + new_num = ir->b.b.width0 / 4 * sizeof(float); - memcpy(i915->current.constants[shader], ir->data, ir->b.b.width0); - i915->current.num_user_constants[shader] = (ir->b.b.width0 / - 4 * sizeof(float)); - } - else { - i915->current.num_user_constants[shader] = 0; + if (old && new_num != i915->current.num_user_constants[shader]) + diff = memcmp(old->data, ir->data, ir->b.b.width0); + } else { + diff = i915->current.num_user_constants[shader] != 0; } - i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; + /* + * flush before updateing the state. + * XXX: looks like its okay to skip the flush for vertex cbufs + */ + if (diff && shader == PIPE_SHADER_FRAGMENT) + draw_flush(i915->draw); + + pipe_resource_reference(&i915->constants[shader], buf); + i915->current.num_user_constants[shader] = new_num; + + if (diff) + i915->dirty |= shader == PIPE_SHADER_VERTEX ? I915_NEW_VS_CONSTANTS : I915_NEW_FS_CONSTANTS; } |