Skip to main content

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