Mesa (master): r600g: adjust vs/ps gprs on r600/r700 cards when needed.

Dave Airlie airlied at kemper.freedesktop.org
Thu Jun 9 01:20:32 UTC 2011


Module: Mesa
Branch: master
Commit: 04554c7d3a3b28e8103e50ed54f1ac57c6c11017
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=04554c7d3a3b28e8103e50ed54f1ac57c6c11017

Author: Dave Airlie <airlied at redhat.com>
Date:   Wed Jun  8 14:35:00 2011 +1000

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 at gmail.com>
r600c: bump sq gpr resources if a shader needs more than default

Signed-off-by: Dave Airlie <airlied at redhat.com>

---

 src/gallium/drivers/r600/r600_pipe.h          |    2 +
 src/gallium/drivers/r600/r600_state.c         |   43 +++++++++++++++++++++++++
 src/gallium/drivers/r600/r600_state_common.c  |    8 +++-
 src/gallium/winsys/r600/drm/r600_hw_context.c |   42 ++++++++++++++----------
 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 d92b74e..332f932 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 3851042..5a1c456 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 a670ac0..1eb9389 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 44957db..d065717 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 45bc64f..69f7251 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;




More information about the mesa-commit mailing list