previously, we always emitted blocks that were set before a draw, after this
 patch the block only gets emitted when it is really changed.

Also added a force parameter to r600_context_pipe_state_set, because the
shader constant buffers need 2 registers in different blocks updated, even
if only one is dirty, so those blocks are always marked dirty when they
 are set.
---
 src/gallium/drivers/r600/evergreen_state.c         |   16 ++++----
 src/gallium/drivers/r600/r600.h                    |    2 +-
 src/gallium/drivers/r600/r600_state.c              |   16 ++++----
 src/gallium/drivers/r600/r600_state_common.c       |   22 +++++-----
 src/gallium/winsys/r600/drm/evergreen_hw_context.c |   33 ++++++++++++++-
 src/gallium/winsys/r600/drm/r600_hw_context.c      |   43 +++++++++++++++++--
 6 files changed, 97 insertions(+), 35 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index cff79fa..b8ebae0 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -65,7 +65,7 @@ static void evergreen_set_blend_color(struct pipe_context 
*ctx,
 
        free(rctx->states[R600_PIPE_STATE_BLEND_COLOR]);
        rctx->states[R600_PIPE_STATE_BLEND_COLOR] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void *evergreen_create_blend_state(struct pipe_context *ctx,
@@ -539,7 +539,7 @@ static void evergreen_set_clip_state(struct pipe_context 
*ctx,
 
        free(rctx->states[R600_PIPE_STATE_CLIP]);
        rctx->states[R600_PIPE_STATE_CLIP] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void evergreen_set_polygon_stipple(struct pipe_context *ctx,
@@ -591,7 +591,7 @@ static void evergreen_set_scissor_state(struct pipe_context 
*ctx,
 
        free(rctx->states[R600_PIPE_STATE_SCISSOR]);
        rctx->states[R600_PIPE_STATE_SCISSOR] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void evergreen_set_stencil_ref(struct pipe_context *ctx,
@@ -617,7 +617,7 @@ static void evergreen_set_stencil_ref(struct pipe_context 
*ctx,
 
        free(rctx->states[R600_PIPE_STATE_STENCIL_REF]);
        rctx->states[R600_PIPE_STATE_STENCIL_REF] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void evergreen_set_viewport_state(struct pipe_context *ctx,
@@ -643,7 +643,7 @@ static void evergreen_set_viewport_state(struct 
pipe_context *ctx,
 
        free(rctx->states[R600_PIPE_STATE_VIEWPORT]);
        rctx->states[R600_PIPE_STATE_VIEWPORT] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void evergreen_cb(struct r600_pipe_context *rctx, struct 
r600_pipe_state *rstate,
@@ -876,7 +876,7 @@ static void evergreen_set_framebuffer_state(struct 
pipe_context *ctx,
 
        free(rctx->states[R600_PIPE_STATE_FRAMEBUFFER]);
        rctx->states[R600_PIPE_STATE_FRAMEBUFFER] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 
        if (state->zsbuf) {
                evergreen_polygon_offset_update(rctx);
@@ -1276,7 +1276,7 @@ void evergreen_init_config(struct r600_pipe_context *rctx)
 
        r600_pipe_state_add_reg(rstate, R_028810_PA_CL_CLIP_CNTL, 0x0, 
0xFFFFFFFF, NULL);
 
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 void evergreen_polygon_offset_update(struct r600_pipe_context *rctx)
@@ -1324,7 +1324,7 @@ void evergreen_polygon_offset_update(struct 
r600_pipe_context *rctx)
                r600_pipe_state_add_reg(&state,
                                R_028B78_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
                                offset_db_fmt_cntl, 0xFFFFFFFF, NULL);
-               r600_context_pipe_state_set(&rctx->ctx, &state);
+               r600_context_pipe_state_set(&rctx->ctx, &state,FALSE);
        }
 }
 
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 4256a7e..d34f560 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -267,7 +267,7 @@ struct r600_draw {
 
 int r600_context_init(struct r600_context *ctx, struct radeon *radeon);
 void r600_context_fini(struct r600_context *ctx);
-void r600_context_pipe_state_set(struct r600_context *ctx, struct 
r600_pipe_state *state);
+void r600_context_pipe_state_set(struct r600_context *ctx, struct 
r600_pipe_state *state,boolean force);
 void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct 
r600_pipe_state *state, unsigned rid);
 void r600_context_pipe_state_set_vs_resource(struct r600_context *ctx, struct 
r600_pipe_state *state, unsigned rid);
 void r600_context_pipe_state_set_fs_resource(struct r600_context *ctx, struct 
r600_pipe_state *state, unsigned rid);
diff --git a/src/gallium/drivers/r600/r600_state.c 
b/src/gallium/drivers/r600/r600_state.c
index 3a863ae..1b1cfc8 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -91,7 +91,7 @@ void r600_polygon_offset_update(struct r600_pipe_context 
*rctx)
                r600_pipe_state_add_reg(&state,
                                R_028DF8_PA_SU_POLY_OFFSET_DB_FMT_CNTL,
                                offset_db_fmt_cntl, 0xFFFFFFFF, NULL);
-               r600_context_pipe_state_set(&rctx->ctx, &state);
+               r600_context_pipe_state_set(&rctx->ctx, &state,FALSE);
        }
 }
 
@@ -111,7 +111,7 @@ static void r600_set_blend_color(struct pipe_context *ctx,
        r600_pipe_state_add_reg(rstate, R_028420_CB_BLEND_ALPHA, 
fui(state->color[3]), 0xFFFFFFFF, NULL);
        free(rctx->states[R600_PIPE_STATE_BLEND_COLOR]);
        rctx->states[R600_PIPE_STATE_BLEND_COLOR] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void *r600_create_blend_state(struct pipe_context *ctx,
@@ -602,7 +602,7 @@ static void r600_set_clip_state(struct pipe_context *ctx,
 
        free(rctx->states[R600_PIPE_STATE_CLIP]);
        rctx->states[R600_PIPE_STATE_CLIP] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void r600_set_polygon_stipple(struct pipe_context *ctx,
@@ -654,7 +654,7 @@ static void r600_set_scissor_state(struct pipe_context *ctx,
 
        free(rctx->states[R600_PIPE_STATE_SCISSOR]);
        rctx->states[R600_PIPE_STATE_SCISSOR] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void r600_set_stencil_ref(struct pipe_context *ctx,
@@ -680,7 +680,7 @@ static void r600_set_stencil_ref(struct pipe_context *ctx,
 
        free(rctx->states[R600_PIPE_STATE_STENCIL_REF]);
        rctx->states[R600_PIPE_STATE_STENCIL_REF] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void r600_set_viewport_state(struct pipe_context *ctx,
@@ -706,7 +706,7 @@ static void r600_set_viewport_state(struct pipe_context 
*ctx,
 
        free(rctx->states[R600_PIPE_STATE_VIEWPORT]);
        rctx->states[R600_PIPE_STATE_VIEWPORT] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state 
*rstate,
@@ -930,7 +930,7 @@ static void r600_set_framebuffer_state(struct pipe_context 
*ctx,
 
        free(rctx->states[R600_PIPE_STATE_FRAMEBUFFER]);
        rctx->states[R600_PIPE_STATE_FRAMEBUFFER] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 
        if (state->zsbuf) {
                r600_polygon_offset_update(rctx);
@@ -1235,7 +1235,7 @@ void r600_init_config(struct r600_pipe_context *rctx)
        r600_pipe_state_add_reg(rstate, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN, 
0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_028AA0_VGT_INSTANCE_STEP_RATE_0, 
0x00000000, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(rstate, R_028AA4_VGT_INSTANCE_STEP_RATE_1, 
0x00000000, 0xFFFFFFFF, NULL);
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 void r600_pipe_shader_ps(struct pipe_context *ctx, struct r600_pipe_shader 
*shader)
diff --git a/src/gallium/drivers/r600/r600_state_common.c 
b/src/gallium/drivers/r600/r600_state_common.c
index 43dad0c..bd1a8fa 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -43,7 +43,7 @@ void r600_bind_blend_state(struct pipe_context *ctx, void 
*state)
        rstate = &blend->rstate;
        rctx->states[rstate->id] = rstate;
        rctx->cb_target_mask = blend->cb_target_mask;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 void r600_bind_rs_state(struct pipe_context *ctx, void *state)
@@ -59,7 +59,7 @@ void r600_bind_rs_state(struct pipe_context *ctx, void *state)
        rctx->rasterizer = rs;
 
        rctx->states[rs->rstate.id] = &rs->rstate;
-       r600_context_pipe_state_set(&rctx->ctx, &rs->rstate);
+       r600_context_pipe_state_set(&rctx->ctx, &rs->rstate,FALSE);
 
        if (rctx->family >= CHIP_CEDAR) {
                evergreen_polygon_offset_update(rctx);
@@ -99,7 +99,7 @@ void r600_bind_state(struct pipe_context *ctx, void *state)
        if (state == NULL)
                return;
        rctx->states[rstate->id] = rstate;
-       r600_context_pipe_state_set(&rctx->ctx, rstate);
+       r600_context_pipe_state_set(&rctx->ctx, rstate,FALSE);
 }
 
 void r600_delete_state(struct pipe_context *ctx, void *state)
@@ -127,7 +127,7 @@ void r600_bind_vertex_elements(struct pipe_context *ctx, 
void *state)
                                                v->vmgr_elements);
 
                rctx->states[v->rstate.id] = &v->rstate;
-               r600_context_pipe_state_set(&rctx->ctx, &v->rstate);
+               r600_context_pipe_state_set(&rctx->ctx, &v->rstate,FALSE);
        }
 }
 
@@ -235,7 +235,7 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void 
*state)
        /* TODO delete old shader */
        rctx->ps_shader = (struct r600_pipe_shader *)state;
        if (state) {
-               r600_context_pipe_state_set(&rctx->ctx, 
&rctx->ps_shader->rstate);
+               r600_context_pipe_state_set(&rctx->ctx, 
&rctx->ps_shader->rstate,FALSE);
        }
 }
 
@@ -246,7 +246,7 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void 
*state)
        /* TODO delete old shader */
        rctx->vs_shader = (struct r600_pipe_shader *)state;
        if (state) {
-               r600_context_pipe_state_set(&rctx->ctx, 
&rctx->vs_shader->rstate);
+               r600_context_pipe_state_set(&rctx->ctx, 
&rctx->vs_shader->rstate,FALSE);
        }
 }
 
@@ -309,7 +309,7 @@ void r600_spi_update(struct r600_pipe_context *rctx)
 
                r600_pipe_state_add_reg(&rstate, R_028644_SPI_PS_INPUT_CNTL_0 + 
i * 4, tmp, 0xFFFFFFFF, NULL);
        }
-       r600_context_pipe_state_set(&rctx->ctx, &rstate);
+       r600_context_pipe_state_set(&rctx->ctx, &rstate,FALSE);
 }
 
 void r600_set_constant_buffer(struct pipe_context *ctx, uint shader, uint 
index,
@@ -340,7 +340,8 @@ void r600_set_constant_buffer(struct pipe_context *ctx, 
uint shader, uint index,
                r600_pipe_state_add_reg(&rctx->vs_const_buffer,
                                        R_028980_ALU_CONST_CACHE_VS_0,
                                        offset >> 8, 0xFFFFFFFF, rbuffer->r.bo);
-               r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_const_buffer);
+               /* the buffer size always needs to be set together with the 
buffer, so we force it dirty */
+               r600_context_pipe_state_set(&rctx->ctx, 
&rctx->vs_const_buffer,TRUE);
 
                rstate = &rctx->vs_const_buffer_resource[index];
                rstate->id = R600_PIPE_STATE_RESOURCE;
@@ -362,7 +363,8 @@ void r600_set_constant_buffer(struct pipe_context *ctx, 
uint shader, uint index,
                r600_pipe_state_add_reg(&rctx->ps_const_buffer,
                                        R_028940_ALU_CONST_CACHE_PS_0,
                                        offset >> 8, 0xFFFFFFFF, rbuffer->r.bo);
-               r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_const_buffer);
+               /* the buffer size always needs to be set together with the 
buffer, so we force it dirty */
+               r600_context_pipe_state_set(&rctx->ctx, 
&rctx->ps_const_buffer,TRUE);
 
                rstate = &rctx->ps_const_buffer_resource[index];
                rstate->id = R600_PIPE_STATE_RESOURCE;
@@ -517,7 +519,7 @@ void r600_draw_vbo(struct pipe_context *ctx, const struct 
pipe_draw_info *info)
        r600_pipe_state_add_reg(&vgt, R_028238_CB_TARGET_MASK, 
rctx->cb_target_mask & mask, 0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(&vgt, R_03CFF0_SQ_VTX_BASE_VTX_LOC, 0, 
0xFFFFFFFF, NULL);
        r600_pipe_state_add_reg(&vgt, R_03CFF4_SQ_VTX_START_INST_LOC, 
draw.info.start_instance, 0xFFFFFFFF, NULL);
-       r600_context_pipe_state_set(&rctx->ctx, &vgt);
+       r600_context_pipe_state_set(&rctx->ctx, &vgt,FALSE);
 
        rdraw.vgt_num_indices = draw.info.count;
        rdraw.vgt_num_instances = draw.info.instance_count;
diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c 
b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
index fcf73f8..d71e6c5 100644
--- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c
+++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c
@@ -637,6 +637,7 @@ static inline void 
evergreen_context_pipe_state_set_resource(struct r600_context
 {
        struct r600_range *range;
        struct r600_block *block;
+       boolean dirty = FALSE;
 
        range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -647,6 +648,11 @@ static inline void 
evergreen_context_pipe_state_set_resource(struct r600_context
                LIST_DELINIT(&block->list);
                return;
        }
+
+       for(int i = 0; i < 8; i++)
+               if(block->reg[i] != state->regs[i].value)
+                       dirty = TRUE;
+
        block->reg[0] = state->regs[0].value;
        block->reg[1] = state->regs[1].value;
        block->reg[2] = state->regs[2].value;
@@ -660,14 +666,20 @@ static inline void 
evergreen_context_pipe_state_set_resource(struct r600_context
                /* VERTEX RESOURCE, we preted there is 2 bo to relocate so
                 * we have single case btw VERTEX & TEXTURE resource
                 */
+               if(block->reloc[1].bo != state->regs[0].bo || 
block->reloc[2].bo != state->regs[0].bo)
+                       dirty = TRUE;
+
                r600_block_bo_reference(ctx->radeon, &block->reloc[1].bo, 
state->regs[0].bo);
                r600_block_bo_reference(ctx->radeon, &block->reloc[2].bo, 
state->regs[0].bo);
        } else {
                /* TEXTURE RESOURCE */
+               if(block->reloc[1].bo != state->regs[2].bo || 
block->reloc[2].bo != state->regs[3].bo)
+                       dirty = TRUE;
+
                r600_block_bo_reference(ctx->radeon, &block->reloc[1].bo, 
state->regs[2].bo);
                r600_block_bo_reference(ctx->radeon, &block->reloc[2].bo, 
state->regs[3].bo);
        }
-       if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+       if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
@@ -700,6 +712,7 @@ static inline void 
evergreen_context_pipe_state_set_sampler(struct r600_context
 {
        struct r600_range *range;
        struct r600_block *block;
+       boolean dirty = FALSE;
 
        range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -708,10 +721,15 @@ static inline void 
evergreen_context_pipe_state_set_sampler(struct r600_context
                LIST_DELINIT(&block->list);
                return;
        }
+
+       for(int i = 0; i < 3; i++)
+               if(block->reg[i] != state->regs[i].value)
+                       dirty = TRUE;
+
        block->reg[0] = state->regs[0].value;
        block->reg[1] = state->regs[1].value;
        block->reg[2] = state->regs[2].value;
-       if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+       if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
@@ -724,6 +742,7 @@ static inline void 
evergreen_context_pipe_state_set_sampler_border(struct r600_c
        unsigned fake_offset = (offset - R_00A400_TD_PS_SAMPLER0_BORDER_INDEX) 
* 0x100 + 0x40000 + id * 0x1C;
        struct r600_range *range;
        struct r600_block *block;
+       boolean dirty = FALSE;
 
        range = &ctx->range[CTX_RANGE_ID(ctx, fake_offset)];
        block = range->blocks[CTX_BLOCK_ID(ctx, fake_offset)];
@@ -735,12 +754,20 @@ static inline void 
evergreen_context_pipe_state_set_sampler_border(struct r600_c
        if (state->nregs <= 3) {
                return;
        }
+
+       if(block->reg[0] != id)
+               dirty = TRUE;
+
+       for(int i = 1; i < 5; i++)
+               if(block->reg[i] != state->regs[i+2].value)
+                       dirty = TRUE;
+
        block->reg[0] = id;
        block->reg[1] = state->regs[3].value;
        block->reg[2] = state->regs[4].value;
        block->reg[3] = state->regs[5].value;
        block->reg[4] = state->regs[6].value;
-       if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+       if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c 
b/src/gallium/winsys/r600/drm/r600_hw_context.c
index a365f16..aaaffc2 100644
--- a/src/gallium/winsys/r600/drm/r600_hw_context.c
+++ b/src/gallium/winsys/r600/drm/r600_hw_context.c
@@ -832,26 +832,35 @@ void r600_context_bo_reloc(struct r600_context *ctx, u32 
*pm4, struct r600_bo *r
        *pm4 = bo->reloc_id;
 }
 
-void r600_context_pipe_state_set(struct r600_context *ctx, struct 
r600_pipe_state *state)
+void r600_context_pipe_state_set(struct r600_context *ctx, struct 
r600_pipe_state *state,boolean force)
 {
        struct r600_range *range;
        struct r600_block *block;
 
        for (int i = 0; i < state->nregs; i++) {
                unsigned id;
+               boolean dirty=force;
 
                range = &ctx->range[CTX_RANGE_ID(ctx, state->regs[i].offset)];
                block = range->blocks[CTX_BLOCK_ID(ctx, state->regs[i].offset)];
                id = (state->regs[i].offset - block->start_offset) >> 2;
+
+               if((block->reg[id] ^ state->regs[i].value) & 
state->regs[i].mask)
+                       dirty = TRUE;
+
                block->reg[id] &= ~state->regs[i].mask;
                block->reg[id] |= state->regs[i].value;
                if (block->pm4_bo_index[id]) {
                        /* find relocation */
                        id = block->pm4_bo_index[id];
+
+                       if(block->reloc[id].bo != state->regs[i].bo)
+                               dirty = TRUE;
+
                        r600_block_bo_reference(ctx->radeon, 
&block->reloc[id].bo, state->regs[i].bo);
                        state->regs[i].bo->fence = ctx->radeon->fence;
                }
-               if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+               if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                        block->status |= R600_BLOCK_STATUS_ENABLED;
                        block->status |= R600_BLOCK_STATUS_DIRTY;
                        ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
@@ -864,6 +873,7 @@ static inline void 
r600_context_pipe_state_set_resource(struct r600_context *ctx
 {
        struct r600_range *range;
        struct r600_block *block;
+       boolean dirty = FALSE;
 
        range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -874,6 +884,11 @@ static inline void 
r600_context_pipe_state_set_resource(struct r600_context *ctx
                LIST_DELINIT(&block->list);
                return;
        }
+
+       for(int i = 0; i < 7; i++)
+               if(block->reg[i] != state->regs[i].value)
+                       dirty = TRUE;
+
        block->reg[0] = state->regs[0].value;
        block->reg[1] = state->regs[1].value;
        block->reg[2] = state->regs[2].value;
@@ -886,17 +901,23 @@ static inline void 
r600_context_pipe_state_set_resource(struct r600_context *ctx
                /* VERTEX RESOURCE, we preted there is 2 bo to relocate so
                 * we have single case btw VERTEX & TEXTURE resource
                 */
+               if(block->reloc[1].bo != state->regs[0].bo || 
block->reloc[2].bo != state->regs[0].bo)
+                       dirty = TRUE;
+
                r600_block_bo_reference(ctx->radeon, &block->reloc[1].bo, 
state->regs[0].bo);
                r600_block_bo_reference(ctx->radeon, &block->reloc[2].bo, 
state->regs[0].bo);
                state->regs[0].bo->fence = ctx->radeon->fence;
        } else {
                /* TEXTURE RESOURCE */
+               if(block->reloc[1].bo != state->regs[2].bo || 
block->reloc[2].bo != state->regs[3].bo)
+                       dirty = TRUE;
+
                r600_block_bo_reference(ctx->radeon, &block->reloc[1].bo, 
state->regs[2].bo);
                r600_block_bo_reference(ctx->radeon, &block->reloc[2].bo, 
state->regs[3].bo);
                state->regs[2].bo->fence = ctx->radeon->fence;
                state->regs[3].bo->fence = ctx->radeon->fence;
        }
-       if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+       if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
@@ -929,6 +950,7 @@ static inline void 
r600_context_pipe_state_set_sampler(struct r600_context *ctx,
 {
        struct r600_range *range;
        struct r600_block *block;
+       boolean dirty = false;
 
        range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -937,10 +959,15 @@ static inline void 
r600_context_pipe_state_set_sampler(struct r600_context *ctx,
                LIST_DELINIT(&block->list);
                return;
        }
+
+       for(int i = 0; i < 3; i++)
+               if(block->reg[i] != state->regs[i].value)
+                       dirty = TRUE;
+
        block->reg[0] = state->regs[0].value;
        block->reg[1] = state->regs[1].value;
        block->reg[2] = state->regs[2].value;
-       if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+       if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
@@ -952,6 +979,7 @@ static inline void 
r600_context_pipe_state_set_sampler_border(struct r600_contex
 {
        struct r600_range *range;
        struct r600_block *block;
+       boolean dirty = FALSE;
 
        range = &ctx->range[CTX_RANGE_ID(ctx, offset)];
        block = range->blocks[CTX_BLOCK_ID(ctx, offset)];
@@ -963,11 +991,16 @@ static inline void 
r600_context_pipe_state_set_sampler_border(struct r600_contex
        if (state->nregs <= 3) {
                return;
        }
+
+       for(int i = 0; i < 4; i++)
+               if(block->reg[i] != state->regs[i+3].value)
+                       dirty = TRUE;
+
        block->reg[0] = state->regs[3].value;
        block->reg[1] = state->regs[4].value;
        block->reg[2] = state->regs[5].value;
        block->reg[3] = state->regs[6].value;
-       if (!(block->status & R600_BLOCK_STATUS_DIRTY)) {
+       if ((!(block->status & R600_BLOCK_STATUS_DIRTY) && dirty) || 
!(block->status & R600_BLOCK_STATUS_ENABLED)) {
                block->status |= R600_BLOCK_STATUS_ENABLED;
                block->status |= R600_BLOCK_STATUS_DIRTY;
                ctx->pm4_dirty_cdwords += block->pm4_ndwords + 
block->pm4_flush_ndwords;
-- 
1.7.3.4

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to