On 12/04/2014 04:37 PM, Matt Turner wrote: > The LINE instruction performs a multiply-add instruction (a * b + c) > where b and c are scalar arguments. It reads b and c from offsets in > src0 such that you can load them (it they're representable) as a > vector-float immediate with a single instruction. > > Hurts some programs, but that'll all get better once we CSE the > vector-float MOVs in the next patch. >
Why only on Gen <= 5? It looks like the instruction still exists at least on Gen6. Either way, the series looks good. Reviewed-by: Ian Romanick <ian.d.roman...@intel.com> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77544 > --- > 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 b29b6b0..fed1208 100644 > --- a/src/mesa/drivers/dri/i965/brw_fs.h > +++ b/src/mesa/drivers/dri/i965/brw_fs.h > @@ -500,6 +500,7 @@ public: > void emit_minmax(enum brw_conditional_mod conditionalmod, const fs_reg > &dst, > const fs_reg &src0, const fs_reg &src1); > bool try_emit_saturate(ir_expression *ir); > + bool try_emit_line(ir_expression *ir); > bool try_emit_mad(ir_expression *ir); > void try_replace_with_sel(); > bool opt_peephole_sel(); > diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > index 62ef853..465e59a 100644 > --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp > @@ -296,6 +296,59 @@ fs_visitor::try_emit_saturate(ir_expression *ir) > } > > bool > +fs_visitor::try_emit_line(ir_expression *ir) > +{ > + /* LINE's src0 must be of type float. */ > + if (ir->type != glsl_type::float_type) > + return false; > + > + ir_rvalue *nonmul = ir->operands[1]; > + ir_expression *mul = ir->operands[0]->as_expression(); > + > + if (!mul || mul->operation != ir_binop_mul) { > + nonmul = ir->operands[0]; > + mul = ir->operands[1]->as_expression(); > + > + if (!mul || mul->operation != ir_binop_mul) > + return false; > + } > + > + ir_constant *const_add = nonmul->as_constant(); > + if (!const_add) > + return false; > + > + int add_operand_vf = brw_float_to_vf(const_add->value.f[0]); > + if (add_operand_vf == -1) > + return false; > + > + ir_rvalue *non_const_mul = mul->operands[1]; > + ir_constant *const_mul = mul->operands[0]->as_constant(); > + if (!const_mul) { > + const_mul = mul->operands[1]->as_constant(); > + > + if (!const_mul) > + return false; > + > + non_const_mul = mul->operands[0]; > + } > + > + int mul_operand_vf = brw_float_to_vf(const_mul->value.f[0]); > + if (mul_operand_vf == -1) > + return false; > + > + non_const_mul->accept(this); > + fs_reg src1 = this->result; > + > + fs_reg src0 = fs_reg(this, ir->type); > + emit(BRW_OPCODE_MOV, src0, > + fs_reg((uint8_t)mul_operand_vf, 0, 0, (uint8_t)add_operand_vf)); > + > + this->result = fs_reg(this, ir->type); > + emit(BRW_OPCODE_LINE, this->result, src0, src1); > + return true; > +} > + > +bool > fs_visitor::try_emit_mad(ir_expression *ir) > { > /* 3-src instructions were introduced in gen6. */ > @@ -482,6 +535,8 @@ fs_visitor::visit(ir_expression *ir) > /* Deal with the real oddball stuff first */ > switch (ir->operation) { > case ir_binop_add: > + if (brw->gen <= 5 && try_emit_line(ir)) > + return; > if (try_emit_mad(ir)) > return; > break; > _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev