diff options
-rw-r--r-- | src/gallium/drivers/r600/r600.h | 2 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/evergreen_hw_context.c | 46 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_hw_context.c | 42 | ||||
-rw-r--r-- | src/gallium/winsys/r600/drm/r600_priv.h | 1 |
4 files changed, 56 insertions, 35 deletions
diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h index cc70600610e..b1444bf94f4 100644 --- a/src/gallium/drivers/r600/r600.h +++ b/src/gallium/drivers/r600/r600.h @@ -188,6 +188,7 @@ struct r600_block_reloc { struct r600_block { struct list_head list; + struct list_head enable_list; unsigned status; unsigned flags; unsigned start_offset; @@ -251,6 +252,7 @@ struct r600_context { unsigned nblocks; struct r600_block **blocks; struct list_head dirty; + struct list_head enable_list; unsigned pm4_ndwords; unsigned pm4_cdwords; unsigned pm4_dirty_cdwords; diff --git a/src/gallium/winsys/r600/drm/evergreen_hw_context.c b/src/gallium/winsys/r600/drm/evergreen_hw_context.c index 7072461dc59..7a1be87f3dc 100644 --- a/src/gallium/winsys/r600/drm/evergreen_hw_context.c +++ b/src/gallium/winsys/r600/drm/evergreen_hw_context.c @@ -43,31 +43,31 @@ static const struct r600_reg evergreen_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, {R_008A14_PA_CL_ENHANCE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, 0, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, 0, 0, 0}, - {R_008C08_SQ_GPR_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008C0C_SQ_THREAD_RESOURCE_MGMT, 0, 0, 0}, - {R_008C18_SQ_THREAD_RESOURCE_MGMT_1, 0, 0, 0}, - {R_008C1C_SQ_THREAD_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008C20_SQ_STACK_RESOURCE_MGMT_1, 0, 0, 0}, - {R_008C24_SQ_STACK_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008C28_SQ_STACK_RESOURCE_MGMT_3, 0, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0, 0, 0}, - {R_009100_SPI_CONFIG_CNTL, 0, 0, 0}, - {R_00913C_SPI_CONFIG_CNTL_1, 0, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C18_SQ_THREAD_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C1C_SQ_THREAD_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C20_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C24_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C28_SQ_STACK_RESOURCE_MGMT_3, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, }; static const struct r600_reg cayman_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 0, 0, 0}, {R_008A14_PA_CL_ENHANCE, 0, 0, 0}, - {R_008C00_SQ_CONFIG, 0, 0, 0}, - {R_008C04_SQ_GPR_RESOURCE_MGMT_1, 0, 0, 0}, - {CM_R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, 0, 0, 0}, - {CM_R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, 0, 0, 0}, - {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0, 0, 0}, - {R_009100_SPI_CONFIG_CNTL, 0, 0, 0}, - {R_00913C_SPI_CONFIG_CNTL_1, 0, 0, 0}, + {R_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {CM_R_008C10_SQ_GLOBAL_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {CM_R_008C14_SQ_GLOBAL_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_009100_SPI_CONFIG_CNTL, REG_FLAG_ENABLE_ALWAYS, 0, 0}, + {R_00913C_SPI_CONFIG_CNTL_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, }; static const struct r600_reg evergreen_ctl_const_list[] = { @@ -904,6 +904,10 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) ctx->radeon = radeon; LIST_INITHEAD(&ctx->query_list); + /* init dirty list */ + LIST_INITHEAD(&ctx->dirty); + LIST_INITHEAD(&ctx->enable_list); + ctx->range = calloc(NUM_RANGES, sizeof(struct r600_range)); if (!ctx->range) { r = -ENOMEM; @@ -1007,8 +1011,6 @@ int evergreen_context_init(struct r600_context *ctx, struct radeon *radeon) LIST_INITHEAD(&ctx->fenced_bo); - /* init dirty list */ - LIST_INITHEAD(&ctx->dirty); return 0; out_err: r600_context_fini(ctx); @@ -1048,6 +1050,7 @@ static inline void evergreen_context_pipe_state_set_sampler(struct r600_context if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } dirty = block->status & R600_BLOCK_STATUS_DIRTY; @@ -1086,6 +1089,7 @@ static inline void evergreen_context_pipe_state_set_sampler_border(struct r600_c if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } if (state->nregs <= 3) { diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 1fd6d344798..c5551b2674c 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -98,11 +98,17 @@ static void r600_init_block(struct r600_context *ctx, block->nreg_dirty = n; block->flags = 0; LIST_INITHEAD(&block->list); + LIST_INITHEAD(&block->enable_list); for (j = 0; j < n; j++) { if (reg[i+j].flags & REG_FLAG_DIRTY_ALWAYS) { block->flags |= REG_FLAG_DIRTY_ALWAYS; } + if (reg[i+j].flags & REG_FLAG_ENABLE_ALWAYS) { + block->status |= R600_BLOCK_STATUS_ENABLED; + LIST_ADDTAIL(&block->enable_list, &ctx->enable_list); + } + if (reg[i+j].flags & REG_FLAG_NEED_BO) { block->nbo++; assert(block->nbo < R600_BLOCK_MAX_BO); @@ -184,6 +190,7 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, } r600_init_block(ctx, block, reg, i, n, opcode, offset_base); + } return 0; } @@ -768,6 +775,10 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) ctx->radeon = radeon; LIST_INITHEAD(&ctx->query_list); + /* init dirty list */ + LIST_INITHEAD(&ctx->dirty); + LIST_INITHEAD(&ctx->enable_list); + ctx->range = calloc(NUM_RANGES, sizeof(struct r600_range)); if (!ctx->range) { r = -ENOMEM; @@ -861,9 +872,6 @@ int r600_context_init(struct r600_context *ctx, struct radeon *radeon) LIST_INITHEAD(&ctx->fenced_bo); - /* init dirty list */ - LIST_INITHEAD(&ctx->dirty); - ctx->max_db = 4; return 0; @@ -985,17 +993,20 @@ void r600_context_reg(struct r600_context *ctx, r600_context_dirty_block(ctx, block, dirty, id); } -void r600_context_dirty_block(struct r600_context *ctx, struct r600_block *block, +void r600_context_dirty_block(struct r600_context *ctx, + struct r600_block *block, int dirty, int index) { if ((index + 1) > block->nreg_dirty) block->nreg_dirty = index + 1; if ((dirty != (block->status & R600_BLOCK_STATUS_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; + if (!(block->status & R600_BLOCK_STATUS_ENABLED)) { + block->status |= R600_BLOCK_STATUS_ENABLED; + LIST_ADDTAIL(&block->enable_list, &ctx->enable_list); + } LIST_ADDTAIL(&block->list,&ctx->dirty); } } @@ -1052,6 +1063,7 @@ void r600_context_pipe_state_set_resource(struct r600_context *ctx, struct r600_ r600_bo_reference(ctx->radeon, &block->reloc[1].bo, NULL); r600_bo_reference(ctx->radeon , &block->reloc[2].bo, NULL); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } @@ -1143,6 +1155,7 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } dirty = block->status & R600_BLOCK_STATUS_DIRTY; @@ -1180,6 +1193,7 @@ static inline void r600_context_pipe_state_set_sampler_border(struct r600_contex if (state == NULL) { block->status &= ~(R600_BLOCK_STATUS_ENABLED | R600_BLOCK_STATUS_DIRTY); LIST_DELINIT(&block->list); + LIST_DELINIT(&block->enable_list); return; } if (state->nregs <= 3) { @@ -1407,6 +1421,7 @@ void r600_context_flush(struct r600_context *ctx) uint64_t chunk_array[2]; unsigned fence; int r; + struct r600_block *enable_block = NULL, *next_block; if (!ctx->pm4_cdwords) return; @@ -1480,15 +1495,14 @@ void r600_context_flush(struct r600_context *ctx) /* set all valid group as dirty so they get reemited on * next draw command */ - for (int i = 0; i < ctx->nblocks; i++) { - if (ctx->blocks[i]->status & R600_BLOCK_STATUS_ENABLED) { - if(!(ctx->blocks[i]->status & R600_BLOCK_STATUS_DIRTY)) { - LIST_ADDTAIL(&ctx->blocks[i]->list,&ctx->dirty); - } - ctx->pm4_dirty_cdwords += ctx->blocks[i]->pm4_ndwords + ctx->blocks[i]->pm4_flush_ndwords; - ctx->blocks[i]->status |= R600_BLOCK_STATUS_DIRTY; - ctx->blocks[i]->nreg_dirty = ctx->blocks[i]->nreg; + LIST_FOR_EACH_ENTRY(enable_block, &ctx->enable_list, enable_list) { + if(!(enable_block->status & R600_BLOCK_STATUS_DIRTY)) { + LIST_ADDTAIL(&enable_block->list,&ctx->dirty); } + ctx->pm4_dirty_cdwords += enable_block->pm4_ndwords + + enable_block->pm4_flush_ndwords; + enable_block->status |= R600_BLOCK_STATUS_DIRTY; + enable_block->nreg_dirty = enable_block->nreg; } } diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 3e0fd6d7a71..d9cb52409cd 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -66,6 +66,7 @@ struct radeon { #define REG_FLAG_DIRTY_ALWAYS 2 #define REG_FLAG_RV6XX_SBU 4 #define REG_FLAG_NOT_R600 8 +#define REG_FLAG_ENABLE_ALWAYS 16 struct r600_reg { unsigned offset; |