vc4: Kill a bunch of color write calculation when colormask is all off.
authorEric Anholt <eric@anholt.net>
Sun, 1 Feb 2015 22:09:12 +0000 (14:09 -0800)
committerEric Anholt <eric@anholt.net>
Mon, 2 Feb 2015 00:07:24 +0000 (16:07 -0800)
I could have done this in the bit that generates the ANDs and ORs, but
it's probably generally useful.  Sadly, I still need this even if I move
to NIR, because I can't yet express my read of the destination color in
NIR, which I would need to move my blend/logicop/colormask handling into
NIR.

total uniforms in shared programs: 13497 -> 13455 (-0.31%)
uniforms in affected programs:     101 -> 59 (-41.58%)
total instructions in shared programs: 40797 -> 40296 (-1.23%)
instructions in affected programs:     1639 -> 1138 (-30.57%)

src/gallium/drivers/vc4/vc4_opt_algebraic.c

index d36bb2d6596e057294a362fc3b527656bc44108d..994fa907f7745648b8ebf6da00d3d26a63f94d90 100644 (file)
@@ -100,7 +100,7 @@ replace_with_mov(struct vc4_compile *c, struct qinst *inst, struct qreg arg)
 }
 
 static bool
-add_replace_zero(struct vc4_compile *c,
+replace_x_0_with_x(struct vc4_compile *c,
                  struct qinst **defs,
                  struct qinst *inst,
                  int arg)
@@ -112,7 +112,7 @@ add_replace_zero(struct vc4_compile *c,
 }
 
 static bool
-fmul_replace_zero(struct vc4_compile *c,
+replace_x_0_with_0(struct vc4_compile *c,
                   struct qinst **defs,
                   struct qinst *inst,
                   int arg)
@@ -217,16 +217,16 @@ qir_opt_algebraic(struct vc4_compile *c)
                         break;
 
                 case QOP_ADD:
-                        if (add_replace_zero(c, defs, inst, 0) ||
-                            add_replace_zero(c, defs, inst, 1)) {
+                        if (replace_x_0_with_x(c, defs, inst, 0) ||
+                            replace_x_0_with_x(c, defs, inst, 1)) {
                                 progress = true;
                                 break;
                         }
                         break;
 
                 case QOP_FADD:
-                        if (add_replace_zero(c, defs, inst, 0) ||
-                            add_replace_zero(c, defs, inst, 1)) {
+                        if (replace_x_0_with_x(c, defs, inst, 0) ||
+                            replace_x_0_with_x(c, defs, inst, 1)) {
                                 progress = true;
                                 break;
                         }
@@ -262,8 +262,8 @@ 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) ||
+                        if (replace_x_0_with_0(c, defs, inst, 0) ||
+                            replace_x_0_with_0(c, defs, inst, 1) ||
                             fmul_replace_one(c, defs, inst, 0) ||
                             fmul_replace_one(c, defs, inst, 1)) {
                                 progress = true;
@@ -271,6 +271,33 @@ qir_opt_algebraic(struct vc4_compile *c)
                         }
                         break;
 
+                case QOP_AND:
+                        if (replace_x_0_with_0(c, defs, inst, 0) ||
+                            replace_x_0_with_0(c, defs, inst, 1)) {
+                                progress = true;
+                                break;
+                        }
+
+                        if (is_constant_value(c, defs, inst->src[0], ~0)) {
+                                replace_with_mov(c, inst, inst->src[1]);
+                                progress = true;
+                                break;
+                        }
+                        if (is_constant_value(c, defs, inst->src[1], ~0)) {
+                                replace_with_mov(c, inst, inst->src[0]);
+                                progress = true;
+                                break;
+                        }
+                        break;
+
+                case QOP_OR:
+                        if (replace_x_0_with_x(c, defs, inst, 0) ||
+                            replace_x_0_with_x(c, defs, inst, 1)) {
+                                progress = true;
+                                break;
+                        }
+                        break;
+
                 default:
                         break;
                 }