Skip to main content

mtl_gpu/device/
command_queue.rs

1//! Device command queue creation methods.
2//!
3//! Corresponds to command queue creation methods in `Metal/MTLDevice.hpp`.
4
5use std::ffi::c_void;
6
7use mtl_foundation::{Referencing, UInteger};
8use mtl_sys::{msg_send_0, msg_send_1, sel};
9
10use super::Device;
11use crate::command_queue::CommandQueue;
12
13impl Device {
14    // =========================================================================
15    // Command Queue Creation
16    // =========================================================================
17
18    /// Create a new command queue.
19    ///
20    /// C++ equivalent: `CommandQueue* newCommandQueue()`
21    pub fn new_command_queue(&self) -> Option<CommandQueue> {
22        unsafe {
23            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(newCommandQueue));
24            CommandQueue::from_raw(ptr)
25        }
26    }
27
28    /// Create a new command queue with a maximum command buffer count.
29    ///
30    /// C++ equivalent: `CommandQueue* newCommandQueue(NS::UInteger maxCommandBufferCount)`
31    pub fn new_command_queue_with_max_command_buffer_count(
32        &self,
33        max_command_buffer_count: UInteger,
34    ) -> Option<CommandQueue> {
35        unsafe {
36            let ptr: *mut c_void = msg_send_1(
37                self.as_ptr(),
38                sel!(newCommandQueueWithMaxCommandBufferCount:),
39                max_command_buffer_count,
40            );
41            CommandQueue::from_raw(ptr)
42        }
43    }
44
45    /// Create a new command queue with a descriptor.
46    ///
47    /// C++ equivalent: `CommandQueue* newCommandQueue(const CommandQueueDescriptor*)`
48    ///
49    /// # Safety
50    ///
51    /// The descriptor pointer must be valid.
52    pub unsafe fn new_command_queue_with_descriptor(
53        &self,
54        descriptor: *const c_void,
55    ) -> Option<CommandQueue> {
56        unsafe {
57            let ptr: *mut c_void = msg_send_1(
58                self.as_ptr(),
59                sel!(newCommandQueueWithDescriptor:),
60                descriptor,
61            );
62            CommandQueue::from_raw(ptr)
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use crate::device::system_default;
70
71    #[test]
72    fn test_new_command_queue() {
73        let device = system_default().expect("no Metal device");
74        let queue = device.new_command_queue();
75        assert!(queue.is_some());
76    }
77
78    #[test]
79    fn test_new_command_queue_with_max() {
80        let device = system_default().expect("no Metal device");
81        let queue = device.new_command_queue_with_max_command_buffer_count(64);
82        assert!(queue.is_some());
83    }
84
85    #[test]
86    fn test_command_buffer_creation() {
87        let device = system_default().expect("no Metal device");
88        let queue = device.new_command_queue().expect("failed to create queue");
89        let cmd_buf = queue.command_buffer();
90        assert!(cmd_buf.is_some());
91    }
92}