spirv: Implement SPV_EXT_demote_to_helper_invocation
authorCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Sat, 8 Jun 2019 06:08:04 +0000 (23:08 -0700)
committerCaio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Mon, 8 Jul 2019 15:57:25 +0000 (08:57 -0700)
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
src/compiler/shader_info.h
src/compiler/spirv/spirv_to_nir.c

index 46588c327f9e90a9626ff02a03b8d8349e509b8b..f71b93e84d0b7c67d4df8e67b5eed5a2e5b87360 100644 (file)
@@ -35,6 +35,7 @@ extern "C" {
 struct spirv_supported_capabilities {
    bool address;
    bool atomic_storage;
+   bool demote_to_helper_invocation;
    bool derivative_group;
    bool descriptor_array_dynamic_indexing;
    bool descriptor_array_non_uniform_indexing;
index b9eb69c724721850669c1a5ff456de2f13fc3a51..3e88e54ab84273d4af6643d336c62b7accd848f7 100644 (file)
@@ -3718,6 +3718,10 @@ vtn_handle_preamble_instruction(struct vtn_builder *b, SpvOp opcode,
          spv_check_supported(fragment_shader_pixel_interlock, cap);
          break;
 
+      case SpvCapabilityDemoteToHelperInvocationEXT:
+         spv_check_supported(demote_to_helper_invocation, cap);
+         break;
+
       default:
          vtn_fail("Unhandled capability: %s (%u)",
                   spirv_capability_to_string(cap), cap);
@@ -4532,6 +4536,28 @@ vtn_handle_body_instruction(struct vtn_builder *b, SpvOp opcode,
       vtn_emit_barrier(b, nir_intrinsic_end_invocation_interlock);
       break;
 
+   case SpvOpDemoteToHelperInvocationEXT: {
+      nir_intrinsic_instr *intrin =
+         nir_intrinsic_instr_create(b->shader, nir_intrinsic_demote);
+      nir_builder_instr_insert(&b->nb, &intrin->instr);
+      break;
+   }
+
+   case SpvOpIsHelperInvocationEXT: {
+      nir_intrinsic_instr *intrin =
+         nir_intrinsic_instr_create(b->shader, nir_intrinsic_is_helper_invocation);
+      nir_ssa_dest_init(&intrin->instr, &intrin->dest, 1, 1, NULL);
+      nir_builder_instr_insert(&b->nb, &intrin->instr);
+
+      struct vtn_type *res_type =
+         vtn_value(b, w[1], vtn_value_type_type)->type;
+      struct vtn_ssa_value *val = vtn_create_ssa_value(b, res_type->type);
+      val->def = &intrin->dest.ssa;
+
+      vtn_push_ssa(b, w[2], res_type, val);
+      break;
+   }
+
    default:
       vtn_fail_with_opcode("Unhandled opcode", opcode);
    }