From: Vadim Girlin Date: Sun, 26 May 2013 21:39:54 +0000 (+0400) Subject: r600g/sb: fix scheduling of PRED_SET instructions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ff2a6116992a6592747105fb167cab18603361c0;p=mesa.git 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 --- diff --git a/src/gallium/drivers/r600/sb/sb_gcm.cpp b/src/gallium/drivers/r600/sb/sb_gcm.cpp index b09008c6f08..bccb6713967 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(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 d5d48c3c740..a6338ae0176 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();