[Mesa-dev] [PATCH] i965/fs: Optimize [-]b2f([!]gl_FrontFacing).

Jason Ekstrand jason at jlekstrand.net
Fri Jan 16 08:45:40 PST 2015


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" <mattst88 at 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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20150116/4e547ed2/attachment.html>


More information about the mesa-dev mailing list