[Mesa-dev] [PATCH 09/11] nir/intrinsics: Add more atomic_counter ops

Ian Romanick idr at freedesktop.org
Wed Jul 6 00:46:17 UTC 2016


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                  | 43 +++++++++++++++++++---
 src/compiler/glsl/nir_intrinsic_map.py             |  8 ++++
 .../glsl/tests/get_intrinsic_opcode_test.cpp       |  8 ++++
 src/compiler/nir/nir.c                             |  1 +
 src/compiler/nir/nir_intrinsics.h                  | 14 +++++++
 src/compiler/nir/nir_lower_atomics.c               | 38 +++++++++++++++++++
 6 files changed, 107 insertions(+), 5 deletions(-)

diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index 3b8424e..ab7200b 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -616,11 +616,44 @@ nir_visitor::visit(ir_call *ir)
       switch (op) {
       case nir_intrinsic_atomic_counter_read_var:
       case nir_intrinsic_atomic_counter_inc_var:
-      case nir_intrinsic_atomic_counter_dec_var: {
-         ir_dereference *param =
-            (ir_dereference *) ir->actual_parameters.get_head();
-         instr->variables[0] = evaluate_deref(&instr->instr, param);
-         nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+      case nir_intrinsic_atomic_counter_dec_var:
+      case nir_intrinsic_atomic_counter_add_var:
+      case nir_intrinsic_atomic_counter_min_var:
+      case nir_intrinsic_atomic_counter_max_var:
+      case nir_intrinsic_atomic_counter_and_var:
+      case nir_intrinsic_atomic_counter_or_var:
+      case nir_intrinsic_atomic_counter_xor_var:
+      case nir_intrinsic_atomic_counter_exchange_var:
+      case nir_intrinsic_atomic_counter_comp_swap_var: {
+         nir_ssa_undef_instr *instr_undef =
+            nir_ssa_undef_instr_create(shader, 1, 32);
+         nir_builder_instr_insert(&b, &instr_undef->instr);
+
+         /* Set the counter variable dereference. */
+         exec_node *param = ir->actual_parameters.get_head();
+         ir_dereference *counter = (ir_dereference *)param;
+
+         instr->variables[0] = evaluate_deref(&instr->instr, counter);
+         param = param->get_next();
+
+         /* Set the intrinsic destination. */
+         if (ir->return_deref) {
+            nir_ssa_dest_init(&instr->instr, &instr->dest, 1, 32, NULL);
+         }
+
+         /* Set the intrinsic parameters. */
+         if (!param->is_tail_sentinel()) {
+            instr->src[0] =
+               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
+            param = param->get_next();
+         }
+
+         if (!param->is_tail_sentinel()) {
+            instr->src[1] =
+               nir_src_for_ssa(evaluate_rvalue((ir_dereference *)param));
+            param = param->get_next();
+         }
+
          nir_builder_instr_insert(&b, &instr->instr);
          break;
       }
diff --git a/src/compiler/glsl/nir_intrinsic_map.py b/src/compiler/glsl/nir_intrinsic_map.py
index 07b2d0d..5abc3cb 100644
--- a/src/compiler/glsl/nir_intrinsic_map.py
+++ b/src/compiler/glsl/nir_intrinsic_map.py
@@ -26,6 +26,14 @@ from mako.template import Template
 intrinsics = [("__intrinsic_atomic_read", ("nir_intrinsic_atomic_counter_read_var", None)),
               ("__intrinsic_atomic_increment", ("nir_intrinsic_atomic_counter_inc_var", None)),
               ("__intrinsic_atomic_predecrement", ("nir_intrinsic_atomic_counter_dec_var", None)),
+              ("__intrinsic_atomic_add", ("nir_intrinsic_atomic_counter_add_var", None)),
+              ("__intrinsic_atomic_min", ("nir_intrinsic_atomic_counter_min_var", None)),
+              ("__intrinsic_atomic_max", ("nir_intrinsic_atomic_counter_max_var", None)),
+              ("__intrinsic_atomic_and", ("nir_intrinsic_atomic_counter_and_var", None)),
+              ("__intrinsic_atomic_or", ("nir_intrinsic_atomic_counter_or_var", None)),
+              ("__intrinsic_atomic_xor", ("nir_intrinsic_atomic_counter_xor_var", None)),
+              ("__intrinsic_atomic_exchange", ("nir_intrinsic_atomic_counter_exchange_var", None)),
+              ("__intrinsic_atomic_comp_swap", ("nir_intrinsic_atomic_counter_comp_swap_var", None)),
               ("__intrinsic_image_load", ("nir_intrinsic_image_load", None)),
               ("__intrinsic_image_store", ("nir_intrinsic_image_store", None)),
               ("__intrinsic_image_atomic_add", ("nir_intrinsic_image_atomic_add", None)),
diff --git a/src/compiler/glsl/tests/get_intrinsic_opcode_test.cpp b/src/compiler/glsl/tests/get_intrinsic_opcode_test.cpp
index aeecf32..d270a03 100644
--- a/src/compiler/glsl/tests/get_intrinsic_opcode_test.cpp
+++ b/src/compiler/glsl/tests/get_intrinsic_opcode_test.cpp
@@ -45,6 +45,14 @@ static const struct test_vector {
    test_vector("__intrinsic_atomic_read", nir_intrinsic_atomic_counter_read_var),
    test_vector("__intrinsic_atomic_increment", nir_intrinsic_atomic_counter_inc_var),
    test_vector("__intrinsic_atomic_predecrement", nir_intrinsic_atomic_counter_dec_var),
+   test_vector("__intrinsic_atomic_add", nir_intrinsic_atomic_counter_add),
+   test_vector("__intrinsic_atomic_min", nir_intrinsic_atomic_counter_min),
+   test_vector("__intrinsic_atomic_max", nir_intrinsic_atomic_counter_max),
+   test_vector("__intrinsic_atomic_and", nir_intrinsic_atomic_counter_and),
+   test_vector("__intrinsic_atomic_or", nir_intrinsic_atomic_counter_or),
+   test_vector("__intrinsic_atomic_xor", nir_intrinsic_atomic_counter_xor),
+   test_vector("__intrinsic_atomic_exchange", nir_intrinsic_atomic_counter_exchange),
+   test_vector("__intrinsic_atomic_comp_swap", nir_intrinsic_atomic_counter_comp_swap),
    test_vector("__intrinsic_image_load", nir_intrinsic_image_load),
    test_vector("__intrinsic_image_store", nir_intrinsic_image_store),
    test_vector("__intrinsic_image_atomic_add", nir_intrinsic_image_atomic_add),
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c
index 3c8b4e0..d2ed1f9 100644
--- a/src/compiler/nir/nir.c
+++ b/src/compiler/nir/nir.c
@@ -365,6 +365,7 @@ src_init(nir_src *src)
    src->reg.reg = NULL;
    src->reg.indirect = NULL;
    src->reg.base_offset = 0;
+   list_inithead(&src->use_link);
 }
 
 nir_if *
diff --git a/src/compiler/nir/nir_intrinsics.h b/src/compiler/nir/nir_intrinsics.h
index d73f1cc..44da242 100644
--- a/src/compiler/nir/nir_intrinsics.h
+++ b/src/compiler/nir/nir_intrinsics.h
@@ -139,10 +139,24 @@ INTRINSIC(set_vertex_count, 1, ARR(1), false, 0, 0, 0, xx, xx, xx, 0)
 #define ATOMIC(name, flags) \
    INTRINSIC(name##_var, 0, ARR(0), true, 1, 1, 0, xx, xx, xx, flags) \
    INTRINSIC(name, 1, ARR(1), true, 1, 0, 1, BASE, xx, xx, flags)
+#define ATOMIC2(name) \
+   INTRINSIC(name##_var, 1, ARR(1), true, 1, 1, 0, xx, xx, xx, 0) \
+   INTRINSIC(name, 2, ARR(1, 1), true, 1, 0, 1, BASE, xx, xx, 0)
+#define ATOMIC3(name) \
+   INTRINSIC(name##_var, 2, ARR(1, 1), true, 1, 1, 0, xx, xx, xx, 0) \
+   INTRINSIC(name, 3, ARR(1, 1, 1), true, 1, 0, 1, BASE, xx, xx, 0)
 
 ATOMIC(atomic_counter_inc, 0)
 ATOMIC(atomic_counter_dec, 0)
 ATOMIC(atomic_counter_read, NIR_INTRINSIC_CAN_ELIMINATE)
+ATOMIC2(atomic_counter_add)
+ATOMIC2(atomic_counter_min)
+ATOMIC2(atomic_counter_max)
+ATOMIC2(atomic_counter_and)
+ATOMIC2(atomic_counter_or)
+ATOMIC2(atomic_counter_xor)
+ATOMIC2(atomic_counter_exchange)
+ATOMIC3(atomic_counter_comp_swap)
 
 /*
  * Image load, store and atomic intrinsics.
diff --git a/src/compiler/nir/nir_lower_atomics.c b/src/compiler/nir/nir_lower_atomics.c
index 04e1feb..583e2a5 100644
--- a/src/compiler/nir/nir_lower_atomics.c
+++ b/src/compiler/nir/nir_lower_atomics.c
@@ -54,6 +54,38 @@ lower_instr(nir_intrinsic_instr *instr,
       op = nir_intrinsic_atomic_counter_dec;
       break;
 
+   case nir_intrinsic_atomic_counter_add_var:
+      op = nir_intrinsic_atomic_counter_add;
+      break;
+
+   case nir_intrinsic_atomic_counter_min_var:
+      op = nir_intrinsic_atomic_counter_min;
+      break;
+
+   case nir_intrinsic_atomic_counter_max_var:
+      op = nir_intrinsic_atomic_counter_max;
+      break;
+
+   case nir_intrinsic_atomic_counter_and_var:
+      op = nir_intrinsic_atomic_counter_and;
+      break;
+
+   case nir_intrinsic_atomic_counter_or_var:
+      op = nir_intrinsic_atomic_counter_or;
+      break;
+
+   case nir_intrinsic_atomic_counter_xor_var:
+      op = nir_intrinsic_atomic_counter_xor;
+      break;
+
+   case nir_intrinsic_atomic_counter_exchange_var:
+      op = nir_intrinsic_atomic_counter_exchange;
+      break;
+
+   case nir_intrinsic_atomic_counter_comp_swap_var:
+      op = nir_intrinsic_atomic_counter_comp_swap;
+      break;
+
    default:
       return;
    }
@@ -120,6 +152,12 @@ lower_instr(nir_intrinsic_instr *instr,
    new_instr->src[0].is_ssa = true;
    new_instr->src[0].ssa = offset_def;
 
+   /* Copy the other sources, if any, from the original instruction to the new
+    * instruction.
+    */
+   for (unsigned i = 0; i < nir_intrinsic_infos[instr->intrinsic].num_srcs; i++)
+      new_instr->src[i + 1] = instr->src[i];
+
    if (instr->dest.is_ssa) {
       nir_ssa_dest_init(&new_instr->instr, &new_instr->dest,
                         instr->dest.ssa.num_components, 32, NULL);
-- 
2.5.5



More information about the mesa-dev mailing list