[Mesa-dev] [PATCH 3/3] r600g: only emit blocks when they are changed
Bas Nieuwenhuizen
bas at basnieuwenhuizen.nl
Wed Apr 13 11:36:17 PDT 2011
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
More information about the mesa-dev
mailing list