i965/fs: Implement ARB_shader_ballot operations
authorMatt Turner <mattst88@gmail.com>
Thu, 22 Jun 2017 23:46:39 +0000 (16:46 -0700)
committerMatt Turner <mattst88@gmail.com>
Thu, 20 Jul 2017 23:56:49 +0000 (16:56 -0700)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/intel/compiler/brw_compiler.c
src/intel/compiler/brw_fs_nir.cpp
src/intel/compiler/brw_nir.c

index 397c8cccf908e971ccd5778e5901de9a2619d6aa..39a8237ff07162f75ab91bd67c3e07876dc7ec29 100644 (file)
@@ -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,
+   .lower_subgroup_masks = true,
    .max_unroll_iterations = 32,
 };
 
index 491f5184e3922c513ddc749ada9fe20b5ead0c37..74f90dabeac3995f059cf75218cee6f5344a7bf8 100644 (file)
@@ -4103,6 +4103,10 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
       break;
    }
 
+   case nir_intrinsic_load_subgroup_size:
+      bld.MOV(retype(dest, BRW_REGISTER_TYPE_D), brw_imm_d(dispatch_width));
+      break;
+
    case nir_intrinsic_load_subgroup_invocation: {
       fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_UW);
       dest = retype(dest, BRW_REGISTER_TYPE_UD);
@@ -4118,6 +4122,13 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
       break;
    }
 
+   case nir_intrinsic_load_subgroup_eq_mask:
+   case nir_intrinsic_load_subgroup_ge_mask:
+   case nir_intrinsic_load_subgroup_gt_mask:
+   case nir_intrinsic_load_subgroup_le_mask:
+   case nir_intrinsic_load_subgroup_lt_mask:
+      unreachable("not reached");
+
    case nir_intrinsic_vote_any: {
       const fs_builder ubld = bld.exec_all();
 
@@ -4168,6 +4179,41 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr
                     bld.SEL(dest, dest, brw_imm_d(0)));
       break;
    }
+
+   case nir_intrinsic_ballot: {
+      const fs_reg value = retype(get_nir_src(instr->src[0]),
+                                  BRW_REGISTER_TYPE_UD);
+      const struct brw_reg flag = retype(brw_flag_reg(0, 0),
+                                         BRW_REGISTER_TYPE_UD);
+
+      bld.exec_all().MOV(flag, brw_imm_ud(0u));
+      bld.CMP(bld.null_reg_ud(), value, brw_imm_ud(0u), BRW_CONDITIONAL_NZ);
+
+      dest.type = BRW_REGISTER_TYPE_UQ;
+      bld.MOV(dest, flag);
+      break;
+   }
+
+   case nir_intrinsic_read_invocation: {
+      const fs_reg value = get_nir_src(instr->src[0]);
+      const fs_reg invocation = get_nir_src(instr->src[1]);
+      fs_reg tmp = bld.vgrf(value.type);
+
+      bld.exec_all().emit(SHADER_OPCODE_BROADCAST, tmp, value,
+                          component(invocation, 0));
+
+      bld.MOV(retype(dest, BRW_REGISTER_TYPE_D),
+              fs_reg(component(tmp, 0)));
+      break;
+   }
+
+   case nir_intrinsic_read_first_invocation: {
+      const fs_reg value = get_nir_src(instr->src[0]);
+      bld.MOV(retype(dest, BRW_REGISTER_TYPE_D),
+              bld.emit_uniformize(value));
+      break;
+   }
+
    default:
       unreachable("unknown intrinsic");
    }
index cede77fbc8854627003fc2021367b3a2020d997c..ce21c016699bac11d7d663506160fc22a593ff1e 100644 (file)
@@ -620,6 +620,7 @@ brw_preprocess_nir(const struct brw_compiler *compiler, nir_shader *nir)
 
    OPT(nir_lower_tex, &tex_options);
    OPT(nir_normalize_cubemap_coords);
+   OPT(nir_lower_read_invocation_to_scalar);
 
    OPT(nir_lower_global_vars_to_local);