<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>