[Mesa-dev] [PATCH 16/20] nir: Add a ballot32 intrinsic

Matt Turner mattst88 at gmail.com
Thu Jul 6 23:48:26 UTC 2017


Some hardware, like i965, doesn't support group sizes greater than 32.
In that case, we can use the ballot32 intrinsic instead, which will
simplify our code generation.
---
 src/compiler/nir/nir.h                |  2 ++
 src/compiler/nir/nir_intrinsics.h     |  3 +++
 src/compiler/nir/nir_opt_intrinsics.c | 17 +++++++++++++++++
 src/intel/compiler/brw_compiler.c     |  1 +
 4 files changed, 23 insertions(+)

diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 3591048574..a3d8df0b19 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1844,6 +1844,8 @@ typedef struct nir_shader_compiler_options {
     */
    bool use_interpolated_input_intrinsics;
 
+   unsigned max_subgroup_size;
+
    unsigned max_unroll_iterations;
 } nir_shader_compiler_options;
 
diff --git a/src/compiler/nir/nir_intrinsics.h b/src/compiler/nir/nir_intrinsics.h
index 96ecfbc338..61ad9f6643 100644
--- a/src/compiler/nir/nir_intrinsics.h
+++ b/src/compiler/nir/nir_intrinsics.h
@@ -106,6 +106,9 @@ INTRINSIC(ballot, 1, ARR(1), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMIN
 INTRINSIC(read_invocation, 2, ARR(0, 1), true, 0, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE)
 INTRINSIC(read_first_invocation, 1, ARR(0), true, 0, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE)
 
+/* Equivalent to ballot, but only returns the low 32-bits */
+INTRINSIC(ballot32, 1, ARR(1), true, 1, 0, 0, xx, xx, xx, NIR_INTRINSIC_CAN_ELIMINATE)
+
 /*
  * Memory barrier with semantics analogous to the compute shader
  * groupMemoryBarrier(), memoryBarrierAtomicCounter(), memoryBarrierBuffer(),
diff --git a/src/compiler/nir/nir_opt_intrinsics.c b/src/compiler/nir/nir_opt_intrinsics.c
index 0cd75d8b28..023e169a99 100644
--- a/src/compiler/nir/nir_opt_intrinsics.c
+++ b/src/compiler/nir/nir_opt_intrinsics.c
@@ -69,6 +69,23 @@ opt_intrinsics_impl(nir_function_impl *impl)
             replacement = nir_imm_int(&b, NIR_TRUE);
             break;
          }
+         case nir_intrinsic_ballot: {
+            assert(b.shader->options->max_subgroup_size != 0);
+            if (b.shader->options->max_subgroup_size > 32)
+               continue;
+
+            nir_intrinsic_instr *ballot =
+               nir_intrinsic_instr_create(b.shader, nir_intrinsic_ballot32);
+            nir_ssa_dest_init(&ballot->instr, &ballot->dest, 1, 32, NULL);
+            ballot->src[0] = intrin->src[0];
+
+            nir_builder_instr_insert(&b, &ballot->instr);
+
+            replacement = nir_pack_64_2x32_split(&b,
+                                                 &ballot->dest.ssa,
+                                                 nir_imm_int(&b, 0));
+            break;
+         }
          default:
             break;
          }
diff --git a/src/intel/compiler/brw_compiler.c b/src/intel/compiler/brw_compiler.c
index 9ad5d8e4ee..6970bcb40f 100644
--- a/src/intel/compiler/brw_compiler.c
+++ b/src/intel/compiler/brw_compiler.c
@@ -57,6 +57,7 @@ static const struct nir_shader_compiler_options scalar_nir_options = {
    .lower_unpack_snorm_4x8 = true,
    .lower_unpack_unorm_2x16 = true,
    .lower_unpack_unorm_4x8 = true,
+   .max_subgroup_size = 64, /* FIXME */
    .max_unroll_iterations = 32,
 };
 
-- 
2.13.0



More information about the mesa-dev mailing list