<p dir="ltr">I meant to make this comment earlier but have been busy with other stuff.  I like these optimizations in terms of the code they generate. Good work on figuring those out! That said, I'm a little pensive about adding more GLSL-IR-specific stuff to fs_visitor that we'll just have to rewrite for NIR.  Also, converting "x ? 1.0 : 0.0" to a cast can be done in one line in NIR.<br>
--Jason</p>
<div class="gmail_quote">On Jan 15, 2015 7:20 PM, "Matt Turner" <<a href="mailto:mattst88@gmail.com">mattst88@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The GLSL compiler optimizes the pattern<br>
<br>
   result = [!]gl_FrontFacing ? x : y;<br>
<br>
where x and y are ±0.0 and ±1.0 into<br>
<br>
   result = [-]b2f([!]gl_FrontFacing);<br>
<br>
We can do these expressions in two instructions.<br>
<br>
total instructions in shared programs: 5928518 -> 5927775 (-0.01%)<br>
instructions in affected programs:     190021 -> 189278 (-0.39%)<br>
GAINED:                                2<br>
LOST:                                  0<br>
<br>
(one of the GAINED programs had been lost in the previous commit)<br>
---<br>
This patch applies on top of<br>
<br>
> glsl: Optimize certain if-statements to just casts from the condition<br>
<br>
and replaces<br>
<br>
> i965/fs: Optimize (gl_FrontFacing ? x : -1.0) where x is ±0.0.<br>
<br>
 src/mesa/drivers/dri/i965/brw_fs.h           |  1 +<br>
 src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 55 ++++++++++++++++++++++++++++<br>
 2 files changed, 56 insertions(+)<br>
<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h<br>
index b5e7db0..60c1201 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs.h<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs.h<br>
@@ -535,6 +535,7 @@ public:<br>
    bool try_emit_line(ir_expression *ir);<br>
    bool try_emit_mad(ir_expression *ir);<br>
    bool try_opt_frontfacing_ternary(ir_if *ir);<br>
+   bool try_opt_b2f_frontfacing(ir_expression *ir);<br>
    void try_replace_with_sel();<br>
    bool opt_peephole_sel();<br>
    bool opt_peephole_predicated_break();<br>
diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp<br>
index 56b5fe1..5e3fb26 100644<br>
--- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp<br>
+++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp<br>
@@ -687,6 +687,9 @@ fs_visitor::visit(ir_expression *ir)<br>
       emit(NOT(this->result, op[0]));<br>
       break;<br>
    case ir_unop_neg:<br>
+      if (try_opt_b2f_frontfacing(ir))<br>
+         return;<br>
+<br>
       op[0].negate = !op[0].negate;<br>
       emit(MOV(this->result, op[0]));<br>
       break;<br>
@@ -964,6 +967,9 @@ fs_visitor::visit(ir_expression *ir)<br>
       emit(AND(this->result, op[0], fs_reg(1)));<br>
       break;<br>
    case ir_unop_b2f:<br>
+      if (try_opt_b2f_frontfacing(ir))<br>
+         return;<br>
+<br>
       if (brw->gen <= 5) {<br>
          resolve_bool_comparison(ir->operands[0], &op[0]);<br>
       }<br>
@@ -2806,6 +2812,55 @@ fs_visitor::try_opt_frontfacing_ternary(ir_if *ir)<br>
    return false;<br>
 }<br>
<br>
+bool<br>
+fs_visitor::try_opt_b2f_frontfacing(ir_expression *ir)<br>
+{<br>
+   bool invert = false, negated = false;<br>
+<br>
+   if (ir->operation == ir_unop_neg) {<br>
+      ir = ir->operands[0]->as_expression();<br>
+      if (!ir || ir->operation != ir_unop_b2f)<br>
+         return false;<br>
+<br>
+      negated = true;<br>
+   }<br>
+   assert(ir->operation == ir_unop_b2f);<br>
+<br>
+   ir_dereference_variable *deref;<br>
+   ir_expression *expr = ir->operands[0]->as_expression();<br>
+   if (expr && expr->operation == ir_unop_logic_not) {<br>
+      deref = expr->operands[0]->as_dereference_variable();<br>
+      invert = true;<br>
+   } else {<br>
+      deref = ir->operands[0]->as_dereference_variable();<br>
+   }<br>
+<br>
+   if (!deref || strcmp(deref->var->name, "gl_FrontFacing") != 0)<br>
+      return false;<br>
+<br>
+   fs_reg tmp = fs_reg(this, glsl_type::int_type);<br>
+   fs_inst *asr_inst;<br>
+<br>
+   if (brw->gen >= 6) {<br>
+      /* Bit 15 of g0.0 is 0 if the polygon is front facing. */<br>
+      fs_reg g0 = fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_W));<br>
+      asr_inst = emit(ASR(tmp, g0, fs_reg(15)));<br>
+   } else {<br>
+      /* Bit 31 of g1.6 is 0 if the polygon is front facing. */<br>
+      fs_reg g1_6 = fs_reg(retype(brw_vec1_grf(1, 6), BRW_REGISTER_TYPE_D));<br>
+      asr_inst = emit(ASR(tmp, g1_6, fs_reg(31)));<br>
+   }<br>
+<br>
+   if (!invert)<br>
+      asr_inst->src[0].negate = true;<br>
+<br>
+   fs_inst *and_inst = emit(AND(this->result, tmp,<br>
+                                fs_reg(negated ? 0xbf800000 : 0x3f800000)));<br>
+   and_inst->dst.type = BRW_REGISTER_TYPE_D;<br>
+<br>
+   return true;<br>
+}<br>
+<br>
 /**<br>
  * Try to replace IF/MOV/ELSE/MOV/ENDIF with SEL.<br>
  *<br>
--<br>
2.0.4<br>
<br>
_______________________________________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev" target="_blank">http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</blockquote></div>