Mesa (master): i915g: Don't do unnecessary copies of constants

Jakob Bornecrantz wallbraker at kemper.freedesktop.org
Fri Jan 21 19:55:16 UTC 2011


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

Author: Jakob Bornecrantz <wallbraker at gmail.com>
Date:   Wed Dec  1 05:45:42 2010 +0100

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.

---

 src/gallium/drivers/i915/i915_context.c         |    7 +++-
 src/gallium/drivers/i915/i915_context.h         |    2 -
 src/gallium/drivers/i915/i915_resource_buffer.c |    3 +-
 src/gallium/drivers/i915/i915_state.c           |   42 ++++++++++++----------
 src/gallium/drivers/i915/i915_state_emit.c      |    3 +-
 5 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/src/gallium/drivers/i915/i915_context.c b/src/gallium/drivers/i915/i915_context.c
index 15454d0..ea3c10b 100644
--- a/src/gallium/drivers/i915/i915_context.c
+++ b/src/gallium/drivers/i915/i915_context.c
@@ -80,7 +80,7 @@ i915_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info)
 
    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)));
    }
@@ -127,6 +127,11 @@ static void i915_destroy(struct pipe_context *pipe)
    }
    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);
 }
 
diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h
index 6dab3a1..b7f1fb2 100644
--- a/src/gallium/drivers/i915/i915_context.h
+++ b/src/gallium/drivers/i915/i915_context.h
@@ -136,7 +136,6 @@ struct i915_state
    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];
 
@@ -214,7 +213,6 @@ struct i915_context {
    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;
diff --git a/src/gallium/drivers/i915/i915_resource_buffer.c b/src/gallium/drivers/i915/i915_resource_buffer.c
index 6e2b490..51482f5 100644
--- a/src/gallium/drivers/i915/i915_resource_buffer.c
+++ b/src/gallium/drivers/i915/i915_resource_buffer.c
@@ -147,8 +147,7 @@ i915_buffer_create(struct pipe_screen *screen,
    buf->b.vtbl = &i915_buffer_vtbl;
    pipe_reference_init(&buf->b.b.reference, 1);
    buf->b.b.screen = screen;
-
-   buf->data = MALLOC(template->width0);
+   buf->data = align_malloc(template->width0, 16);
    buf->free_on_destroy = TRUE;
 
    if (!buf->data)
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index cc8bd3b..4a1a4a0 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;
 }
 
 
diff --git a/src/gallium/drivers/i915/i915_state_emit.c b/src/gallium/drivers/i915/i915_state_emit.c
index 86c0297..5a89977 100644
--- a/src/gallium/drivers/i915/i915_state_emit.c
+++ b/src/gallium/drivers/i915/i915_state_emit.c
@@ -367,7 +367,8 @@ i915_emit_hardware_state(struct i915_context *i915 )
             const uint *c;
             if (i915->fs->constant_flags[i] == I915_CONSTFLAG_USER) {
                /* grab user-defined constant */
-               c = (uint *) i915->current.constants[PIPE_SHADER_FRAGMENT][i];
+               c = (uint *) i915_buffer(i915->constants[PIPE_SHADER_FRAGMENT])->data;
+               c += 4 * i;
             }
             else {
                /* emit program constant */




More information about the mesa-commit mailing list