Mesa (master): r600g/sb: fix scheduling of PRED_SET instructions

Vadim Girlin vadimg at kemper.freedesktop.org
Sun May 26 21:59:54 UTC 2013


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

Author: Vadim Girlin <vadimgirlin at gmail.com>
Date:   Mon May 27 01:39:54 2013 +0400

r600g/sb: fix scheduling of PRED_SET instructions

PRED_SET instructions that update exec mask should be scheduled immediately
prior to the "if-then-else" block, because any instruction that is
inserted after alu clause with PRED_SET and before conditional block is
also conditionally executed by hw (exec mask is already updated at that
moment).

Propbably it's better to make PRED_SET a part of conditional
"if-then-else" block in the IR to handle this more cleanly,
but for now this temporary solution should prevent the problem.

Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>

---

 src/gallium/drivers/r600/sb/sb_gcm.cpp |   16 +++++++++++++++-
 src/gallium/drivers/r600/sb/sb_pass.h  |    4 +++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r600/sb/sb_gcm.cpp b/src/gallium/drivers/r600/sb/sb_gcm.cpp
index b09008c..bccb671 100644
--- a/src/gallium/drivers/r600/sb/sb_gcm.cpp
+++ b/src/gallium/drivers/r600/sb/sb_gcm.cpp
@@ -359,6 +359,13 @@ void gcm::bu_sched_bb(bb_node* bb) {
 
 		for (unsigned sq = SQ_CF; sq < SQ_NUM; ++sq) {
 
+			if (sq == SQ_CF && pending_exec_mask_update) {
+				pending_exec_mask_update = false;
+				sq = SQ_ALU;
+				--sq;
+				continue;
+			}
+
 			if (!bu_ready_next[sq].empty())
 				bu_ready[sq].splice(bu_ready[sq].end(), bu_ready_next[sq]);
 
@@ -599,7 +606,14 @@ void gcm::add_ready(node *n) {
 		bu_ready_early[sq].push_back(n);
 	else if (sq == SQ_ALU && n->is_copy_mov())
 		bu_ready[sq].push_front(n);
-	else
+	else if (n->is_alu_inst()) {
+		alu_node *a = static_cast<alu_node*>(n);
+		if (a->bc.op_ptr->flags & AF_PRED && a->dst[2]) {
+			// PRED_SET instruction that updates exec mask
+			pending_exec_mask_update = true;
+		}
+		bu_ready_next[sq].push_back(n);
+	} else
 		bu_ready_next[sq].push_back(n);
 }
 
diff --git a/src/gallium/drivers/r600/sb/sb_pass.h b/src/gallium/drivers/r600/sb/sb_pass.h
index d5d48c3..a6338ae 100644
--- a/src/gallium/drivers/r600/sb/sb_pass.h
+++ b/src/gallium/drivers/r600/sb/sb_pass.h
@@ -250,13 +250,15 @@ class gcm : public pass {
 
 	static const int rp_threshold = 100;
 
+	bool pending_exec_mask_update;
+
 public:
 
 	gcm(shader &sh) : pass(sh),
 		bu_ready(), bu_ready_next(), bu_ready_early(),
 		ready(), op_map(), uses(), nuc_stk(1), ucs_level(),
 		bu_bb(), pending_defs(), pending_nodes(), cur_sq(),
-		live(), live_count() {}
+		live(), live_count(), pending_exec_mask_update() {}
 
 	virtual int run();
 




More information about the mesa-commit mailing list