summaryrefslogtreecommitdiff
path: root/src/panfrost/bifrost/bi_schedule.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/panfrost/bifrost/bi_schedule.c')
-rw-r--r--src/panfrost/bifrost/bi_schedule.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/panfrost/bifrost/bi_schedule.c b/src/panfrost/bifrost/bi_schedule.c
index d974d4a98f1..cc0c128f1ea 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) {
@@ -1796,7 +1807,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);