spirv: Implement OpTerminateRayKHR and OpIgnoreIntersectionKHR
authorJason Ekstrand <jason@jlekstrand.net>
Thu, 29 Oct 2020 17:01:22 +0000 (12:01 -0500)
committerMarge Bot <eric+marge@anholt.net>
Tue, 24 Nov 2020 15:47:06 +0000 (15:47 +0000)
In the final version of SPV_KHR_ray_tracing, these are now block
terminators like OpKill or OpReturn.  This means that they need special
handling in vtn_cfg.c.

Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7734>

src/compiler/spirv/vtn_cfg.c
src/compiler/spirv/vtn_private.h

index 4d68f8f..445e3e5 100644 (file)
@@ -256,6 +256,8 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
    case SpvOpSwitch:
    case SpvOpKill:
    case SpvOpTerminateInvocation:
+   case SpvOpIgnoreIntersectionKHR:
+   case SpvOpTerminateRayKHR:
    case SpvOpReturn:
    case SpvOpReturnValue:
    case SpvOpUnreachable:
@@ -693,7 +695,17 @@ vtn_process_block(struct vtn_builder *b,
 
    case SpvOpTerminateInvocation:
       b->has_early_terminate = true;
-      block->branch_type = vtn_branch_type_terminate;
+      block->branch_type = vtn_branch_type_terminate_invocation;
+      return NULL;
+
+   case SpvOpIgnoreIntersectionKHR:
+      b->has_early_terminate = true;
+      block->branch_type = vtn_branch_type_ignore_intersection;
+      return NULL;
+
+   case SpvOpTerminateRayKHR:
+      b->has_early_terminate = true;
+      block->branch_type = vtn_branch_type_terminate_ray;
       return NULL;
 
    case SpvOpBranchConditional: {
@@ -957,12 +969,25 @@ vtn_emit_branch(struct vtn_builder *b, enum vtn_branch_type branch_type,
       nir_builder_instr_insert(&b->nb, &discard->instr);
       break;
    }
-   case vtn_branch_type_terminate: {
+   case vtn_branch_type_terminate_invocation: {
       nir_intrinsic_instr *terminate =
          nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_terminate);
       nir_builder_instr_insert(&b->nb, &terminate->instr);
       break;
    }
+   case vtn_branch_type_ignore_intersection: {
+      nir_intrinsic_instr *ignore =
+         nir_intrinsic_instr_create(b->nb.shader,
+                                    nir_intrinsic_ignore_ray_intersection);
+      nir_builder_instr_insert(&b->nb, &ignore->instr);
+      break;
+   }
+   case vtn_branch_type_terminate_ray: {
+      nir_intrinsic_instr *terminate =
+         nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_terminate_ray);
+      nir_builder_instr_insert(&b->nb, &terminate->instr);
+      break;
+   }
    default:
       vtn_fail("Invalid branch type");
    }
index 3d32db8..7275fff 100644 (file)
@@ -139,7 +139,9 @@ enum vtn_branch_type {
    vtn_branch_type_loop_continue,
    vtn_branch_type_loop_back_edge,
    vtn_branch_type_discard,
-   vtn_branch_type_terminate,
+   vtn_branch_type_terminate_invocation,
+   vtn_branch_type_ignore_intersection,
+   vtn_branch_type_terminate_ray,
    vtn_branch_type_return,
 };
 
@@ -709,6 +711,8 @@ struct vtn_builder {
     *
     *  - OpKill
     *  - OpTerminateInvocation
+    *  - OpIgnoreIntersectionKHR
+    *  - OpTerminateRayKHR
     *
     * However, in NIR, they're represented by regular intrinsics with no
     * control-flow semantics.  This means that the SSA form from the SPIR-V