On 22 August 2013 16:08, Matt Turner <matts...@gmail.com> wrote: > --- > src/glsl/ir_optimization.h | 1 + > src/glsl/lower_instructions.cpp | 106 > ++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 107 insertions(+) >
Depending on how we decide to resolve the "ir_expression writing to one of its parameters" issue I brought up in patch 5, I believe this patch will either need to go away or get substantially rewritten. Patch 15 may also need a small tweak. I've sent comments on patches 3, 5, 8, 10, 11, 12, and 13. Patches 1, 2, 4, 6, 7, 9, and 15 are: Reviewed-by: Paul Berry <stereotype...@gmail.com> > > diff --git a/src/glsl/ir_optimization.h b/src/glsl/ir_optimization.h > index 074686c..51c73bb 100644 > --- a/src/glsl/ir_optimization.h > +++ b/src/glsl/ir_optimization.h > @@ -39,6 +39,7 @@ > #define LRP_TO_ARITH 0x80 > #define BITFIELD_INSERT_TO_BFM_BFI 0x100 > #define LDEXP_TO_ARITH 0x200 > +#define FREXP_TO_ARITH 0x400 > > /** > * \see class lower_packing_builtins_visitor > diff --git a/src/glsl/lower_instructions.cpp > b/src/glsl/lower_instructions.cpp > index 8b0a8e1..495c232 100644 > --- a/src/glsl/lower_instructions.cpp > +++ b/src/glsl/lower_instructions.cpp > @@ -87,6 +87,10 @@ > * ------------- > * Converts ir_binop_ldexp to arithmetic and bit operations. > * > + * FREXP_TO_ARITH: > + * ------------- > + * Converts ir_binop_frexp to arithmetic and bit operations. > + * > * LRP_TO_ARITH: > * ------------- > * Converts ir_triop_lrp to (op0 * (1.0f - op2)) + (op1 * op2). > @@ -131,6 +135,7 @@ private: > void lrp_to_arith(ir_expression *); > void bitfield_insert_to_bfm_bfi(ir_expression *); > void ldexp_to_arith(ir_expression *); > + void frexp_to_arith(ir_expression *); > }; > > /** > @@ -455,6 +460,102 @@ > lower_instructions_visitor::ldexp_to_arith(ir_expression *ir) > this->progress = true; > } > > +void > +lower_instructions_visitor::frexp_to_arith(ir_expression *ir) > +{ > + /* Translates > + * ir_binop_frexp x_input exp > + * into: > + * > + * x = x_input; > + * exp = 0; > + * > + * if (abs(x) != 0.0) { > + * bits = bitcast_f2u(x); > + * > + * exp += (bitcast_f2u(abs(x)) >> exp_shift) + exp_bias; > + * bits &= sign_mantissa_mask; > + * bits |= exponent_mask; > + * x = bitcast_u2f(bits); > + * } > + * return x; > + * > + * which we can't actually implement as such, since the GLSL IR doesn't > + * have vectorized if-statements. We actually implement it without > branches > + * using conditional-select: > + * > + * x = x_input; > + * > + * is_not_zero = abs(x) != 0.0f; > + * > + * exp = u2i(bitcast_f2u(abs(x)) >> exp_shift); > + * exp += cond_sel(is_not_zero, exp_bias, 0); > + * > + * bits = bitcast_f2u(x); > + * bits &= sign_mantissa_mask; > + * bits |= cond_sel(is_not_zero, exponent_mask, 0u); > + * x = bitcast_u2f(bits); > + * return x; > + */ > + > + const unsigned vec_elem = ir->type->vector_elements; > + > + /* Types */ > + const glsl_type *uvec = glsl_type::get_instance(GLSL_TYPE_UINT, > vec_elem, 1); > + const glsl_type *bvec = glsl_type::get_instance(GLSL_TYPE_BOOL, > vec_elem, 1); > + const glsl_type *ivec = glsl_type::get_instance(GLSL_TYPE_INT, > vec_elem, 1); > + > + /* Constants */ > + ir_constant *zeroi = ir_constant::zero(ir, ivec); > + ir_constant *zerou = ir_constant::zero(ir, uvec); > + ir_constant *zerof = ir_constant::zero(ir, ir->type); > + > + ir_constant *exp_bias = new(ir) ir_constant(-126, vec_elem); > + ir_constant *exp_shift = new(ir) ir_constant(23u, vec_elem); > + > + ir_constant *sign_mantissa_mask = new(ir) ir_constant(0x807fffffu, > vec_elem); > + ir_constant *exponent_mask = new(ir) ir_constant(0x3f000000u, > vec_elem); > + > + /* Temporary variables */ > + ir_variable *x = new(ir) ir_variable(ir->type, "x", ir_var_temporary); > + > + ir_variable *bits = new(ir) ir_variable(uvec, "bits", > ir_var_temporary); > + > + ir_variable *is_not_zero = new(ir) ir_variable(bvec, "is_not_zero", > + ir_var_temporary); > + > + /* Variable passed as <exp> parameter */ > + ir_variable *exponent = ir->operands[1]->variable_referenced(); > + > + > + ir_instruction &i = *base_ir; > + > + /* Initialize x = x_input; exponent = 0; */ > + i.insert_before(x); > + i.insert_before(assign(x, ir->operands[0])); > + i.insert_before(is_not_zero); > + i.insert_before(assign(is_not_zero, nequal(abs(x), zerof))); > + > + /* Calculate exponent */ > + /* Use bitcast to unsigned to get shr, not asr. */ > + i.insert_before(assign(exponent, add(u2i(rshift(bitcast_f2u(abs(x)), > + exp_shift)), > + cond_sel(is_not_zero, exp_bias, > + zeroi)))); > + > + /* Calculate mantissa */ > + i.insert_before(bits); > + i.insert_before(assign(bits, bit_and(bitcast_f2u(x), > sign_mantissa_mask))); > + i.insert_before(assign(bits, bit_or(bits, cond_sel(is_not_zero, > + exponent_mask, > zerou)))); > + > + ir->operation = ir_unop_bitcast_u2f; > + ir->operands[0] = new(ir) ir_dereference_variable(bits); > + ir->operands[1] = NULL; > + > + this->progress = true; > +} > + > ir_visitor_status > lower_instructions_visitor::visit_leave(ir_expression *ir) > { > @@ -506,6 +607,11 @@ lower_instructions_visitor::visit_leave(ir_expression > *ir) > ldexp_to_arith(ir); > break; > > + case ir_binop_frexp: > + if (lowering(FREXP_TO_ARITH)) > + frexp_to_arith(ir); > + break; > + > default: > return visit_continue; > } > -- > 1.8.3.2 > > _______________________________________________ > 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