[Mesa-dev] [PATCH 04/10] i965/fs: Pull ir_binop_min/ir_binop_max handling to a separate function.

Kenneth Graunke kenneth at whitecape.org
Sun Sep 23 23:09:37 PDT 2012


On 09/22/2012 02:04 PM, Eric Anholt wrote:
> This will be reused from the ARB_fp compiler.  I touched up the pre-gen6 path
> to not overwrite dst in the first instruction, which prevents the need for
> aliasing checks (we'll need that in the ARB_fp compiler, but it actually
> hasn't been needed in this codebase since the revert of the nasty old
> MOV-avoidance code)
> ---
>  src/mesa/drivers/dri/i965/brw_fs.h           |    2 +
>  src/mesa/drivers/dri/i965/brw_fs_visitor.cpp |   52 +++++++++++---------------
>  2 files changed, 23 insertions(+), 31 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.h b/src/mesa/drivers/dri/i965/brw_fs.h
> index 5134857..9cb9590 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.h
> +++ b/src/mesa/drivers/dri/i965/brw_fs.h
> @@ -317,6 +317,8 @@ public:
>  			      fs_reg shadow_comp, fs_reg lod, fs_reg lod2);
>     fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0);
>     fs_inst *emit_math(enum opcode op, fs_reg dst, fs_reg src0, fs_reg src1);
> +   void emit_minmax(uint32_t conditionalmod, fs_reg dst,
> +                    fs_reg src0, fs_reg src1);
>     bool try_emit_saturate(ir_expression *ir);
>     bool try_emit_mad(ir_expression *ir, int mul_arg);
>     void emit_bool_to_cond_code(ir_rvalue *condition);
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
> index 5bd7238..c8d976f 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_visitor.cpp
> @@ -178,6 +178,24 @@ fs_visitor::visit(ir_dereference_array *ir)
>     }
>  }
>  
> +void
> +fs_visitor::emit_minmax(uint32_t conditionalmod, fs_reg dst,
> +                        fs_reg src0, fs_reg src1)
> +{
> +   fs_inst *inst;
> +
> +   if (intel->gen >= 6) {
> +      inst = emit(BRW_OPCODE_SEL, dst, src0, src1);
> +      inst->conditional_mod = conditionalmod;
> +   } else {
> +      inst = emit(BRW_OPCODE_CMP, reg_null_cmp, src0, src1);
> +      inst->conditional_mod = conditionalmod;
> +
> +      inst = emit(BRW_OPCODE_SEL, dst, src0, src1);
> +      inst->predicated = true;
> +   }
> +}
> +
>  /* Instruction selection: Produce a MOV.sat instead of
>   * MIN(MAX(val, 0), 1) when possible.
>   */
> @@ -515,40 +533,12 @@ fs_visitor::visit(ir_expression *ir)
>        break;
>  
>     case ir_binop_min:
> -      resolve_ud_negate(&op[0]);
> -      resolve_ud_negate(&op[1]);
> -
> -      if (intel->gen >= 6) {
> -	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
> -	 inst->conditional_mod = BRW_CONDITIONAL_L;
> -      } else {
> -	 /* Unalias the destination */
> -	 this->result = fs_reg(this, ir->type);
> -
> -	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
> -	 inst->conditional_mod = BRW_CONDITIONAL_L;
> -
> -	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
> -	 inst->predicated = true;
> -      }
> -      break;
>     case ir_binop_max:
>        resolve_ud_negate(&op[0]);
>        resolve_ud_negate(&op[1]);
> -
> -      if (intel->gen >= 6) {
> -	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
> -	 inst->conditional_mod = BRW_CONDITIONAL_GE;
> -      } else {
> -	 /* Unalias the destination */
> -	 this->result = fs_reg(this, ir->type);
> -
> -	 inst = emit(BRW_OPCODE_CMP, this->result, op[0], op[1]);
> -	 inst->conditional_mod = BRW_CONDITIONAL_G;
> -
> -	 inst = emit(BRW_OPCODE_SEL, this->result, op[0], op[1]);
> -	 inst->predicated = true;
> -      }
> +      emit_minmax(ir->operation == ir_binop_min ?
> +                  BRW_CONDITIONAL_L : BRW_CONDITIONAL_GE,
> +                  this->result, op[0], op[1]);
>        break;
>  
>     case ir_binop_pow:

Noticed a small change here: we used to use > on Gen4-5, and your patch
makes us use >=.  It shouldn't matter...if both operands are equal,
either one is an acceptable result.  The added consistency is nice.

You could make that a separate patch (so it's a clean refactor) but I
don't really care that much.


More information about the mesa-dev mailing list