1 // Copyright (c) 2016 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9 
10 //! Synchronization on the GPU.
11 //!
12 //! Just like for CPU code, you have to ensure that buffers and images are not accessed mutably by
13 //! multiple GPU queues simultaneously and that they are not accessed mutably by the CPU and by the
14 //! GPU simultaneously.
15 //!
16 //! This safety is enforced at runtime by vulkano but it is not magic and you will require some
17 //! knowledge if you want to avoid errors.
18 
19 pub(crate) use self::pipeline::{PipelineStageAccess, PipelineStageAccessSet};
20 pub use self::{
21     future::{now, FlushError, GpuFuture},
22     pipeline::{
23         AccessFlags, BufferMemoryBarrier, DependencyFlags, DependencyInfo, ImageMemoryBarrier,
24         MemoryBarrier, PipelineMemoryAccess, PipelineStage, PipelineStages,
25         QueueFamilyOwnershipTransfer,
26     },
27 };
28 use crate::device::Queue;
29 use std::sync::Arc;
30 
31 pub mod event;
32 pub mod fence;
33 pub mod future;
34 mod pipeline;
35 pub mod semaphore;
36 
37 /// Declares in which queue(s) a resource can be used.
38 ///
39 /// When you create a buffer or an image, you have to tell the Vulkan library in which queue
40 /// families it will be used. The vulkano library requires you to tell in which queue family
41 /// the resource will be used, even for exclusive mode.
42 #[derive(Debug, Clone, PartialEq, Eq)]
43 // TODO: remove
44 pub enum SharingMode {
45     /// The resource is used is only one queue family.
46     Exclusive,
47     /// The resource is used in multiple queue families. Can be slower than `Exclusive`.
48     Concurrent(Vec<u32>), // TODO: Vec is too expensive here
49 }
50 
51 impl<'a> From<&'a Arc<Queue>> for SharingMode {
52     #[inline]
from(_queue: &'a Arc<Queue>) -> SharingMode53     fn from(_queue: &'a Arc<Queue>) -> SharingMode {
54         SharingMode::Exclusive
55     }
56 }
57 
58 impl<'a> From<&'a [&'a Arc<Queue>]> for SharingMode {
59     #[inline]
from(queues: &'a [&'a Arc<Queue>]) -> SharingMode60     fn from(queues: &'a [&'a Arc<Queue>]) -> SharingMode {
61         SharingMode::Concurrent(
62             queues
63                 .iter()
64                 .map(|queue| queue.queue_family_index())
65                 .collect(),
66         )
67     }
68 }
69 
70 /// Declares in which queue(s) a resource can be used.
71 #[derive(Debug, Clone, PartialEq, Eq)]
72 pub enum Sharing<I>
73 where
74     I: IntoIterator<Item = u32>,
75 {
76     /// The resource is used is only one queue family.
77     Exclusive,
78     /// The resource is used in multiple queue families. Can be slower than `Exclusive`.
79     Concurrent(I),
80 }
81 
82 /// How the memory of a resource is currently being accessed.
83 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
84 pub(crate) enum CurrentAccess {
85     /// The resource is currently being accessed exclusively by the CPU.
86     CpuExclusive,
87 
88     /// The resource is currently being accessed exclusively by the GPU.
89     /// The GPU can have multiple exclusive accesses, if they are separated by synchronization.
90     ///
91     /// `gpu_writes` must not be 0. If it's decremented to 0, switch to `Shared`.
92     GpuExclusive { gpu_reads: usize, gpu_writes: usize },
93 
94     /// The resource is not currently being accessed, or is being accessed for reading only.
95     Shared { cpu_reads: usize, gpu_reads: usize },
96 }
97