[Mesa-dev] [PATCH] r600/sb: fix rotated register in while loop (v3)
Dave Airlie
airlied at gmail.com
Mon Feb 19 04:05:06 UTC 2018
From: Dave Airlie <airlied at 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.
I've added the additional check here that if the src[0]
of the copy mov has a constraint (which will be true for the
(copy) MOV R1.x.2, t10 case but not for MOV t20, cases,
then we should schedule those early, but the others late.
v2: wrong direction.
v3: back to v1 + changes
Signed-off-by: Dave Airlie <airlied at 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 7776a10fc86..0c715b24dfb 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() || n->src[0]->constraint)
+ 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
More information about the mesa-dev
mailing list