From: Karol Herbst Date: Sun, 30 Jul 2017 15:51:22 +0000 (+0200) Subject: nv50/ir: fix ConstantFolding with saturation X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=24a799ad35a824fba94062f9b018f603717ed145;p=mesa.git nv50/ir: fix ConstantFolding with saturation For mul(a, +-1) codegen can generate OP_MOV with a saturation flag set which is ignored at emission. The same can happen with add(a, 0), and others. Adding an assert for detecting more of such issues. Fixes wrongly rendered water in Hitman Absolution running under wine. Also a few shaders in Mad Max and Alien Isolation produce such MOVs. CC: Signed-off-by: Karol Herbst Reviewed-by: Tobias Klausmann [imirkin: generalize the fix for other cases] Reviewed-by: Ilia Mirkin --- diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp index 14c00bd1870..58594f02c7f 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp @@ -2006,6 +2006,7 @@ CodeEmitterNVC0::getSRegEncoding(const ValueRef& ref) void CodeEmitterNVC0::emitMOV(const Instruction *i) { + assert(!i->saturate); if (i->def(0).getFile() == FILE_PREDICATE) { if (i->src(0).getFile() == FILE_GPR) { code[0] = 0xfc01c003; diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp index dac3e6f814c..cfc0dfc53cf 100644 --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp @@ -1509,6 +1509,14 @@ ConstantFolding::opnd(Instruction *i, ImmediateValue &imm0, int s) default: return; } + + // This can get left behind some of the optimizations which simplify + // saturatable values. + if (newi->op == OP_MOV && newi->saturate) { + newi->saturate = 0; + newi->op = OP_SAT; + } + if (newi->op != op) foldCount++; }