renderling/
sync.rs

1//! GPU locks and atomics.
2
3use crabslab::Id;
4
5/// Perform an [atomic_i_increment](spirv_std::arch::atomic_i_increment) operation.
6///
7/// ## Note
8/// This is **not** atomic on CPU.
9pub fn atomic_i_increment<const SCOPE: u32, const SEMANTICS: u32>(
10    slab: &mut [u32],
11    id: Id<u32>,
12) -> u32 {
13    #[cfg(gpu)]
14    {
15        let ptr = &mut slab[id.index()];
16        unsafe { spirv_std::arch::atomic_i_increment::<u32, SCOPE, SEMANTICS>(ptr) }
17    }
18    #[cfg(cpu)]
19    {
20        let prev = slab[id.index()];
21        slab[id.index()] = prev + 1;
22        prev
23    }
24}
25
26/// Perform an [atomic_u_min](spirv_std::arch::atomic_u_min) operation.
27///
28/// ## Note
29/// This is **not** atomic on CPU.
30pub fn atomic_u_min<const SCOPE: u32, const SEMANTICS: u32>(
31    slab: &mut [u32],
32    id: Id<u32>,
33    val: u32,
34) -> u32 {
35    #[cfg(gpu)]
36    {
37        let ptr = &mut slab[id.index()];
38        unsafe { spirv_std::arch::atomic_u_min::<u32, SCOPE, SEMANTICS>(ptr, val) }
39    }
40    #[cfg(cpu)]
41    {
42        let prev = slab[id.index()];
43        let new = prev.min(val);
44        slab[id.index()] = new;
45        prev
46    }
47}
48
49/// Perform an [atomic_u_max](spirv_std::arch::atomic_u_max) operation.
50///
51/// ## Note
52/// This is **not** atomic on CPU.
53pub fn atomic_u_max<const SCOPE: u32, const SEMANTICS: u32>(
54    slab: &mut [u32],
55    id: Id<u32>,
56    val: u32,
57) -> u32 {
58    #[cfg(gpu)]
59    {
60        let ptr = &mut slab[id.index()];
61        unsafe { spirv_std::arch::atomic_u_max::<u32, SCOPE, SEMANTICS>(ptr, val) }
62    }
63    #[cfg(cpu)]
64    {
65        let prev = slab[id.index()];
66        let new = prev.max(val);
67        slab[id.index()] = new;
68        prev
69    }
70}