[Mesa-dev] [PATCH 06/11] st/mesa: add atomic buffer support

Ilia Mirkin imirkin at alum.mit.edu
Sun Sep 27 00:25:21 PDT 2015


On Sun, Sep 27, 2015 at 3:20 AM, Kai Wasserbäch
<kai at dev.carbon-project.org> wrote:
> Ilia Mirkin wrote on 27.09.2015 08:33:
>> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
>> ---
>>  src/mesa/Makefile.sources                    |   1 +
>>  src/mesa/program/ir_to_mesa.cpp              |   4 +-
>>  src/mesa/state_tracker/st_atom.c             |   5 +
>>  src/mesa/state_tracker/st_atom.h             |   5 +
>>  src/mesa/state_tracker/st_atom_atomicbuf.c   | 151 +++++++++++++++++++++++++++
>>  src/mesa/state_tracker/st_cb_bufferobjects.c |   3 +
>>  src/mesa/state_tracker/st_context.c          |   1 +
>>  src/mesa/state_tracker/st_context.h          |   1 +
>>  src/mesa/state_tracker/st_extensions.c       |  15 +++
>>  src/mesa/state_tracker/st_glsl_to_tgsi.cpp   | 133 +++++++++++++++++++++--
>>  10 files changed, 310 insertions(+), 9 deletions(-)
>>  create mode 100644 src/mesa/state_tracker/st_atom_atomicbuf.c
>>
>> [...]
>> diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> index 633e90f..28c9637 100644
>> --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
>> @@ -261,6 +261,8 @@ public:
>> [...]
>>
>>  void
>> +glsl_to_tgsi_visitor::visit_atomic_counter_intrinsic(ir_call *ir)
>> +{
>> +   const char *callee = ir->callee->function_name();
>> +   ir_dereference *deref = static_cast<ir_dereference *>(
>> +      ir->actual_parameters.get_head());
>> +   ir_variable *location = deref->variable_referenced();
>> +
>> +   /* XXX use accept */
>> +   st_src_reg buffer(
>> +         PROGRAM_SAMPLER, location->data.binding /* XXX */, GLSL_TYPE_ATOMIC_UINT);
>> +
>> +   /* Calculate the surface offset */
>> +   st_src_reg offset;
>> +   ir_dereference_array *deref_array = deref->as_dereference_array();
>> +
>> +   if (deref_array) {
>> +      offset = get_temp(glsl_type::uint_type);
>> +
>> +      deref_array->array_index->accept(this);
>> +
>> +      emit_asm(ir, TGSI_OPCODE_MUL, st_dst_reg(offset),
>> +               this->result, st_src_reg_for_int(ATOMIC_COUNTER_SIZE));
>> +      emit_asm(ir, TGSI_OPCODE_ADD, st_dst_reg(offset),
>> +               offset, st_src_reg_for_int(location->data.atomic.offset));
>> +   } else {
>> +      offset = st_src_reg_for_int(location->data.atomic.offset);
>> +   }
>> +
>> +   ir->return_deref->accept(this);
>> +   st_dst_reg dst(this->result);
>> +   dst.writemask = WRITEMASK_X;
>> +
>> +   glsl_to_tgsi_instruction *inst;
>> +
>> +   if (!strcmp("__intrinsic_atomic_read", callee)) {
>> +      inst = emit_asm(ir, TGSI_OPCODE_LOAD, dst, offset);
>> +      inst->buffer = buffer;
>> +   } else if (!strcmp("__intrinsic_atomic_increment", callee)) {
>> +      inst = emit_asm(ir, TGSI_OPCODE_ATOMUADD, dst, offset,
>> +                      st_src_reg_for_int(1));
>> +      inst->buffer = buffer;
>> +   } else if (!strcmp("__intrinsic_atomic_predecrement", callee)) {
>> +      inst = emit_asm(ir, TGSI_OPCODE_ATOMUADD, dst, offset,
>> +                      st_src_reg_for_int(-1));
>> +      inst->buffer = buffer;
>> +      emit_asm(ir, TGSI_OPCODE_ADD, dst, this->result, st_src_reg_for_int(-1));
>> +   }
>> +}
>> +
>> +void
>>  glsl_to_tgsi_visitor::visit(ir_call *ir)
>>  {
>>     glsl_to_tgsi_instruction *call_inst;
>>     ir_function_signature *sig = ir->callee;
>> +   const char *callee = sig->function_name();
>>     function_entry *entry = get_function_signature(sig);
>>     int i;
>>
>> +   /* Filter out intrinsics */
>> +   if (!strcmp("__intrinsic_atomic_read", callee) ||
>> +       !strcmp("__intrinsic_atomic_increment", callee) ||
>> +       !strcmp("__intrinsic_atomic_predecrement", callee)) {
>> +      visit_atomic_counter_intrinsic(ir);
>> +      return;
>> +   }
>
> You're doing the same string comparison two times in a row (if you match here).
> Wouldn't it be cheaper to cache the result und pass it in to
> visit_atomic_counter_intrinsic()?
>
> I was thinking of something like
>
> unsigned atomic_intr_type = 0;
> if(!strcmp("__intrinsic_atomic_read", callee))
>   atomic_intr_type = 1;
> else if(!strcmp("__intrinsic_atomic_increment", callee))
>   atomic_intr_type = 2;
> else if(!strcmp("__intrinsic_atomic_predecrement", callee))
>   atomic_intr_type = 3;
>
> if(atomic_intr_type) {
>   visit_atomic_counter_intrinsic(ir, atomic_intr_type);
>   return;
> }
>
> Obviously visit_atomic_counter_intrinsic() would need to take that parameter and
> then replace the respective if block with a check for the right code.
>
>
> This is just a suggestion and I might be totally missing something here. ;-)

You're quite right. ir_call's are rare though, so I doubt this would
have much impact. Happy to stick a todo in there.

  -ilia


More information about the mesa-dev mailing list