aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarol Herbst <[email protected]>2017-07-30 17:51:22 +0200
committerIlia Mirkin <[email protected]>2017-08-09 10:25:26 -0400
commit24a799ad35a824fba94062f9b018f603717ed145 (patch)
treebe402e7cc07cafd5f3d9a423641728e55b5e2544
parentcc43c4a9e56a5f6dd66e6e67074c219e6f87ba26 (diff)
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: <[email protected]> Signed-off-by: Karol Herbst <[email protected]> Reviewed-by: Tobias Klausmann <[email protected]> [imirkin: generalize the fix for other cases] Reviewed-by: Ilia Mirkin <[email protected]>
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_emit_nvc0.cpp1
-rw-r--r--src/gallium/drivers/nouveau/codegen/nv50_ir_peephole.cpp8
2 files changed, 9 insertions, 0 deletions
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++;
}