If we have a loop, instructions before the tex might be added as tex uses, and those may in fact dominate all other uses of the tex results. This however doesn't mean that we don't need a texbar after the tex. Only check if uses dominate each other they are dominated by the tex.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96565 Fixes: 7752bbc44 (gk104/ir: simplify and fool-proof texbar algorithm) Signed-off-by: Ilia Mirkin <imir...@alum.mit.edu> Cc: "11.2 12.0" <mesa-sta...@lists.freedesktop.org> --- .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp | 34 +++++++++++++++------- .../nouveau/codegen/nv50_ir_lowering_nvc0.h | 5 ++-- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp index 71013eb..67bd73b 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp @@ -172,19 +172,33 @@ NVC0LegalizePostRA::addTexUse(std::list<TexUse> &uses, Instruction *usei, const Instruction *texi) { bool add = true; - for (std::list<TexUse>::iterator it = uses.begin(); - it != uses.end();) { - if (insnDominatedBy(usei, it->insn)) { - add = false; - break; - } - if (insnDominatedBy(it->insn, usei)) - it = uses.erase(it); - else + bool dominated = insnDominatedBy(usei, texi); + // Uses before the tex have to all be included. Just because an earlier + // instruction dominates another instruction doesn't mean that there's no + // way to get from the tex to the later instruction. For example you could + // have nested loops, with the tex in the inner loop, and uses before it in + // both loops - even though the outer loop's instruction would dominate the + // inner's, we still want a texbar before the inner loop's instruction. + // + // However we can still use the eliding logic between uses dominated by the + // tex instruction, as that is unambiguously correct. + if (dominated) { + for (std::list<TexUse>::iterator it = uses.begin(); it != uses.end();) { + if (it->after) { + if (insnDominatedBy(usei, it->insn)) { + add = false; + break; + } + if (insnDominatedBy(it->insn, usei)) { + it = uses.erase(it); + continue; + } + } ++it; + } } if (add) - uses.push_back(TexUse(usei, texi)); + uses.push_back(TexUse(usei, texi, dominated)); } // While it might be tempting to use the an algorithm that just looks at tex diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h index 2321956..4b23303 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h @@ -55,10 +55,11 @@ private: struct TexUse { - TexUse(Instruction *use, const Instruction *tex) - : insn(use), tex(tex), level(-1) { } + TexUse(Instruction *use, const Instruction *tex, bool after) + : insn(use), tex(tex), after(after), level(-1) { } Instruction *insn; const Instruction *tex; // or split / mov + bool after; int level; }; struct Limits -- 2.7.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev