diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 2521ff9..04c412b 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -798,10 +798,12 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat { struct r600_range *range; struct r600_block *block; + unsigned status; for (int i = 0; i < state->nregs; i++) { unsigned id; + status = R600_BLOCK_STATUS_DIRTY | R600_BLOCK_STATUS_ENABLED; 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; @@ -810,13 +812,22 @@ void r600_context_pipe_state_set(struct r600_context *ctx, struct r600_pipe_stat if (block->pm4_bo_index[id]) { /* find relocation */ id = block->pm4_bo_index[id]; - r600_bo_reference(ctx->radeon, &block->reloc[id].bo, state->regs[i].bo); + if (state->regs[i].bo) { + r600_bo_reference(ctx->radeon, &block->reloc[id].bo, state->regs[i].bo); + } else { + r600_bo_reference(ctx->radeon, &block->reloc[id].bo, NULL); + status = 0; + block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); + } } - if (!(block->status & R600_BLOCK_STATUS_DIRTY)) { - block->status |= R600_BLOCK_STATUS_ENABLED; - block->status |= R600_BLOCK_STATUS_DIRTY; - ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords; - LIST_ADDTAIL(&block->list,&ctx->dirty); + if (!((block->status & status) ^ status)) { + block->status = status; + if (status) { + ctx->pm4_dirty_cdwords += block->pm4_ndwords + block->pm4_flush_ndwords; + LIST_ADDTAIL(&block->list, &ctx->dirty); + } else { + LIST_DELINIT(&block->list); + } } } }