diff options
author | Dave Airlie <[email protected]> | 2011-06-08 14:35:00 +1000 |
---|---|---|
committer | Dave Airlie <[email protected]> | 2011-06-09 11:25:02 +1000 |
commit | 04554c7d3a3b28e8103e50ed54f1ac57c6c11017 (patch) | |
tree | 83165b67573bfd9cb778db08fdbb2f1622097322 /src/gallium | |
parent | d56fe67c6255b1ace84c025c83439ab8cb3f91fe (diff) |
r600g: adjust vs/ps gprs on r600/r700 cards when needed.
Ideally we'd have a compiler and register spilling and all that
but this is good enough for now to avoid the gpu hang in piglit,
glsl-vs-vec4-indexing-temp-dst-in-nested-loop-combined
on r600/r700 cards.
based on r600c patch
Andre Maasikas <[email protected]>
r600c: bump sq gpr resources if a shader needs more than default
Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/r600/r600_pipe.h | 2 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state.c | 43 | ||||
-rw-r--r-- | src/gallium/drivers/r600/r600_state_common.c | 8 | ||||
-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 |
5 files changed, 77 insertions, 19 deletions
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h index d92b74ebc4e..332f932013a 100644 --- a/src/gallium/drivers/r600/r600_pipe.h +++ b/src/gallium/drivers/r600/r600_pipe.h @@ -205,6 +205,7 @@ struct r600_pipe_context { struct util_slab_mempool pool_transfers; boolean blit; + unsigned default_ps_gprs, default_vs_gprs; }; struct r600_drawl { @@ -270,6 +271,7 @@ void r600_pipe_init_buffer_resource(struct r600_pipe_context *rctx, void r600_pipe_mod_buffer_resource(struct r600_pipe_resource_state *rstate, struct r600_resource *rbuffer, unsigned offset, unsigned stride); +void r600_adjust_gprs(struct r600_pipe_context *rctx); /* r600_texture.c */ void r600_init_screen_texture_functions(struct pipe_screen *screen); diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c index 3851042965c..5a1c456309b 100644 --- a/src/gallium/drivers/r600/r600_state.c +++ b/src/gallium/drivers/r600/r600_state.c @@ -1025,6 +1025,46 @@ void r600_init_state_functions(struct r600_pipe_context *rctx) rctx->context.texture_barrier = r600_texture_barrier; } +void r600_adjust_gprs(struct r600_pipe_context *rctx) +{ + enum radeon_family family; + struct r600_pipe_state rstate; + unsigned num_ps_gprs = rctx->default_ps_gprs; + unsigned num_vs_gprs = rctx->default_vs_gprs; + unsigned tmp; + int diff; + + family = r600_get_family(rctx->radeon); + + if (family >= CHIP_CEDAR) + return; + + if (!rctx->ps_shader && !rctx->vs_shader) + return; + + if (rctx->ps_shader->shader.bc.ngpr > rctx->default_ps_gprs) + { + diff = rctx->ps_shader->shader.bc.ngpr - rctx->default_ps_gprs; + num_vs_gprs -= diff; + num_ps_gprs += diff; + } + + if (rctx->vs_shader->shader.bc.ngpr > rctx->default_vs_gprs) + { + diff = rctx->vs_shader->shader.bc.ngpr - rctx->default_vs_gprs; + num_ps_gprs -= diff; + num_vs_gprs += diff; + } + + tmp = 0; + tmp |= S_008C04_NUM_PS_GPRS(num_ps_gprs); + tmp |= S_008C04_NUM_VS_GPRS(num_vs_gprs); + rstate.nregs = 0; + r600_pipe_state_add_reg(&rstate, R_008C04_SQ_GPR_RESOURCE_MGMT_1, tmp, 0x0FFFFFFF, NULL); + + r600_context_pipe_state_set(&rctx->ctx, &rstate); +} + void r600_init_config(struct r600_pipe_context *rctx) { int ps_prio; @@ -1167,6 +1207,9 @@ void r600_init_config(struct r600_pipe_context *rctx) break; } + rctx->default_ps_gprs = num_ps_gprs; + rctx->default_vs_gprs = num_vs_gprs; + rstate->id = R600_PIPE_STATE_CONFIG; /* SQ_CONFIG */ diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c index a670ac02be2..1eb9389bade 100644 --- a/src/gallium/drivers/r600/r600_state_common.c +++ b/src/gallium/drivers/r600/r600_state_common.c @@ -273,8 +273,10 @@ void r600_bind_ps_shader(struct pipe_context *ctx, void *state) if (state) { r600_context_pipe_state_set(&rctx->ctx, &rctx->ps_shader->rstate); } - if (rctx->ps_shader && rctx->vs_shader) + if (rctx->ps_shader && rctx->vs_shader) { r600_spi_update(rctx); + r600_adjust_gprs(rctx); + } } void r600_bind_vs_shader(struct pipe_context *ctx, void *state) @@ -286,8 +288,10 @@ void r600_bind_vs_shader(struct pipe_context *ctx, void *state) if (state) { r600_context_pipe_state_set(&rctx->ctx, &rctx->vs_shader->rstate); } - if (rctx->ps_shader && rctx->vs_shader) + if (rctx->ps_shader && rctx->vs_shader) { r600_spi_update(rctx); + r600_adjust_gprs(rctx); + } } void r600_delete_ps_shader(struct pipe_context *ctx, void *state) diff --git a/src/gallium/winsys/r600/drm/r600_hw_context.c b/src/gallium/winsys/r600/drm/r600_hw_context.c index 44957db89af..d065717022c 100644 --- a/src/gallium/winsys/r600/drm/r600_hw_context.c +++ b/src/gallium/winsys/r600/drm/r600_hw_context.c @@ -40,6 +40,17 @@ #define GROUP_FORCE_NEW_BLOCK 0 +static inline void r600_context_ps_partial_flush(struct r600_context *ctx) +{ + if (!(ctx->flags & R600_CONTEXT_DRAW_PENDING)) + return; + + ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0); + ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4); + + ctx->flags &= ~R600_CONTEXT_DRAW_PENDING; +} + void r600_init_cs(struct r600_context *ctx) { /* R6xx requires this packet at the start of each command buffer */ @@ -116,6 +127,9 @@ static void r600_init_block(struct r600_context *ctx, LIST_ADDTAIL(&block->list,&ctx->dirty); } } + if (reg[i+j].flags & REG_FLAG_FLUSH_CHANGE) { + block->flags |= REG_FLAG_FLUSH_CHANGE; + } if (reg[i+j].flags & REG_FLAG_NEED_BO) { block->nbo++; @@ -206,13 +220,13 @@ int r600_context_add_block(struct r600_context *ctx, const struct r600_reg *reg, /* R600/R700 configuration */ static const struct r600_reg r600_config_reg_list[] = { {R_008958_VGT_PRIMITIVE_TYPE, 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_008C10_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS, 0, 0}, - {R_008C14_SQ_STACK_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_008C00_SQ_CONFIG, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C04_SQ_GPR_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C08_SQ_GPR_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C0C_SQ_THREAD_RESOURCE_MGMT, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C10_SQ_STACK_RESOURCE_MGMT_1, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008C14_SQ_STACK_RESOURCE_MGMT_2, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, + {R_008D8C_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, REG_FLAG_ENABLE_ALWAYS | REG_FLAG_FLUSH_CHANGE, 0, 0}, {R_009508_TA_CNTL_AUX, REG_FLAG_ENABLE_ALWAYS, 0, 0}, {R_009714_VC_ENHANCE, REG_FLAG_ENABLE_ALWAYS, 0, 0}, {R_009830_DB_DEBUG, REG_FLAG_ENABLE_ALWAYS, 0, 0}, @@ -1008,6 +1022,10 @@ void r600_context_dirty_block(struct r600_context *ctx, LIST_ADDTAIL(&block->enable_list, &ctx->enable_list); } LIST_ADDTAIL(&block->list,&ctx->dirty); + + if (block->flags & REG_FLAG_FLUSH_CHANGE) { + r600_context_ps_partial_flush(ctx); + } } } @@ -1187,16 +1205,6 @@ static inline void r600_context_pipe_state_set_sampler(struct r600_context *ctx, r600_context_dirty_block(ctx, block, dirty, 2); } -static inline void r600_context_ps_partial_flush(struct r600_context *ctx) -{ - if (!(ctx->flags & R600_CONTEXT_DRAW_PENDING)) - return; - - ctx->pm4[ctx->pm4_cdwords++] = PKT3(PKT3_EVENT_WRITE, 0, 0); - ctx->pm4[ctx->pm4_cdwords++] = EVENT_TYPE(EVENT_TYPE_PS_PARTIAL_FLUSH) | EVENT_INDEX(4); - - ctx->flags &= ~R600_CONTEXT_DRAW_PENDING; -} static inline void r600_context_pipe_state_set_sampler_border(struct r600_context *ctx, struct r600_pipe_state *state, unsigned offset) { diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h index 45bc64fcf9a..69f7251c043 100644 --- a/src/gallium/winsys/r600/drm/r600_priv.h +++ b/src/gallium/winsys/r600/drm/r600_priv.h @@ -69,6 +69,7 @@ struct radeon { #define REG_FLAG_NOT_R600 8 #define REG_FLAG_ENABLE_ALWAYS 16 #define BLOCK_FLAG_RESOURCE 32 +#define REG_FLAG_FLUSH_CHANGE 64 struct r600_reg { unsigned offset; |