1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#[cfg(target_arch = "spirv")]
use core::arch::asm;

/// Reports an intersection back to the traversal infrastructure.
///
/// If the intersection occurred within the current ray interval, the
/// intersection confirmation is performed (see the API specification for more
/// details). If the value of Hit falls outside the current ray interval, the
/// hit is rejected.
///
/// Returns True if the hit was accepted by the ray interval and the intersection was confirmed. Returns False otherwise.
///
/// - `hit` is the floating point parametric value along ray for the intersection.
/// - `hit_kind` is the integer hit kind reported back to other shaders and
///   accessible by the `hit kind` builtin.
///
/// This instruction is allowed only in IntersectionKHR execution model.
///
/// This instruction is a shader call instruction which may invoke shaders with
/// the `any_hit` execution model.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpReportIntersectionKHR")]
#[inline]
pub unsafe fn report_intersection(hit: f32, hit_kind: u32) -> bool {
    let mut result = false;

    asm! {
        "%bool = OpTypeBool",
        "%result = OpReportIntersectionKHR %bool {hit} {hit_kind}",
        "OpStore {result} %result",
        result = in(reg) &mut result,
        hit = in(reg) hit,
        hit_kind = in(reg) hit_kind,
    };

    result
}

/// Ignores the current potential intersection, terminating the invocation that
/// executes it, and continues the ray traversal.  This instruction is allowed
/// only in `any_hit` execution model.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpIgnoreIntersectionKHR")]
#[inline]
pub unsafe fn ignore_intersection() -> ! {
    asm!("OpIgnoreIntersectionKHR", options(noreturn));
}

/// Terminates the invocation that executes it, stops the ray traversal, accepts
/// the current hit, and invokes the `closest_hit` execution model
/// (if active). This instruction is allowed only in the `any_hit`
/// execution model.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpTerminateRayKHR")]
#[inline]
pub unsafe fn terminate_ray() -> ! {
    asm!("OpTerminateRayKHR", options(noreturn));
}

/// Invoke a callable shader.
///
/// - `INDEX` is the index into the SBT table to select callable shader
///   to execute.
/// - `data` is a pointer to the callable data to pass into the called shader.
///   `data` must have a storage class of `callable_data`
///   or `incoming_callable_data`.
///
/// This instruction is allowed only in `ray_generation`, `closest_hit`,
/// `miss` and `callable` execution models.
///
/// This instruction is a shader call instruction which will invoke a shader
/// with the `callable` execution model.
#[spirv_std_macros::gpu_only]
#[doc(alias = "OpExecuteCallableKHR")]
#[inline]
pub unsafe fn execute_callable<T, const ID: usize>(data: &T) {
    asm! {
        "%u32 = OpTypeInt 32 0",
        "%id = OpConstant %u32 {id}",
        "OpExecuteCallableKHR %id {data}",
        id = const ID,
        data = in(reg) data,
    };
}