Mesa (master): pan/mdg: Don't assign destination in writeout block to r1

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Thu Jul 2 19:11:40 UTC 2020


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

Author: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Date:   Tue Jun 30 13:52:05 2020 -0400

pan/mdg: Don't assign destination in writeout block to r1

It will misbehave.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5513>

---

 src/panfrost/midgard/midgard_ra.c | 52 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/panfrost/midgard/midgard_ra.c b/src/panfrost/midgard/midgard_ra.c
index 1cc6431bc63..2cae4814d9f 100644
--- a/src/panfrost/midgard/midgard_ra.c
+++ b/src/panfrost/midgard/midgard_ra.c
@@ -466,7 +466,11 @@ allocate_registers(compiler_context *ctx, bool *spilled)
         if (!ctx->temp_count)
                 return NULL;
 
-        struct lcra_state *l = lcra_alloc_equations(ctx->temp_count, 5);
+        /* Initialize LCRA. Allocate an extra node at the end for a precoloured
+         * r1 for interference */
+
+        struct lcra_state *l = lcra_alloc_equations(ctx->temp_count + 1, 5);
+        unsigned node_r1 = ctx->temp_count;
 
         /* Starts of classes, in bytes */
         l->class_start[REG_CLASS_WORK]  = 16 * 0;
@@ -635,6 +639,52 @@ allocate_registers(compiler_context *ctx, bool *spilled)
                         l->solutions[ins->dest] = (16 * 1) + COMPONENT_W * 4;
         }
 
+        /* Destinations of instructions in a writeout block cannot be assigned
+         * to r1 unless they are actually used as r1 from the writeout itself,
+         * since the writes to r1 are special. A code sequence like:
+         *
+         *      sadd.fmov r1.x, [...]
+         *      vadd.fadd r0, r1, r2
+         *      [writeout branch]
+         *
+         * will misbehave since the r1.x write will be interpreted as a
+         * gl_FragDepth write so it won't show up correctly when r1 is read in
+         * the following segment. We model this as interference.
+         */
+
+        l->solutions[node_r1] = (16 * 1);
+
+        mir_foreach_block(ctx, _blk) {
+                midgard_block *blk = (midgard_block *) _blk;
+
+                mir_foreach_bundle_in_block(blk, v) {
+                        /* We need at least a writeout and nonwriteout instruction */
+                        if (v->instruction_count < 2)
+                                continue;
+
+                        /* Branches always come at the end */
+                        midgard_instruction *br = v->instructions[v->instruction_count - 1];
+
+                        if (!br->writeout)
+                                continue;
+
+                        for (signed i = v->instruction_count - 2; i >= 0; --i) {
+                                midgard_instruction *ins = v->instructions[i];
+
+                                if (ins->dest >= ctx->temp_count)
+                                        continue;
+
+                                bool used_as_r1 = (br->dest == ins->dest);
+
+                                mir_foreach_src(br, s)
+                                        used_as_r1 |= (s > 0) && (br->src[s] == ins->dest);
+
+                                if (!used_as_r1)
+                                        lcra_add_node_interference(l, ins->dest, mir_bytemask(ins), node_r1, 0xFFFF);
+                        }
+                }
+        }
+
         /* Precolour blend input to r0. Note writeout is necessarily at the end
          * and blend shaders are single-RT only so there is only a single
          * writeout block, so this cannot conflict with the writeout r0 (there



More information about the mesa-commit mailing list