1 //! Memory buffers.
2 //!
3 //! Buffers interpret memory slices as linear contiguous data array.
4 //!
5 //! They can be used as shader resources, vertex buffers, index buffers or for
6 //! specifying the action commands for indirect execution.
7 
8 use crate::{device::OutOfMemory, format::Format};
9 
10 /// An offset inside a buffer, in bytes.
11 pub type Offset = u64;
12 
13 /// An stride between elements inside a buffer, in bytes.
14 pub type Stride = u32;
15 
16 /// A subrange of the buffer.
17 #[derive(Clone, Debug, Default, Hash, PartialEq, Eq)]
18 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19 pub struct SubRange {
20     /// Offset to the subrange.
21     pub offset: Offset,
22     /// Size of the subrange, or None for the remaining size of the buffer.
23     pub size: Option<Offset>,
24 }
25 
26 impl SubRange {
27     /// Whole buffer subrange.
28     pub const WHOLE: Self = SubRange {
29         offset: 0,
30         size: None,
31     };
32 
33     /// Return the stored size, if present, or computed size based on the limit.
size_to(&self, limit: Offset) -> Offset34     pub fn size_to(&self, limit: Offset) -> Offset {
35         self.size.unwrap_or(limit - self.offset)
36     }
37 }
38 
39 /// Buffer state.
40 pub type State = Access;
41 
42 /// Error creating a buffer.
43 #[derive(Clone, Debug, PartialEq, thiserror::Error)]
44 pub enum CreationError {
45     /// Out of either host or device memory.
46     #[error(transparent)]
47     OutOfMemory(#[from] OutOfMemory),
48     /// Requested buffer usage is not supported.
49     ///
50     /// Older GL version don't support constant buffers or multiple usage flags.
51     #[error("Unsupported usage: {0:?}")]
52     UnsupportedUsage(Usage),
53 }
54 
55 /// Error creating a buffer view.
56 #[derive(Clone, Debug, PartialEq, thiserror::Error)]
57 pub enum ViewCreationError {
58     /// Out of either host or device memory.
59     #[error(transparent)]
60     OutOfMemory(#[from] OutOfMemory),
61     /// Buffer view format is not supported.
62     #[error("Unsupported format: {0:?}")]
63     UnsupportedFormat(Option<Format>),
64 }
65 
66 bitflags!(
67     /// Buffer usage flags.
68     #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69     pub struct Usage: u32 {
70         ///
71         const TRANSFER_SRC  = 0x1;
72         ///
73         const TRANSFER_DST = 0x2;
74         ///
75         const UNIFORM_TEXEL = 0x4;
76         ///
77         const STORAGE_TEXEL = 0x8;
78         ///
79         const UNIFORM = 0x10;
80         ///
81         const STORAGE = 0x20;
82         ///
83         const INDEX = 0x40;
84         ///
85         const VERTEX = 0x80;
86         ///
87         const INDIRECT = 0x100;
88     }
89 );
90 
91 bitflags!(
92     /// Buffer create flags.
93     #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
94     pub struct CreateFlags: u32 {
95         /// Specifies the view will be backed using sparse memory binding.
96         const SPARSE_BINDING = 0x0000_0001;
97         /// Specifies the view can be partially backed with sparse memory binding.
98         /// Must have `SPARSE_BINDING` enabled.
99         const SPARSE_RESIDENCY = 0x0000_0002;
100         /// Specifies the view will be backed using sparse memory binding with memory bindings that
101         /// might alias other data. Must have `SPARSE_BINDING` enabled.
102         const SPARSE_ALIASED = 0x0000_0004;
103     }
104 );
105 
106 impl Usage {
107     /// Returns if the buffer can be used in transfer operations.
can_transfer(&self) -> bool108     pub fn can_transfer(&self) -> bool {
109         self.intersects(Usage::TRANSFER_SRC | Usage::TRANSFER_DST)
110     }
111 }
112 
113 bitflags!(
114     /// Buffer access flags.
115     ///
116     /// Access of buffers by the pipeline or shaders.
117     #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
118     pub struct Access: u32 {
119         /// Read commands instruction for indirect execution.
120         const INDIRECT_COMMAND_READ = 0x1;
121         /// Read index values for indexed draw commands.
122         ///
123         /// See [`draw_indexed`](../command/trait.RawCommandBuffer.html#tymethod.draw_indexed)
124         /// and [`draw_indexed_indirect`](../command/trait.RawCommandBuffer.html#tymethod.draw_indexed_indirect).
125         const INDEX_BUFFER_READ = 0x2;
126         /// Read vertices from vertex buffer for draw commands in the [`VERTEX_INPUT`](
127         /// ../pso/struct.PipelineStage.html#associatedconstant.VERTEX_INPUT) stage.
128         const VERTEX_BUFFER_READ = 0x4;
129         ///
130         const UNIFORM_READ = 0x8;
131         ///
132         const SHADER_READ = 0x20;
133         ///
134         const SHADER_WRITE = 0x40;
135         ///
136         const TRANSFER_READ = 0x800;
137         ///
138         const TRANSFER_WRITE = 0x1000;
139         ///
140         const HOST_READ = 0x2000;
141         ///
142         const HOST_WRITE = 0x4000;
143         ///
144         const MEMORY_READ = 0x8000;
145         ///
146         const MEMORY_WRITE = 0x10000;
147     }
148 );
149