From: Dave Airlie <airl...@redhat.com>

A bunch of CTS tests led me to write
tests/shaders/ssa/fs-while-loop-rotate-value.shader_test
which r600/sb always fell over on.

This patch fixes it, but I'll probably never be 100% sure why.

Anyways what appears to be happening is when gcm is scheduling
the copy_movs used for phis, we have 4 copy_movs in the scheduling
queue, one of them releases a new copy_mov and it gets pushed
to the the front of the scheduling queue, but for correctness
we rely on the previous copy_movs getting emitted first. This
places copy_movs in order on the list.

So if the list is empty, it puts it at the front, if the list
has just copy_movs in it, it goes to the end, otherwise
we iterate the list and insert it between the copy_movs and
subsequent instructions.

Signed-off-by: Dave Airlie <airl...@redhat.com>
---
 src/gallium/drivers/r600/sb/sb_gcm.cpp | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r600/sb/sb_gcm.cpp 
b/src/gallium/drivers/r600/sb/sb_gcm.cpp
index 7776a10fc8..7b4df8bd52 100644
--- a/src/gallium/drivers/r600/sb/sb_gcm.cpp
+++ b/src/gallium/drivers/r600/sb/sb_gcm.cpp
@@ -637,8 +637,23 @@ void gcm::add_ready(node *n) {
        sched_queue_id sq = sh.get_queue_id(n);
        if (n->flags & NF_SCHEDULE_EARLY)
                bu_ready_early[sq].push_back(n);
-       else if (sq == SQ_ALU && n->is_copy_mov())
-               bu_ready[sq].push_front(n);
+       else if (sq == SQ_ALU && n->is_copy_mov()) {
+               if (bu_ready[sq].empty())
+                       bu_ready[sq].push_front(n);
+               else {
+                       bool inserted = false;
+                       for (sched_queue::iterator I = bu_ready[sq].begin(), E 
= bu_ready[sq].end(); I != E; I++) {
+                               node *a = *I;
+                               if (!a->is_copy_mov()) {
+                                       bu_ready[sq].insert(I, n);
+                                       inserted = true;
+                                       break;
+                               }
+                       }
+                       if (!inserted)
+                               bu_ready[sq].push_back(n);
+               }
+       }
        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]) {
-- 
2.14.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to