summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/nouveau
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/nouveau')
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp34
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h5
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 71013eb63b5..67bd73bc8c7 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 2321956322e..4b23303d02d 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