if (cbuf_dirty) {
draw_set_mapped_constant_buffer(draw, PIPE_SHADER_VERTEX, 0,
- i915->current.constants[PIPE_SHADER_VERTEX],
+ i915_buffer(i915->constants[PIPE_SHADER_VERTEX])->data,
(i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
4 * sizeof(float)));
}
}
pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
+ /* unbind constant buffers */
+ for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+ pipe_resource_reference(&i915->constants[i], NULL);
+ }
+
FREE(i915);
}
unsigned immediate[I915_MAX_IMMEDIATE];
unsigned dynamic[I915_MAX_DYNAMIC];
- float constants[PIPE_SHADER_TYPES][I915_MAX_CONSTANT][4];
/** number of constants passed in through a constant buffer */
uint num_user_constants[PIPE_SHADER_TYPES];
struct pipe_blend_color blend_color;
struct pipe_stencil_ref stencil_ref;
struct pipe_clip_state clip;
- /* XXX unneded */
struct pipe_resource *constants[PIPE_SHADER_TYPES];
struct pipe_framebuffer_state framebuffer;
struct pipe_poly_stipple poly_stipple;
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;
}