Mesa (main): pan/bi: Schedule around blend shader register clobbering

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sat Jan 15 22:07:20 UTC 2022


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

Author: Alyssa Rosenzweig <alyssa at collabora.com>
Date:   Sat Jan 15 15:24:17 2022 -0500

pan/bi: Schedule around blend shader register clobbering

By software ABI, a blend shader is permitted to clobber registers
R0-R15. The scheduler needs to be aware of this, to avoid moving a write
to one of these registers past the BLEND itself. Otherwise the schedule
is invalid.

This bug affects GLES3.0, but is rare enough in practice that we had
missed it. It requires a fragment shader to write to multiple render
targets with attached blend shaders, and have temporaries register
allocated to R0-R15 that are not read by the blend shader, but are sunk
past the BLEND instruction by the scheduler. Prevents a regression when
switching boolean representations on:

dEQP-GLES31.functional.shaders.builtin_functions.integer.uaddcarry.uvec4_lowp_fragment

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

---

 src/panfrost/bifrost/bi_schedule.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c
index 7d73b2f9674..88162ecc86e 100644
--- a/src/panfrost/bifrost/bi_schedule.c
+++ b/src/panfrost/bifrost/bi_schedule.c
@@ -197,7 +197,7 @@ bi_is_sched_barrier(bi_instr *I)
 }
 
 static void
-bi_create_dependency_graph(struct bi_worklist st, bool inorder)
+bi_create_dependency_graph(struct bi_worklist st, bool inorder, bool is_blend)
 {
         struct util_dynarray last_read[64], last_write[64];
 
@@ -262,6 +262,17 @@ bi_create_dependency_graph(struct bi_worklist st, bool inorder)
                         }
                 }
 
+                /* Blend shaders are allowed to clobber R0-R15. Treat these
+                 * registers like extra destinations for scheduling purposes.
+                 */
+                if (ins->op == BI_OPCODE_BLEND && !is_blend) {
+                        for (unsigned c = 0; c < 16; ++c) {
+                                add_dependency(last_read, c, i, st.dependents, st.dep_counts);
+                                add_dependency(last_write, c, i, st.dependents, st.dep_counts);
+                                mark_access(last_write, c, i);
+                        }
+                }
+
                 bi_foreach_src(ins, s) {
                         if (ins->src[s].type != BI_INDEX_REGISTER) continue;
 
@@ -414,7 +425,7 @@ bi_flatten_block(bi_block *block, unsigned *len)
  */
 
 static struct bi_worklist
-bi_initialize_worklist(bi_block *block, bool inorder)
+bi_initialize_worklist(bi_block *block, bool inorder, bool is_blend)
 {
         struct bi_worklist st = { };
         st.instructions = bi_flatten_block(block, &st.count);
@@ -425,7 +436,7 @@ bi_initialize_worklist(bi_block *block, bool inorder)
         st.dependents = calloc(st.count, sizeof(st.dependents[0]));
         st.dep_counts = calloc(st.count, sizeof(st.dep_counts[0]));
 
-        bi_create_dependency_graph(st, inorder);
+        bi_create_dependency_graph(st, inorder, is_blend);
         st.worklist = calloc(BITSET_WORDS(st.count), sizeof(BITSET_WORD));
 
         for (unsigned i = 0; i < st.count; ++i) {
@@ -1801,7 +1812,8 @@ bi_schedule_block(bi_context *ctx, bi_block *block)
 
         /* Copy list to dynamic array */
         struct bi_worklist st = bi_initialize_worklist(block,
-                        bifrost_debug & BIFROST_DBG_INORDER);
+                        bifrost_debug & BIFROST_DBG_INORDER,
+                        ctx->inputs->is_blend);
 
         if (!st.count) {
                 bi_free_worklist(st);



More information about the mesa-commit mailing list