[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