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 <amaasikas@gmail.com> r600c: bump sq gpr resources if a shader needs more than default Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
d56fe67c62
commit
04554c7d3a
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue