[Mesa-dev] [PATCH 09/13] nir: Add floating point atomic min, max, and compare-swap instrinsics

Ian Romanick idr at freedesktop.org
Mon Aug 20 18:37:38 UTC 2018


On 08/17/2018 05:06 PM, Caio Marcelo de Oliveira Filho wrote:
> On Fri, Jun 22, 2018 at 10:03:54PM -0700, Ian Romanick wrote:
>> From: Ian Romanick <ian.d.romanick at intel.com>
>>
>> Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
>> ---
>>  src/compiler/glsl/glsl_to_nir.cpp            | 32 ++++++++++++++++++++++------
>>  src/compiler/nir/nir_intrinsics.py           | 11 +++++++++-
>>  src/compiler/nir/nir_lower_atomics_to_ssbo.c |  6 +++++-
>>  src/compiler/nir/nir_lower_io.c              |  9 ++++++++
>>  4 files changed, 50 insertions(+), 8 deletions(-)
>>
>> diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
>> index 90e960592a0..4d6f826f72f 100644
>> --- a/src/compiler/glsl/glsl_to_nir.cpp
>> +++ b/src/compiler/glsl/glsl_to_nir.cpp
>> @@ -735,6 +735,8 @@ nir_visitor::visit(ir_call *ir)
>>              op = nir_intrinsic_ssbo_atomic_imin;
>>           else if (ir->return_deref->type == glsl_type::uint_type)
>>              op = nir_intrinsic_ssbo_atomic_umin;
>> +         else if (ir->return_deref->type == glsl_type::float_type)
>> +            op = nir_intrinsic_ssbo_atomic_fmin;
>>           else
>>              unreachable("Invalid type");
>>           break;
>> @@ -744,6 +746,8 @@ nir_visitor::visit(ir_call *ir)
>>              op = nir_intrinsic_ssbo_atomic_imax;
>>           else if (ir->return_deref->type == glsl_type::uint_type)
>>              op = nir_intrinsic_ssbo_atomic_umax;
>> +         else if (ir->return_deref->type == glsl_type::float_type)
>> +            op = nir_intrinsic_ssbo_atomic_fmax;
>>           else
>>              unreachable("Invalid type");
>>           break;
>> @@ -751,7 +755,9 @@ nir_visitor::visit(ir_call *ir)
>>           op = nir_intrinsic_ssbo_atomic_exchange;
>>           break;
>>        case ir_intrinsic_ssbo_atomic_comp_swap:
>> -         op = nir_intrinsic_ssbo_atomic_comp_swap;
>> +         op = ir->return_deref->type->is_integer_32_64()
>> +            ? nir_intrinsic_ssbo_atomic_comp_swap
>> +            : nir_intrinsic_ssbo_atomic_fcomp_swap;
> 
> Why not compare to glsl_type::float_type?

No particular reason. :)  I guess if we ever get 64-bit float atomics,
we'd need a similar condition.  *shrug*

