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