On Thu, Jul 7, 2016 at 9:26 PM, Ian Romanick <i...@freedesktop.org> wrote: > On 07/07/2016 04:58 PM, Ilia Mirkin wrote: >> 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? > > Oh, I already went down that path. :) neg_data would have to be in two > lists at the same time: the instruction stream and parameters. > Restructuring the code so that the ir_variables could be in parameters > then move them to the instruction stream was... enough to make a grown > Mick Jagger cry. > > I'm not terribly enamored with this solution either, but I didn't see a > better way.
How does it work in the "normal" case, i.e. if I just write GLSL that looks like int foo = 1; bar(foo) Is there a separate ir_variable created to hold the foo inside the call? If so, that seems easy enough too ... perhaps there's a non-obvious reason why that turns into a pile of sadness? _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev