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. --Jason On Jan 15, 2015 7:20 PM, "Matt Turner" <matts...@gmail.com> wrote:
> The GLSL compiler optimizes the pattern > > result = [!]gl_FrontFacing ? x : y; > > where x and y are ±0.0 and ±1.0 into > > result = [-]b2f([!]gl_FrontFacing); > > We can do these expressions in two instructions. > > total instructions in shared programs: 5928518 -> 5927775 (-0.01%) > instructions in affected programs: 190021 -> 189278 (-0.39%) > GAINED: 2 > LOST: 0 > > (one of the GAINED programs had been lost in the previous commit) > --- > This patch applies on top of > > > glsl: Optimize certain if-statements to just casts from the condition > > and replaces > > > i965/fs: Optimize (gl_FrontFacing ? x : -1.0) where x is ±0.0. > > src/mesa/drivers/dri/i965/brw_fs.h | 1 + > src/mesa/drivers/dri/i965/brw_fs_visitor.cpp | 55 > ++++++++++++++++++++++++++++ > 2 files changed, 56 insertions(+) > > diff --git a/src/mesa/drivers/dri/i965/brw_fs.h > b/src/mesa/drivers/dri/i965/brw_fs.h > index b5e7db0..60c1201 100644 > --- a/src/mesa/drivers/dri/i965/brw_fs.h > +++ b/src/mesa/drivers/dri/i965/brw_fs.h > @@ -535,6 +535,7 @@ public: > bool try_emit_line(ir_expression *ir); > bool try_emit_mad(ir_expression *ir); > bool try_opt_frontfacing_ternary(ir_if *ir); > + bool try_opt_b2f_frontfacing(ir_expression *ir); > void try_replace_with_sel(); > bool opt_peephole_sel(); > bool opt_peephole_predicated_break(); > diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > index 56b5fe1..5e3fb26 100644 > --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > @@ -687,6 +687,9 @@ fs_visitor::visit(ir_expression *ir) > emit(NOT(this->result, op[0])); > break; > case ir_unop_neg: > + if (try_opt_b2f_frontfacing(ir)) > + return; > + > op[0].negate = !op[0].negate; > emit(MOV(this->result, op[0])); > break; > @@ -964,6 +967,9 @@ fs_visitor::visit(ir_expression *ir) > emit(AND(this->result, op[0], fs_reg(1))); > break; > case ir_unop_b2f: > + if (try_opt_b2f_frontfacing(ir)) > + return; > + > if (brw->gen <= 5) { > resolve_bool_comparison(ir->operands[0], &op[0]); > } > @@ -2806,6 +2812,55 @@ fs_visitor::try_opt_frontfacing_ternary(ir_if *ir) > return false; > } > > +bool > +fs_visitor::try_opt_b2f_frontfacing(ir_expression *ir) > +{ > + bool invert = false, negated = false; > + > + if (ir->operation == ir_unop_neg) { > + ir = ir->operands[0]->as_expression(); > + if (!ir || ir->operation != ir_unop_b2f) > + return false; > + > + negated = true; > + } > + assert(ir->operation == ir_unop_b2f); > + > + ir_dereference_variable *deref; > + ir_expression *expr = ir->operands[0]->as_expression(); > + if (expr && expr->operation == ir_unop_logic_not) { > + deref = expr->operands[0]->as_dereference_variable(); > + invert = true; > + } else { > + deref = ir->operands[0]->as_dereference_variable(); > + } > + > + if (!deref || strcmp(deref->var->name, "gl_FrontFacing") != 0) > + return false; > + > + fs_reg tmp = fs_reg(this, glsl_type::int_type); > + fs_inst *asr_inst; > + > + if (brw->gen >= 6) { > + /* Bit 15 of g0.0 is 0 if the polygon is front facing. */ > + fs_reg g0 = fs_reg(retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_W)); > + asr_inst = emit(ASR(tmp, g0, fs_reg(15))); > + } else { > + /* Bit 31 of g1.6 is 0 if the polygon is front facing. */ > + fs_reg g1_6 = fs_reg(retype(brw_vec1_grf(1, 6), > BRW_REGISTER_TYPE_D)); > + asr_inst = emit(ASR(tmp, g1_6, fs_reg(31))); > + } > + > + if (!invert) > + asr_inst->src[0].negate = true; > + > + fs_inst *and_inst = emit(AND(this->result, tmp, > + fs_reg(negated ? 0xbf800000 : > 0x3f800000))); > + and_inst->dst.type = BRW_REGISTER_TYPE_D; > + > + return true; > +} > + > /** > * Try to replace IF/MOV/ELSE/MOV/ENDIF with SEL. > * > -- > 2.0.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev