summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-10-09 15:02:00 +0200
committerEric Anholt <[email protected]>2014-10-09 21:47:06 +0200
commit0401f55fffc6e77807e6987e23d2709a1599d61e (patch)
tree5ce87cfe7978a07094587776668f141f78e217e9 /src/gallium
parent1cd8c1aab04c4da9aa6cbbd52460607b8416ce1b (diff)
vc4: Optimize fmul(x, 0) and fmul(x, 1).
This was being generated frequently by matrix multiplies of 2 and 3-channel vertex attributes (which have the 0 or 1 loaded in the shader).
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/vc4/vc4_opt_algebraic.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_opt_algebraic.c b/src/gallium/drivers/vc4/vc4_opt_algebraic.c
index 8c6fcef5936..435814e6912 100644
--- a/src/gallium/drivers/vc4/vc4_opt_algebraic.c
+++ b/src/gallium/drivers/vc4/vc4_opt_algebraic.c
@@ -33,6 +33,7 @@
*/
#include "vc4_qir.h"
+#include "util/u_math.h"
static bool debug;
@@ -77,6 +78,16 @@ is_zero(struct vc4_compile *c, struct qinst **defs, struct qreg reg)
c->uniform_data[reg.index] == 0);
}
+static bool
+is_1f(struct vc4_compile *c, struct qinst **defs, struct qreg reg)
+{
+ reg = follow_movs(defs, reg);
+
+ return (reg.file == QFILE_UNIF &&
+ c->uniform_contents[reg.index] == QUNIFORM_CONSTANT &&
+ c->uniform_data[reg.index] == fui(1.0));
+}
+
static void
replace_with_mov(struct vc4_compile *c, struct qinst *inst, struct qreg arg)
{
@@ -87,6 +98,30 @@ replace_with_mov(struct vc4_compile *c, struct qinst *inst, struct qreg arg)
dump_to(c, inst);
}
+static bool
+fmul_replace_zero(struct vc4_compile *c,
+ struct qinst **defs,
+ struct qinst *inst,
+ int arg)
+{
+ if (!is_zero(c, defs, inst->src[arg]))
+ return false;
+ replace_with_mov(c, inst, inst->src[arg]);
+ return true;
+}
+
+static bool
+fmul_replace_one(struct vc4_compile *c,
+ struct qinst **defs,
+ struct qinst *inst,
+ int arg)
+{
+ if (!is_1f(c, defs, inst->src[arg]))
+ return false;
+ replace_with_mov(c, inst, inst->src[1 - arg]);
+ return true;
+}
+
bool
qir_opt_algebraic(struct vc4_compile *c)
{
@@ -177,6 +212,16 @@ qir_opt_algebraic(struct vc4_compile *c)
}
break;
+ case QOP_FMUL:
+ if (fmul_replace_zero(c, defs, inst, 0) ||
+ fmul_replace_zero(c, defs, inst, 1) ||
+ fmul_replace_one(c, defs, inst, 0) ||
+ fmul_replace_one(c, defs, inst, 1)) {
+ progress = true;
+ break;
+ }
+ break;
+
default:
break;
}