On Thu, Jul 7, 2016 at 5:02 PM, Ian Romanick <i...@freedesktop.org> wrote: > From: Ian Romanick <ian.d.roman...@intel.com> > > Just generate an __intrinsic_atomic_add with a negated parameter. > > Signed-off-by: Ian Romanick <ian.d.roman...@intel.com> > --- > src/compiler/glsl/builtin_functions.cpp | 50 > +++++++++++++++++++++++++++--- > src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 8 ----- > 2 files changed, 46 insertions(+), 12 deletions(-) > > diff --git a/src/compiler/glsl/builtin_functions.cpp > b/src/compiler/glsl/builtin_functions.cpp > index 941ea12..ef3b2b0 100644 > --- a/src/compiler/glsl/builtin_functions.cpp > +++ b/src/compiler/glsl/builtin_functions.cpp > @@ -3310,13 +3310,29 @@ builtin_builder::asin_expr(ir_variable *x, float p0, > float p1) > mul(abs(x), imm(p1)))))))))); > } > > +/** > + * Generate a ir_call to a function with a set of parameters > + * > + * The input \c params can either be a list of \c ir_variable or a list of > + * \c ir_dereference_variable. In the latter case, all nodes will be removed > + * from \c params and used directly as the parameters to the generated > + * \c ir_call. > + */ > ir_call * > builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params) > { > exec_list actual_params; > > - foreach_in_list(ir_variable, var, ¶ms) { > - actual_params.push_tail(var_ref(var)); > + foreach_in_list_safe(ir_instruction, ir, ¶ms) { > + ir_dereference_variable *d = ir->as_dereference_variable(); > + if (d != NULL) { > + d->remove(); > + actual_params.push_tail(d); > + } else { > + ir_variable *var = ir->as_variable(); > + assert(var != NULL); > + actual_params.push_tail(var_ref(var)); > + } > } > > ir_function_signature *sig = > @@ -5292,8 +5308,34 @@ builtin_builder::_atomic_counter_op1(const char > *intrinsic, > MAKE_SIG(glsl_type::uint_type, avail, 2, counter, data); > > ir_variable *retval = body.make_temp(glsl_type::uint_type, > "atomic_retval"); > - body.emit(call(shader->symbols->get_function(intrinsic), retval, > - sig->parameters)); > + > + /* Instead of generating an __intrinsic_atomic_sub, generate an > + * __intrinsic_atomic_add with the data parameter negated. > + */ > + if (strcmp("__intrinsic_atomic_sub", intrinsic) == 0) { > + ir_variable *const neg_data = > + body.make_temp(glsl_type::uint_type, "neg_data"); > + > + body.emit(assign(neg_data, neg(data))); > + > + exec_list parameters; > + > + parameters.push_tail(new(mem_ctx) ir_dereference_variable(counter)); > + parameters.push_tail(new(mem_ctx) ir_dereference_variable(neg_data));
I don't get it ... why change call() to allow taking dereferences and create them here rather than just feeding in the ir_variables directly? > + > + ir_function *const func = > + shader->symbols->get_function("__intrinsic_atomic_add"); > + ir_instruction *const c = call(func, retval, parameters); > + > + assert(c != NULL); > + assert(parameters.is_empty()); > + > + body.emit(c); > + } else { > + body.emit(call(shader->symbols->get_function(intrinsic), retval, > + sig->parameters)); > + } > + > body.emit(ret(retval)); > return sig; > } > diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > index 197b3af..3320f2a 100644 > --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp > @@ -3208,13 +3208,6 @@ > glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir) > val = ((ir_instruction *)param)->as_rvalue(); > val->accept(this); > data2 = this->result; > - } else if (!strcmp("__intrinsic_atomic_sub", callee)) { > - opcode = TGSI_OPCODE_ATOMUADD; > - st_src_reg res = get_temp(glsl_type::uvec4_type); > - st_dst_reg dstres = st_dst_reg(res); > - dstres.writemask = dst.writemask; > - emit_asm(ir, TGSI_OPCODE_INEG, dstres, data); > - data = res; > } else { > assert(!"Unexpected intrinsic"); > return; > @@ -3625,7 +3618,6 @@ glsl_to_tgsi_visitor::visit(ir_call *ir) > !strcmp("__intrinsic_atomic_increment", callee) || > !strcmp("__intrinsic_atomic_predecrement", callee) || > !strcmp("__intrinsic_atomic_add", callee) || > - !strcmp("__intrinsic_atomic_sub", callee) || > !strcmp("__intrinsic_atomic_min", callee) || > !strcmp("__intrinsic_atomic_max", callee) || > !strcmp("__intrinsic_atomic_and", callee) || > -- > 2.5.5 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev