nir: Add new SPIR-V ballot intrinsics and lowering
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 9 May 2017 23:44:13 +0000 (16:44 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 7 Mar 2018 20:13:47 +0000 (12:13 -0800)
Someone can make the lowering optional later if they want something
different for their hardware.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
src/compiler/nir/nir_intrinsics.h
src/compiler/nir/nir_lower_subgroups.c

index 1a816b46792a862ed7760b2d22c18080c8e6e87e..46f67a908ed0cfe91e6e5aab1e054bf84d296408 100644 (file)
@@ -106,6 +106,18 @@ INTRINSIC(ballot, 1, ARR(1), true, 0, 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)
 
+/** Additional SPIR-V ballot intrinsics
+ *
+ * These correspond to the SPIR-V opcodes
+ *
+ *    OpGroupUniformElect
+ *    OpSubgroupFirstInvocationKHR
+ */
+INTRINSIC(elect, 0, ARR(0), true, 1, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE)
+INTRINSIC(first_invocation, 0, ARR(0), true, 1, 0, 0, xx, xx, xx,
+          NIR_INTRINSIC_CAN_ELIMINATE)
+
 /*
  * Memory barrier with semantics analogous to the compute shader
  * groupMemoryBarrier(), memoryBarrierAtomicCounter(), memoryBarrierBuffer(),
index acc6ed9a36ecdca6610b7fbf29ee2ab2979ab197..e45a7d723ac6a1d679e1637b0c715b777f802f78 100644 (file)
@@ -244,6 +244,16 @@ lower_subgroups_intrin(nir_builder *b, nir_intrinsic_instr *intrin,
       return nir_bit_count(b, nir_iand(b, int_val, mask));
    }
 
+   case nir_intrinsic_elect: {
+      nir_intrinsic_instr *first =
+         nir_intrinsic_instr_create(b->shader,
+                                    nir_intrinsic_first_invocation);
+      nir_ssa_dest_init(&first->instr, &first->dest, 1, 32, NULL);
+      nir_builder_instr_insert(b, &first->instr);
+
+      return nir_ieq(b, nir_load_subgroup_invocation(b), &first->dest.ssa);
+   }
+
    default:
       break;
    }