diff --git a/src/freedreno/ir3/ir3.c b/src/freedreno/ir3/ir3.c index b57344e30b8..c1e16ffc0b0 100644 --- a/src/freedreno/ir3/ir3.c +++ b/src/freedreno/ir3/ir3.c @@ -1029,6 +1029,11 @@ ir3_store_const(struct ir3_shader_variant *so, struct ir3_builder *build, stc->cat6.type = TYPE_U32; stc->barrier_conflict = IR3_BARRIER_CONST_W; + /* This isn't necessary for instruction encoding but is used by ir3_sched to + * set up dependencies between stc and const reads. + */ + stc->cat6.dst_offset = dst; + if (a1) { ir3_instr_set_address(stc, a1); stc->flags |= IR3_INSTR_A1EN; diff --git a/src/freedreno/ir3/ir3_sched.c b/src/freedreno/ir3/ir3_sched.c index e68c9b24d9a..c72b7b0c4bc 100644 --- a/src/freedreno/ir3/ir3_sched.c +++ b/src/freedreno/ir3/ir3_sched.c @@ -1372,6 +1372,29 @@ add_barrier_deps(struct ir3_block *block, struct ir3_instruction *instr) } } +static bool +add_const_deps(struct ir3_block *block, struct ir3_instruction *stc) +{ + bool progress = false; + unsigned const_start = stc->cat6.dst_offset; + unsigned const_end = const_start + stc->cat6.iim_val; + + foreach_instr_from (instr, stc, &block->instr_list) { + foreach_src (src, instr) { + if (!(src->flags & IR3_REG_CONST)) { + continue; + } + + if (src->num >= const_start && src->num < const_end) { + ir3_instr_add_dep(instr, stc); + progress = true; + } + } + } + + return progress; +} + /* before scheduling a block, we need to add any necessary false-dependencies * to ensure that: * @@ -1392,6 +1415,10 @@ ir3_sched_add_deps(struct ir3 *ir) add_barrier_deps(block, instr); progress = true; } + + if (instr->opc == OPC_STC) { + progress |= add_const_deps(block, instr); + } } }