diff options
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_hw_context.c | 67 |
1 files changed, 49 insertions, 18 deletions
diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 52abf061cce..c5d81f1a3a2 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -880,6 +880,7 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx struct r600_range *range; struct r600_block *block; int i; + int dirty; range = &ctx->range[CTX_RANGE_ID(ctx, offset)]; block = range->blocks[CTX_BLOCK_ID(ctx, offset)]; @@ -891,26 +892,56 @@ static inline void r600_context_pipe_state_set_resource(struct r600_context *ctx return; } - for (i = 0; i < 7; i++) - block->reg[i] = state->regs[i].value; - - r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); - r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL); - if (state->regs[0].bo) { - /* VERTEX RESOURCE, we preted there is 2 bo to relocate so - * we have single case btw VERTEX & TEXTURE resource - */ - r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[0].bo); - r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[0].bo); - state->regs[0].bo->fence = ctx->radeon->fence; + dirty = block->status & R600_BLOCK_STATUS_DIRTY; + + for (i = 0; i < 7; i++) { + if (block->reg[i] != state->regs[i].value) { + dirty |= R600_BLOCK_STATUS_DIRTY; + block->reg[i] = state->regs[i].value; + } + } + + /* if no BOs on block, force dirty */ + if (!block->reloc[1].bo || !block->reloc[2].bo) + dirty |= R600_BLOCK_STATUS_DIRTY; + + if (!dirty) { + if (state->regs[0].bo) { + if ((block->reloc[1].bo->bo->handle != state->regs[0].bo->bo->handle) || + (block->reloc[2].bo->bo->handle != state->regs[0].bo->bo->handle)) + dirty |= R600_BLOCK_STATUS_DIRTY; + } else { + if ((block->reloc[1].bo->bo->handle != state->regs[2].bo->bo->handle) || + (block->reloc[2].bo->bo->handle != state->regs[3].bo->bo->handle)) + dirty |= R600_BLOCK_STATUS_DIRTY; + } + } + if (!dirty) { + if (state->regs[0].bo) + state->regs[0].bo->fence = ctx->radeon->fence; + else { + state->regs[2].bo->fence = ctx->radeon->fence; + state->regs[3].bo->fence = ctx->radeon->fence; + } } else { - /* TEXTURE RESOURCE */ - r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo); - r600_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; + r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); + r600_bo_reference(ctx->radeon, &block->reloc[2].bo, NULL); + if (state->regs[0].bo) { + /* VERTEX RESOURCE, we preted there is 2 bo to relocate so + * we have single case btw VERTEX & TEXTURE resource + */ + r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[0].bo); + r600_bo_reference(ctx->radeon, &block->reloc[2].bo, state->regs[0].bo); + state->regs[0].bo->fence = ctx->radeon->fence; + } else { + /* TEXTURE RESOURCE */ + r600_bo_reference(ctx->radeon, &block->reloc[1].bo, state->regs[2].bo); + r600_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; + } } - r600_context_dirty_block(ctx, block, R600_BLOCK_STATUS_DIRTY, 6); + r600_context_dirty_block(ctx, block, dirty, 6); } void r600_context_pipe_state_set_ps_resource(struct r600_context *ctx, struct r600_pipe_state *state, unsigned rid) |