diff options
author | Ilia Mirkin <[email protected]> | 2015-12-08 18:21:26 -0500 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2015-12-08 23:15:29 -0500 |
commit | c1c1248b94e17a1a4fa0e6f353377efa99efe602 (patch) | |
tree | d657e41fbc6988aeb88631bbbf63f066662d4d3c | |
parent | 99581ca393037e10d17aab1f4c90ff2bdb1ec557 (diff) |
nv50/ir: reduce degree limit on ops that can't encode large reg dests
Operations that take immediates can only encode registers up to 64. This
fixes a shader in a "Powered by Unity" intro.
Signed-off-by: Ilia Mirkin <[email protected]>
-rw-r--r-- | src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp index f5143bf3137..a7d81774a83 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_ra.cpp @@ -103,6 +103,8 @@ public: void print() const; + const bool restrictedGPR16Range; + private: BitSet bits[LAST_REGISTER_FILE + 1]; @@ -110,8 +112,6 @@ private: int last[LAST_REGISTER_FILE + 1]; int fill[LAST_REGISTER_FILE + 1]; - - const bool restrictedGPR16Range; }; void @@ -840,6 +840,32 @@ GCRA::printNodeInfo() const } } +static bool +isShortRegOp(Instruction *insn) +{ + // Immediates are always in src1. Every other situation can be resolved by + // using a long encoding. + return insn->srcExists(1) && insn->src(1).getFile() == FILE_IMMEDIATE; +} + +// Check if this LValue is ever used in an instruction that can't be encoded +// with long registers (i.e. > r63) +static bool +isShortRegVal(LValue *lval) +{ + if (lval->defs.size() == 0) + return false; + for (Value::DefCIterator def = lval->defs.begin(); + def != lval->defs.end(); ++def) + if (isShortRegOp((*def)->getInsn())) + return true; + for (Value::UseCIterator use = lval->uses.begin(); + use != lval->uses.end(); ++use) + if (isShortRegOp((*use)->getInsn())) + return true; + return false; +} + void GCRA::RIG_Node::init(const RegisterSet& regs, LValue *lval) { @@ -855,7 +881,12 @@ GCRA::RIG_Node::init(const RegisterSet& regs, LValue *lval) weight = std::numeric_limits<float>::infinity(); degree = 0; - degreeLimit = regs.getFileSize(f, lval->reg.size); + int size = regs.getFileSize(f, lval->reg.size); + // On nv50, we lose a bit of gpr encoding when there's an embedded + // immediate. + if (regs.restrictedGPR16Range && f == FILE_GPR && isShortRegVal(lval)) + size /= 2; + degreeLimit = size; degreeLimit -= relDegree[1][colors] - 1; livei.insert(lval->livei); |