Skip to main content

mtl_gpu/enums/
command.rs

1//! Command buffer enumerations.
2//!
3//! Corresponds to `Metal/MTLCommandBuffer.hpp`.
4
5use mtl_foundation::{Integer, UInteger};
6
7/// Command buffer status.
8///
9/// C++ equivalent: `MTL::CommandBufferStatus`
10#[repr(transparent)]
11#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
12pub struct CommandBufferStatus(pub UInteger);
13
14impl CommandBufferStatus {
15    pub const NOT_ENQUEUED: Self = Self(0);
16    pub const ENQUEUED: Self = Self(1);
17    pub const COMMITTED: Self = Self(2);
18    pub const SCHEDULED: Self = Self(3);
19    pub const COMPLETED: Self = Self(4);
20    pub const ERROR: Self = Self(5);
21}
22
23/// Command buffer error codes.
24///
25/// C++ equivalent: `MTL::CommandBufferError`
26#[repr(transparent)]
27#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
28pub struct CommandBufferError(pub UInteger);
29
30impl CommandBufferError {
31    pub const NONE: Self = Self(0);
32    pub const INTERNAL: Self = Self(1);
33    pub const TIMEOUT: Self = Self(2);
34    pub const PAGE_FAULT: Self = Self(3);
35    pub const BLACKLISTED: Self = Self(4);
36    pub const ACCESS_REVOKED: Self = Self(4);
37    pub const NOT_PERMITTED: Self = Self(7);
38    pub const OUT_OF_MEMORY: Self = Self(8);
39    pub const INVALID_RESOURCE: Self = Self(9);
40    pub const MEMORYLESS: Self = Self(10);
41    pub const DEVICE_REMOVED: Self = Self(11);
42    pub const STACK_OVERFLOW: Self = Self(12);
43}
44
45/// Command encoder error state.
46///
47/// C++ equivalent: `MTL::CommandEncoderErrorState`
48#[repr(transparent)]
49#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
50pub struct CommandEncoderErrorState(pub Integer);
51
52impl CommandEncoderErrorState {
53    pub const UNKNOWN: Self = Self(0);
54    pub const COMPLETED: Self = Self(1);
55    pub const AFFECTED: Self = Self(2);
56    pub const PENDING: Self = Self(3);
57    pub const FAULTED: Self = Self(4);
58}
59
60/// Dispatch type for compute commands.
61///
62/// C++ equivalent: `MTL::DispatchType`
63#[repr(transparent)]
64#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
65pub struct DispatchType(pub UInteger);
66
67impl DispatchType {
68    pub const SERIAL: Self = Self(0);
69    pub const CONCURRENT: Self = Self(1);
70}
71
72/// Command buffer error options (bitflags).
73///
74/// C++ equivalent: `MTL::CommandBufferErrorOption`
75#[repr(transparent)]
76#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
77pub struct CommandBufferErrorOption(pub UInteger);
78
79impl CommandBufferErrorOption {
80    pub const NONE: Self = Self(0);
81    pub const ENCODER_EXECUTION_STATUS: Self = Self(1);
82
83    /// Returns the raw bits.
84    #[inline]
85    pub const fn bits(&self) -> UInteger {
86        self.0
87    }
88
89    /// Creates from raw bits.
90    #[inline]
91    pub const fn from_bits(bits: UInteger) -> Self {
92        Self(bits)
93    }
94}
95
96impl std::ops::BitOr for CommandBufferErrorOption {
97    type Output = Self;
98    #[inline]
99    fn bitor(self, rhs: Self) -> Self {
100        Self(self.0 | rhs.0)
101    }
102}
103
104/// Resource usage for command encoders (bitflags).
105///
106/// C++ equivalent: `MTL::ResourceUsage`
107#[repr(transparent)]
108#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
109pub struct ResourceUsage(pub UInteger);
110
111impl ResourceUsage {
112    pub const READ: Self = Self(1);
113    pub const WRITE: Self = Self(1 << 1);
114    pub const SAMPLE: Self = Self(1 << 2);
115
116    /// Returns the raw bits.
117    #[inline]
118    pub const fn bits(&self) -> UInteger {
119        self.0
120    }
121
122    /// Creates from raw bits.
123    #[inline]
124    pub const fn from_bits(bits: UInteger) -> Self {
125        Self(bits)
126    }
127
128    /// Check if empty.
129    #[inline]
130    pub const fn is_empty(&self) -> bool {
131        self.0 == 0
132    }
133
134    /// Check if contains all flags in other.
135    #[inline]
136    pub const fn contains(&self, other: Self) -> bool {
137        (self.0 & other.0) == other.0
138    }
139}
140
141impl std::ops::BitOr for ResourceUsage {
142    type Output = Self;
143    #[inline]
144    fn bitor(self, rhs: Self) -> Self {
145        Self(self.0 | rhs.0)
146    }
147}
148
149impl std::ops::BitAnd for ResourceUsage {
150    type Output = Self;
151    #[inline]
152    fn bitand(self, rhs: Self) -> Self {
153        Self(self.0 & rhs.0)
154    }
155}
156
157impl std::ops::BitOrAssign for ResourceUsage {
158    #[inline]
159    fn bitor_assign(&mut self, rhs: Self) {
160        self.0 |= rhs.0;
161    }
162}
163
164/// Barrier scope for command encoders (bitflags).
165///
166/// C++ equivalent: `MTL::BarrierScope`
167#[repr(transparent)]
168#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
169pub struct BarrierScope(pub UInteger);
170
171impl BarrierScope {
172    pub const BUFFERS: Self = Self(1);
173    pub const TEXTURES: Self = Self(1 << 1);
174    pub const RENDER_TARGETS: Self = Self(1 << 2);
175
176    /// Returns the raw bits.
177    #[inline]
178    pub const fn bits(&self) -> UInteger {
179        self.0
180    }
181
182    /// Creates from raw bits.
183    #[inline]
184    pub const fn from_bits(bits: UInteger) -> Self {
185        Self(bits)
186    }
187
188    /// Check if empty.
189    #[inline]
190    pub const fn is_empty(&self) -> bool {
191        self.0 == 0
192    }
193
194    /// Check if contains all flags in other.
195    #[inline]
196    pub const fn contains(&self, other: Self) -> bool {
197        (self.0 & other.0) == other.0
198    }
199}
200
201impl std::ops::BitOr for BarrierScope {
202    type Output = Self;
203    #[inline]
204    fn bitor(self, rhs: Self) -> Self {
205        Self(self.0 | rhs.0)
206    }
207}
208
209impl std::ops::BitAnd for BarrierScope {
210    type Output = Self;
211    #[inline]
212    fn bitand(self, rhs: Self) -> Self {
213        Self(self.0 & rhs.0)
214    }
215}
216
217impl std::ops::BitOrAssign for BarrierScope {
218    #[inline]
219    fn bitor_assign(&mut self, rhs: Self) {
220        self.0 |= rhs.0;
221    }
222}
223
224/// Pipeline stages for barrier operations (bitflags).
225///
226/// C++ equivalent: `MTL::Stages`
227#[repr(transparent)]
228#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
229pub struct Stages(pub UInteger);
230
231impl Stages {
232    pub const VERTEX: Self = Self(1);
233    pub const FRAGMENT: Self = Self(1 << 1);
234    pub const TILE: Self = Self(1 << 2);
235    pub const OBJECT: Self = Self(1 << 3);
236    pub const MESH: Self = Self(1 << 4);
237    pub const RESOURCE_STATE: Self = Self(1 << 26);
238    pub const DISPATCH: Self = Self(1 << 27);
239    pub const BLIT: Self = Self(1 << 28);
240    pub const ACCELERATION_STRUCTURE: Self = Self(1 << 29);
241    pub const MACHINE_LEARNING: Self = Self(1 << 30);
242    pub const ALL: Self = Self(9223372036854775807);
243
244    /// Returns the raw bits.
245    #[inline]
246    pub const fn bits(&self) -> UInteger {
247        self.0
248    }
249
250    /// Creates from raw bits.
251    #[inline]
252    pub const fn from_bits(bits: UInteger) -> Self {
253        Self(bits)
254    }
255
256    /// Check if empty.
257    #[inline]
258    pub const fn is_empty(&self) -> bool {
259        self.0 == 0
260    }
261
262    /// Check if contains all flags in other.
263    #[inline]
264    pub const fn contains(&self, other: Self) -> bool {
265        (self.0 & other.0) == other.0
266    }
267}
268
269impl std::ops::BitOr for Stages {
270    type Output = Self;
271    #[inline]
272    fn bitor(self, rhs: Self) -> Self {
273        Self(self.0 | rhs.0)
274    }
275}
276
277impl std::ops::BitAnd for Stages {
278    type Output = Self;
279    #[inline]
280    fn bitand(self, rhs: Self) -> Self {
281        Self(self.0 & rhs.0)
282    }
283}
284
285impl std::ops::BitOrAssign for Stages {
286    #[inline]
287    fn bitor_assign(&mut self, rhs: Self) {
288        self.0 |= rhs.0;
289    }
290}
291
292#[cfg(test)]
293mod tests {
294    use super::*;
295
296    #[test]
297    fn test_command_buffer_status_values() {
298        assert_eq!(CommandBufferStatus::NOT_ENQUEUED.0, 0);
299        assert_eq!(CommandBufferStatus::COMPLETED.0, 4);
300        assert_eq!(CommandBufferStatus::ERROR.0, 5);
301    }
302
303    #[test]
304    fn test_command_buffer_error_values() {
305        assert_eq!(CommandBufferError::NONE.0, 0);
306        assert_eq!(CommandBufferError::TIMEOUT.0, 2);
307        assert_eq!(
308            CommandBufferError::BLACKLISTED.0,
309            CommandBufferError::ACCESS_REVOKED.0
310        );
311    }
312
313    #[test]
314    fn test_resource_usage_bitor() {
315        let usage = ResourceUsage::READ | ResourceUsage::WRITE;
316        assert!(usage.contains(ResourceUsage::READ));
317        assert!(usage.contains(ResourceUsage::WRITE));
318        assert!(!usage.contains(ResourceUsage::SAMPLE));
319    }
320
321    #[test]
322    fn test_barrier_scope_values() {
323        assert_eq!(BarrierScope::BUFFERS.0, 1);
324        assert_eq!(BarrierScope::TEXTURES.0, 2);
325        assert_eq!(BarrierScope::RENDER_TARGETS.0, 4);
326    }
327
328    #[test]
329    fn test_stages_values() {
330        assert_eq!(Stages::VERTEX.0, 1);
331        assert_eq!(Stages::FRAGMENT.0, 2);
332        assert_eq!(Stages::BLIT.0, 1 << 28);
333    }
334}