spirv_std/arch/
derivative.rs

1use crate::float::Float;
2
3#[cfg(target_arch = "spirv")]
4macro_rules! deriv_fn {
5    ($p:ident, $inst:ident) => {
6        unsafe {
7            let mut o = Default::default();
8            ::core::arch::asm!(
9                "%input = OpLoad _ {0}",
10                concat!("%result = ", stringify!($inst), " _ %input"),
11                "OpStore {1} %result",
12                in(reg) &$p,
13                in(reg) &mut o,
14            );
15            o
16        }
17    };
18}
19
20/// Returns the partial derivative of `component` with respect to the window's X
21/// coordinate. Returns the same result as either [`ddx_fine`] or
22/// [`ddx_coarse`], selection of which one is dependent on external factors.
23#[crate::macros::vectorized]
24#[crate::macros::gpu_only]
25pub fn ddx<F: Float>(component: F) -> F {
26    deriv_fn!(component, OpDPdx)
27}
28
29/// Returns the partial derivative of `component` with respect to the window's X
30/// coordinate. Uses local differencing based on the value of `component` for
31/// the current fragment and its immediate neighbor(s).
32#[crate::macros::vectorized]
33#[crate::macros::gpu_only]
34pub fn ddx_fine<F: Float>(component: F) -> F {
35    deriv_fn!(component, OpDPdxFine)
36}
37
38/// Returns the partial derivative of `component` with respect to the window's X
39/// coordinate. Uses local differencing based on the value of `component` for
40/// the current fragment’s neighbors, and possibly, but not necessarily,
41/// includes the value of `component` for the current fragment. That is, over a
42/// given area, the implementation can compute X derivatives in fewer unique
43/// locations than would be allowed by [`ddx_fine`].
44#[crate::macros::vectorized]
45#[crate::macros::gpu_only]
46pub fn ddx_coarse<F: Float>(component: F) -> F {
47    deriv_fn!(component, OpDPdxCoarse)
48}
49
50/// Returns the partial derivative of `component` with respect to the window's Y
51/// coordinate. Returns the same result as either [`ddy_fine`] or
52/// [`ddy_coarse`], selection of which one is dependent on external factors.
53#[crate::macros::vectorized]
54#[crate::macros::gpu_only]
55pub fn ddy<F: Float>(component: F) -> F {
56    deriv_fn!(component, OpDPdy)
57}
58
59/// Returns the partial derivative of `component` with respect to the window's Y
60/// coordinate. Uses local differencing based on the value of `component` for
61/// the current fragment and its immediate neighbor(s).
62#[crate::macros::vectorized]
63#[crate::macros::gpu_only]
64pub fn ddy_fine<F: Float>(component: F) -> F {
65    deriv_fn!(component, OpDPdyFine)
66}
67
68/// Returns the partial derivative of `component` with respect to the window's Y
69/// coordinate. Uses local differencing based on the value of `component` for
70/// the current fragment’s neighbors, and possibly, but not necessarily,
71/// includes the value of `component` for the current fragment. That is, over a
72/// given area, the implementation can compute Y derivatives in fewer unique
73/// locations than would be allowed by [`ddy_fine`].
74#[crate::macros::vectorized]
75#[crate::macros::gpu_only]
76pub fn ddy_coarse<F: Float>(component: F) -> F {
77    deriv_fn!(component, OpDPdyCoarse)
78}
79
80/// Returns the sum of the absolute values of [`ddx`] and [`ddy`] as a single
81/// operation.
82#[crate::macros::vectorized]
83#[crate::macros::gpu_only]
84pub fn fwidth<F: Float>(component: F) -> F {
85    deriv_fn!(component, OpFwidth)
86}
87
88/// Returns the sum of the absolute values of [`ddx_fine`] and [`ddy_fine`] as a
89/// single operation.
90#[crate::macros::vectorized]
91#[crate::macros::gpu_only]
92pub fn fwidth_fine<F: Float>(component: F) -> F {
93    deriv_fn!(component, OpFwidthFine)
94}
95
96/// Returns the sum of the absolute values of [`ddx_coarse`] and [`ddy_coarse`]
97/// as a single operation.
98#[crate::macros::vectorized]
99#[crate::macros::gpu_only]
100pub fn fwidth_coarse<F: Float>(component: F) -> F {
101    deriv_fn!(component, OpFwidthCoarse)
102}