>>           break;
>>        case ir_intrinsic_shader_clock:
>>           op = nir_intrinsic_shader_clock;
>> @@ -803,6 +809,8 @@ nir_visitor::visit(ir_call *ir)
>>              op = nir_intrinsic_shared_atomic_imin;
>>           else if (ir->return_deref->type == glsl_type::uint_type)
>>              op = nir_intrinsic_shared_atomic_umin;
>> +         else if (ir->return_deref->type == glsl_type::float_type)
>> +            op = nir_intrinsic_shared_atomic_fmin;
>>           else
>>              unreachable("Invalid type");
>>           break;
>> @@ -812,6 +820,8 @@ nir_visitor::visit(ir_call *ir)
>>              op = nir_intrinsic_shared_atomic_imax;
>>           else if (ir->return_deref->type == glsl_type::uint_type)
>>              op = nir_intrinsic_shared_atomic_umax;
>> +         else if (ir->return_deref->type == glsl_type::float_type)
>> +            op = nir_intrinsic_shared_atomic_fmax;
>>           else
>>              unreachable("Invalid type");
>>           break;
>> @@ -819,7 +829,9 @@ nir_visitor::visit(ir_call *ir)
>>           op = nir_intrinsic_shared_atomic_exchange;
>>           break;
>>        case ir_intrinsic_shared_atomic_comp_swap:
>> -         op = nir_intrinsic_shared_atomic_comp_swap;
>> +         op = ir->return_deref->type->is_integer_32_64()
>> +            ? nir_intrinsic_shared_atomic_comp_swap
>> +            : nir_intrinsic_shared_atomic_fcomp_swap;
>>           break;
>>        case ir_intrinsic_vote_any:
>>           op = nir_intrinsic_vote_any;
>> @@ -1068,7 +1080,10 @@ nir_visitor::visit(ir_call *ir)
>>        case nir_intrinsic_ssbo_atomic_xor:
>>        case nir_intrinsic_ssbo_atomic_exchange:
>>        case nir_intrinsic_ssbo_atomic_comp_swap:
>> -      case nir_intrinsic_ssbo_atomic_fadd: {
>> +      case nir_intrinsic_ssbo_atomic_fadd:
>> +      case nir_intrinsic_ssbo_atomic_fmin:
>> +      case nir_intrinsic_ssbo_atomic_fmax:
>> +      case nir_intrinsic_ssbo_atomic_fcomp_swap: {
>>           int param_count = ir->actual_parameters.length();
>>           assert(param_count == 3 || param_count == 4);
>>  
>> @@ -1089,7 +1104,8 @@ nir_visitor::visit(ir_call *ir)
>>  
>>           /* data2 parameter (only with atomic_comp_swap) */
>>           if (param_count == 4) {
>> -            assert(op == nir_intrinsic_ssbo_atomic_comp_swap);
>> +            assert(op == nir_intrinsic_ssbo_atomic_comp_swap ||
>> +                   op == nir_intrinsic_ssbo_atomic_fcomp_swap);
>>              param = param->get_next();
>>              inst = (ir_instruction *) param;
>>              instr->src[3] = nir_src_for_ssa(evaluate_rvalue(inst->as_rvalue()));
>> @@ -1152,7 +1168,10 @@ nir_visitor::visit(ir_call *ir)
>>        case nir_intrinsic_shared_atomic_xor:
>>        case nir_intrinsic_shared_atomic_exchange:
>>        case nir_intrinsic_shared_atomic_comp_swap:
>> -      case nir_intrinsic_shared_atomic_fadd: {
>> +      case nir_intrinsic_shared_atomic_fadd:
>> +      case nir_intrinsic_shared_atomic_fmin:
>> +      case nir_intrinsic_shared_atomic_fmax:
>> +      case nir_intrinsic_shared_atomic_fcomp_swap:  {
>>           int param_count = ir->actual_parameters.length();
>>           assert(param_count == 2 || param_count == 3);
>>  
>> @@ -1168,7 +1187,8 @@ nir_visitor::visit(ir_call *ir)
>>  
>>           /* data2 parameter (only with atomic_comp_swap) */
>>           if (param_count == 3) {
>> -            assert(op == nir_intrinsic_shared_atomic_comp_swap);
>> +            assert(op == nir_intrinsic_shared_atomic_comp_swap ||
>> +                   op == nir_intrinsic_shared_atomic_fcomp_swap);
>>              param = param->get_next();
>>              inst = (ir_instruction *) param;
>>              instr->src[2] =
>> diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py
>> index f1726e54fb0..e492b96346f 100644
>> --- a/src/compiler/nir/nir_intrinsics.py
>> +++ b/src/compiler/nir/nir_intrinsics.py
>> @@ -357,6 +357,9 @@ intrinsic("var_atomic_xor",  src_comp=[1], dest_comp=1, num_vars=1)
>>  intrinsic("var_atomic_exchange", src_comp=[1], dest_comp=1, num_vars=1)
>>  intrinsic("var_atomic_comp_swap", src_comp=[1, 1], dest_comp=1, num_vars=1)
>>  intrinsic("var_atomic_fadd",  src_comp=[1], dest_comp=1, num_vars=1)
>> +intrinsic("var_atomic_fmin",  src_comp=[1], dest_comp=1, num_vars=1)
>> +intrinsic("var_atomic_fmax",  src_comp=[1], dest_comp=1, num_vars=1)
>> +intrinsic("var_atomic_fcomp_swap", src_comp=[1, 1], dest_comp=1, num_vars=1)
>>  
>>  # SSBO atomic intrinsics
>>  #
>> @@ -383,7 +386,10 @@ intrinsic("ssbo_atomic_or",   src_comp=[1, 1, 1], dest_comp=1)
>>  intrinsic("ssbo_atomic_xor",  src_comp=[1, 1, 1], dest_comp=1)
>>  intrinsic("ssbo_atomic_exchange", src_comp=[1, 1, 1], dest_comp=1)
>>  intrinsic("ssbo_atomic_comp_swap", src_comp=[1, 1, 1, 1], dest_comp=1)
>> -intrinsic("ssbo_atomic_fadd",  src_comp=[1, 1, 1], dest_comp=1)
>> +intrinsic("ssbo_atomic_fadd", src_comp=[1, 1, 1], dest_comp=1)
>> +intrinsic("ssbo_atomic_fmin", src_comp=[1, 1, 1], dest_comp=1)
>> +intrinsic("ssbo_atomic_fmax", src_comp=[1, 1, 1], dest_comp=1)
>> +intrinsic("ssbo_atomic_fcomp_swap", src_comp=[1, 1, 1, 1], dest_comp=1)
>>  
>>  # CS shared variable atomic intrinsics
>>  #
>> @@ -410,6 +416,9 @@ intrinsic("shared_atomic_xor",  src_comp=[1, 1], dest_comp=1, indices=[BASE])
>>  intrinsic("shared_atomic_exchange", src_comp=[1, 1], dest_comp=1, indices=[BASE])
>>  intrinsic("shared_atomic_comp_swap", src_comp=[1, 1, 1], dest_comp=1, indices=[BASE])
>>  intrinsic("shared_atomic_fadd",  src_comp=[1, 1], dest_comp=1, indices=[BASE])
>> +intrinsic("shared_atomic_fmin",  src_comp=[1, 1], dest_comp=1, indices=[BASE])
>> +intrinsic("shared_atomic_fmax",  src_comp=[1, 1], dest_comp=1, indices=[BASE])
>> +intrinsic("shared_atomic_fcomp_swap", src_comp=[1, 1, 1], dest_comp=1, indices=[BASE])
>>  
>>  def system_value(name, dest_comp, indices=[]):
>>      intrinsic("load_" + name, [], dest_comp, 0, indices,
>> diff --git a/src/compiler/nir/nir_lower_atomics_to_ssbo.c b/src/compiler/nir/nir_lower_atomics_to_ssbo.c
>> index 72af914fb47..3af9acafef2 100644
>> --- a/src/compiler/nir/nir_lower_atomics_to_ssbo.c
>> +++ b/src/compiler/nir/nir_lower_atomics_to_ssbo.c
>> @@ -58,6 +58,9 @@ lower_instr(nir_intrinsic_instr *instr, unsigned ssbo_offset, nir_builder *b)
>>     case nir_intrinsic_ssbo_atomic_exchange:
>>     case nir_intrinsic_ssbo_atomic_comp_swap:
>>     case nir_intrinsic_ssbo_atomic_fadd:
>> +   case nir_intrinsic_ssbo_atomic_fmin:
>> +   case nir_intrinsic_ssbo_atomic_fmax:
>> +   case nir_intrinsic_ssbo_atomic_fcomp_swap:
>>     case nir_intrinsic_store_ssbo:
>>     case nir_intrinsic_load_ssbo:
>>     case nir_intrinsic_get_buffer_size:
>> @@ -138,7 +141,8 @@ lower_instr(nir_intrinsic_instr *instr, unsigned ssbo_offset, nir_builder *b)
>>        new_instr->src[0] = nir_src_for_ssa(buffer);
>>        nir_src_copy(&new_instr->src[1], &instr->src[0], new_instr);
>>        nir_src_copy(&new_instr->src[2], &instr->src[1], new_instr);
>> -      if (op == nir_intrinsic_ssbo_atomic_comp_swap)
>> +      if (op == nir_intrinsic_ssbo_atomic_comp_swap ||
>> +          op == nir_intrinsic_ssbo_atomic_fcomp_swap)
>>           nir_src_copy(&new_instr->src[3], &instr->src[2], new_instr);
>>        break;
>>     }
>> diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
>> index 9a30564d988..01367b37dc9 100644
>> --- a/src/compiler/nir/nir_lower_io.c
>> +++ b/src/compiler/nir/nir_lower_io.c
>> @@ -287,6 +287,9 @@ lower_atomic(nir_intrinsic_instr *intrin, struct lower_io_state *state,
>>     OP(atomic_or)
>>     OP(atomic_xor)
>>     OP(atomic_fadd)
>> +   OP(atomic_fmin)
>> +   OP(atomic_fmax)
>> +   OP(atomic_fcomp_swap)
>>  #undef OP
>>     default:
>>        unreachable("Invalid atomic");
>> @@ -387,6 +390,9 @@ nir_lower_io_block(nir_block *block,
>>        case nir_intrinsic_var_atomic_exchange:
>>        case nir_intrinsic_var_atomic_comp_swap:
>>        case nir_intrinsic_var_atomic_fadd:
>> +      case nir_intrinsic_var_atomic_fmin:
>> +      case nir_intrinsic_var_atomic_fmax:
>> +      case nir_intrinsic_var_atomic_fcomp_swap:
>>           /* We can lower the io for this nir instrinsic */
>>           break;
>>        case nir_intrinsic_interp_var_at_centroid:
>> @@ -448,6 +454,9 @@ nir_lower_io_block(nir_block *block,
>>        case nir_intrinsic_var_atomic_exchange:
>>        case nir_intrinsic_var_atomic_comp_swap:
>>        case nir_intrinsic_var_atomic_fadd:
>> +      case nir_intrinsic_var_atomic_fmin:
>> +      case nir_intrinsic_var_atomic_fmax:
>> +      case nir_intrinsic_var_atomic_fcomp_swap:
>>           assert(vertex_index == NULL);
>>           replacement = lower_atomic(intrin, state, offset);
>>           break;
>> -- 
>> 2.14.4
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 



More information about the mesa-dev mailing list