nv50/ir: fix ConstantFolding with saturation
authorKarol Herbst <karolherbst@gmail.com>
Sun, 30 Jul 2017 15:51:22 +0000 (17:51 +0200)
committerIlia Mirkin <imirkin@alum.mit.edu>
Wed, 9 Aug 2017 14:25:26 +0000 (10:25 -0400)
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: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Karol Herbst <karolherbst@gmail.com>
Reviewed-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
[imirkin: generalize the fix for other cases]
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp

index 14c00bd1870aafcad73b84fdc6252df59ea3e9d1..58594f02c7ff9b633085466fd0f9b3cf9f4c061b 100644 (file)
@@ -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;
index dac3e6f814c13b1b3965834a6b2c7ec31bbacda8..cfc0dfc53cf63f5d2f1588561a1427ff5fa7bb79 100644 (file)
@@ -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++;
 }