[Mesa-dev] [PATCH 09/13] nir: Add floating point atomic min, max, and compare-swap instrinsics
Ian Romanick
idr at freedesktop.org
Sat Jun 23 05:03:54 UTC 2018
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;
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
More information about the mesa-dev
mailing list