spirv: Implement OpTerminateRayKHR and OpIgnoreIntersectionKHR

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>
This commit is contained in:
Jason Ekstrand 2020-10-29 12:01:22 -05:00 committed by Marge Bot
parent 66685679b7
commit 879b87cf8c
2 changed files with 32 additions and 3 deletions

View file

@ -256,6 +256,8 @@ vtn_cfg_handle_prepass_instruction(struct vtn_builder *b, SpvOp opcode,
case SpvOpSwitch: case SpvOpSwitch:
case SpvOpKill: case SpvOpKill:
case SpvOpTerminateInvocation: case SpvOpTerminateInvocation:
case SpvOpIgnoreIntersectionKHR:
case SpvOpTerminateRayKHR:
case SpvOpReturn: case SpvOpReturn:
case SpvOpReturnValue: case SpvOpReturnValue:
case SpvOpUnreachable: case SpvOpUnreachable:
@ -693,7 +695,17 @@ vtn_process_block(struct vtn_builder *b,
case SpvOpTerminateInvocation: case SpvOpTerminateInvocation:
b->has_early_terminate = true; 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; return NULL;
case SpvOpBranchConditional: { 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); nir_builder_instr_insert(&b->nb, &discard->instr);
break; break;
} }
case vtn_branch_type_terminate: { case vtn_branch_type_terminate_invocation: {
nir_intrinsic_instr *terminate = nir_intrinsic_instr *terminate =
nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_terminate); nir_intrinsic_instr_create(b->nb.shader, nir_intrinsic_terminate);
nir_builder_instr_insert(&b->nb, &terminate->instr); nir_builder_instr_insert(&b->nb, &terminate->instr);
break; 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: default:
vtn_fail("Invalid branch type"); vtn_fail("Invalid branch type");
} }

View file

@ -139,7 +139,9 @@ enum vtn_branch_type {
vtn_branch_type_loop_continue, vtn_branch_type_loop_continue,
vtn_branch_type_loop_back_edge, vtn_branch_type_loop_back_edge,
vtn_branch_type_discard, 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, vtn_branch_type_return,
}; };
@ -709,6 +711,8 @@ struct vtn_builder {
* *
* - OpKill * - OpKill
* - OpTerminateInvocation * - OpTerminateInvocation
* - OpIgnoreIntersectionKHR
* - OpTerminateRayKHR
* *
* However, in NIR, they're represented by regular intrinsics with no * However, in NIR, they're represented by regular intrinsics with no
* control-flow semantics. This means that the SSA form from the SPIR-V * control-flow semantics. This means that the SSA form from the SPIR-V