The shaders only depend on the shader itself and the vertex_elements state and 
we don't need to emit the registers again if these are not changed. Tracking is 
also faster than the
memcmp in r600_shader_update, so in some cases that expensive check doesn't 
have to be performed. I also optimized that expensive check by only looping 
through the first count
elements, as the other elements don't matter.
---
 src/gallium/drivers/r600/r600_pipe.h   |    2 ++
 src/gallium/drivers/r600/r600_shader.c |    2 +-
 src/gallium/drivers/r600/r600_state.c  |   10 +++++++---
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_pipe.h 
b/src/gallium/drivers/r600/r600_pipe.h
index c46029a..ec5fbf3 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -130,6 +130,8 @@ struct r600_pipe_context {
        struct u_upload_mgr             *upload_vb;
        struct u_upload_mgr             *upload_ib;
        unsigned                        any_user_vbs;
+       bool                            vs_shader_dirty;
+       bool                            ps_shader_dirty;
 };
 
 struct r600_drawl {
diff --git a/src/gallium/drivers/r600/r600_shader.c 
b/src/gallium/drivers/r600/r600_shader.c
index 016e75b..e92f2b7 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -247,7 +247,7 @@ static int r600_shader_update(struct pipe_context *ctx, 
struct r600_pipe_shader
                return 0;
        /* doing a full memcmp fell over the refcount */
        if ((rshader->vertex_elements.count == rctx->vertex_elements->count) &&
-           (!memcmp(&rshader->vertex_elements.elements, 
&rctx->vertex_elements->elements, 32 * sizeof(struct pipe_vertex_element)))) {
+           (!memcmp(&rshader->vertex_elements.elements, 
&rctx->vertex_elements->elements, rctx->vertex_elements->count * sizeof(struct 
pipe_vertex_element)))) {
                return 0;
        }
        rshader->vertex_elements = *rctx->vertex_elements;
diff --git a/src/gallium/drivers/r600/r600_state.c 
b/src/gallium/drivers/r600/r600_state.c
index b55c345..a5fafd5 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -79,11 +79,13 @@ static void r600_draw_common(struct r600_drawl *draw)
 
 
        /* rebuild vertex shader if input format changed */
-       if (r600_pipe_shader_update(&rctx->context, rctx->vs_shader))
+       if (rctx->vs_shader_dirty && r600_pipe_shader_update(&rctx->context, 
rctx->vs_shader))
                return;
-       if (r600_pipe_shader_update(&rctx->context, rctx->ps_shader))
+       if (rctx->ps_shader_dirty && r600_pipe_shader_update(&rctx->context, 
rctx->ps_shader))
                return;
 
+       rctx->vs_shader_dirty = FALSE;
+       rctx->ps_shader_dirty = FALSE;
        for (i = 0 ; i < rctx->vertex_elements->count; i++) {
                uint32_t word2, format;
 
@@ -801,7 +803,7 @@ static void r600_bind_vertex_elements(struct pipe_context 
*ctx, void *state)
        rctx->vertex_elements = v;
        if (v) {
                v->refcount++;
-//             rctx->vs_rebuild = TRUE;
+               rctx->vs_shader_dirty = TRUE;
        }
 }
 
@@ -1198,6 +1200,7 @@ static void r600_bind_ps_shader(struct pipe_context *ctx, 
void *state)
 
        /* TODO delete old shader */
        rctx->ps_shader = (struct r600_pipe_shader *)state;
+       rctx->ps_shader_dirty = TRUE;
 }
 
 static void r600_bind_vs_shader(struct pipe_context *ctx, void *state)
@@ -1206,6 +1209,7 @@ static void r600_bind_vs_shader(struct pipe_context *ctx, 
void *state)
 
        /* TODO delete old shader */
        rctx->vs_shader = (struct r600_pipe_shader *)state;
+       rctx->vs_shader_dirty = TRUE;
 }
 
 static void r600_delete_ps_shader(struct pipe_context *ctx, void *state)
-- 
1.7.1

_______________________________________________
mesa-dev mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to