Skip to main content

mtl_gpu/pass/
resource_state.rs

1//! Resource state pass descriptors.
2//!
3//! Corresponds to `Metal/MTLResourceStatePass.hpp`.
4
5use std::ffi::c_void;
6use std::ptr::NonNull;
7
8use mtl_foundation::{Referencing, UInteger};
9use mtl_sys::{Class, msg_send_0, msg_send_1, msg_send_2, sel};
10
11use crate::counter::CounterSampleBuffer;
12
13/// A descriptor for a sample buffer attachment in a resource state pass.
14///
15/// C++ equivalent: `MTL::ResourceStatePassSampleBufferAttachmentDescriptor`
16#[repr(transparent)]
17pub struct ResourceStatePassSampleBufferAttachmentDescriptor(pub(crate) NonNull<c_void>);
18
19impl ResourceStatePassSampleBufferAttachmentDescriptor {
20    /// Create a new sample buffer attachment descriptor.
21    ///
22    /// C++ equivalent: `alloc()->init()`
23    pub fn new() -> Option<Self> {
24        let class = Class::get("MTLResourceStatePassSampleBufferAttachmentDescriptor")?;
25        unsafe {
26            let obj: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
27            if obj.is_null() {
28                return None;
29            }
30            let obj: *mut c_void = msg_send_0(obj, sel!(init));
31            Self::from_raw(obj)
32        }
33    }
34
35    /// Create from a raw pointer.
36    ///
37    /// # Safety
38    ///
39    /// The pointer must be a valid descriptor object.
40    #[inline]
41    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
42        NonNull::new(ptr).map(Self)
43    }
44
45    /// Get the raw pointer.
46    #[inline]
47    pub fn as_raw(&self) -> *mut c_void {
48        self.0.as_ptr()
49    }
50
51    /// Get the sample buffer.
52    ///
53    /// C++ equivalent: `CounterSampleBuffer* sampleBuffer() const`
54    pub fn sample_buffer(&self) -> Option<CounterSampleBuffer> {
55        unsafe {
56            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(sampleBuffer));
57            if ptr.is_null() {
58                None
59            } else {
60                let _: *mut c_void = msg_send_0(ptr, sel!(retain));
61                CounterSampleBuffer::from_raw(ptr)
62            }
63        }
64    }
65
66    /// Set the sample buffer.
67    ///
68    /// C++ equivalent: `void setSampleBuffer(const CounterSampleBuffer*)`
69    pub fn set_sample_buffer(&self, sample_buffer: Option<&CounterSampleBuffer>) {
70        unsafe {
71            let ptr = sample_buffer.map_or(std::ptr::null(), |b| b.as_ptr());
72            let _: () = msg_send_1(self.as_ptr(), sel!(setSampleBuffer:), ptr);
73        }
74    }
75
76    /// Get the start of encoder sample index.
77    ///
78    /// C++ equivalent: `NS::UInteger startOfEncoderSampleIndex() const`
79    pub fn start_of_encoder_sample_index(&self) -> UInteger {
80        unsafe { msg_send_0(self.as_ptr(), sel!(startOfEncoderSampleIndex)) }
81    }
82
83    /// Set the start of encoder sample index.
84    ///
85    /// C++ equivalent: `void setStartOfEncoderSampleIndex(NS::UInteger)`
86    pub fn set_start_of_encoder_sample_index(&self, index: UInteger) {
87        unsafe {
88            let _: () = msg_send_1(self.as_ptr(), sel!(setStartOfEncoderSampleIndex:), index);
89        }
90    }
91
92    /// Get the end of encoder sample index.
93    ///
94    /// C++ equivalent: `NS::UInteger endOfEncoderSampleIndex() const`
95    pub fn end_of_encoder_sample_index(&self) -> UInteger {
96        unsafe { msg_send_0(self.as_ptr(), sel!(endOfEncoderSampleIndex)) }
97    }
98
99    /// Set the end of encoder sample index.
100    ///
101    /// C++ equivalent: `void setEndOfEncoderSampleIndex(NS::UInteger)`
102    pub fn set_end_of_encoder_sample_index(&self, index: UInteger) {
103        unsafe {
104            let _: () = msg_send_1(self.as_ptr(), sel!(setEndOfEncoderSampleIndex:), index);
105        }
106    }
107}
108
109impl Default for ResourceStatePassSampleBufferAttachmentDescriptor {
110    fn default() -> Self {
111        Self::new().expect("failed to create ResourceStatePassSampleBufferAttachmentDescriptor")
112    }
113}
114
115impl Clone for ResourceStatePassSampleBufferAttachmentDescriptor {
116    fn clone(&self) -> Self {
117        unsafe {
118            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
119        }
120        Self(self.0)
121    }
122}
123
124impl Drop for ResourceStatePassSampleBufferAttachmentDescriptor {
125    fn drop(&mut self) {
126        unsafe {
127            msg_send_0::<()>(self.as_ptr(), sel!(release));
128        }
129    }
130}
131
132impl Referencing for ResourceStatePassSampleBufferAttachmentDescriptor {
133    #[inline]
134    fn as_ptr(&self) -> *const c_void {
135        self.0.as_ptr()
136    }
137}
138
139unsafe impl Send for ResourceStatePassSampleBufferAttachmentDescriptor {}
140unsafe impl Sync for ResourceStatePassSampleBufferAttachmentDescriptor {}
141
142impl std::fmt::Debug for ResourceStatePassSampleBufferAttachmentDescriptor {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        f.debug_struct("ResourceStatePassSampleBufferAttachmentDescriptor")
145            .field(
146                "start_of_encoder_sample_index",
147                &self.start_of_encoder_sample_index(),
148            )
149            .field(
150                "end_of_encoder_sample_index",
151                &self.end_of_encoder_sample_index(),
152            )
153            .finish()
154    }
155}
156
157/// An array of sample buffer attachment descriptors for resource state passes.
158///
159/// C++ equivalent: `MTL::ResourceStatePassSampleBufferAttachmentDescriptorArray`
160#[repr(transparent)]
161pub struct ResourceStatePassSampleBufferAttachmentDescriptorArray(pub(crate) NonNull<c_void>);
162
163impl ResourceStatePassSampleBufferAttachmentDescriptorArray {
164    /// Create from a raw pointer.
165    ///
166    /// # Safety
167    ///
168    /// The pointer must be a valid descriptor array object.
169    #[inline]
170    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
171        NonNull::new(ptr).map(Self)
172    }
173
174    /// Get the raw pointer.
175    #[inline]
176    pub fn as_raw(&self) -> *mut c_void {
177        self.0.as_ptr()
178    }
179
180    /// Get the descriptor at the specified index.
181    ///
182    /// C++ equivalent: `ResourceStatePassSampleBufferAttachmentDescriptor* object(NS::UInteger)`
183    pub fn object(
184        &self,
185        index: UInteger,
186    ) -> Option<ResourceStatePassSampleBufferAttachmentDescriptor> {
187        unsafe {
188            let ptr: *mut c_void =
189                msg_send_1(self.as_ptr(), sel!(objectAtIndexedSubscript:), index);
190            if ptr.is_null() {
191                None
192            } else {
193                let _: *mut c_void = msg_send_0(ptr, sel!(retain));
194                ResourceStatePassSampleBufferAttachmentDescriptor::from_raw(ptr)
195            }
196        }
197    }
198
199    /// Set the descriptor at the specified index.
200    ///
201    /// C++ equivalent: `void setObject(const ResourceStatePassSampleBufferAttachmentDescriptor*, NS::UInteger)`
202    pub fn set_object(
203        &self,
204        descriptor: Option<&ResourceStatePassSampleBufferAttachmentDescriptor>,
205        index: UInteger,
206    ) {
207        unsafe {
208            let ptr = descriptor.map_or(std::ptr::null(), |d| d.as_ptr());
209            let _: () = msg_send_2(
210                self.as_ptr(),
211                sel!(setObject: atIndexedSubscript:),
212                ptr,
213                index,
214            );
215        }
216    }
217}
218
219impl Clone for ResourceStatePassSampleBufferAttachmentDescriptorArray {
220    fn clone(&self) -> Self {
221        unsafe {
222            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
223        }
224        Self(self.0)
225    }
226}
227
228impl Drop for ResourceStatePassSampleBufferAttachmentDescriptorArray {
229    fn drop(&mut self) {
230        unsafe {
231            msg_send_0::<()>(self.as_ptr(), sel!(release));
232        }
233    }
234}
235
236impl Referencing for ResourceStatePassSampleBufferAttachmentDescriptorArray {
237    #[inline]
238    fn as_ptr(&self) -> *const c_void {
239        self.0.as_ptr()
240    }
241}
242
243unsafe impl Send for ResourceStatePassSampleBufferAttachmentDescriptorArray {}
244unsafe impl Sync for ResourceStatePassSampleBufferAttachmentDescriptorArray {}
245
246impl std::fmt::Debug for ResourceStatePassSampleBufferAttachmentDescriptorArray {
247    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
248        f.debug_struct("ResourceStatePassSampleBufferAttachmentDescriptorArray")
249            .finish()
250    }
251}
252
253/// A descriptor for a resource state pass.
254///
255/// C++ equivalent: `MTL::ResourceStatePassDescriptor`
256#[repr(transparent)]
257pub struct ResourceStatePassDescriptor(pub(crate) NonNull<c_void>);
258
259impl ResourceStatePassDescriptor {
260    /// Create a new resource state pass descriptor.
261    ///
262    /// C++ equivalent: `resourceStatePassDescriptor()`
263    pub fn new() -> Option<Self> {
264        let class = Class::get("MTLResourceStatePassDescriptor")?;
265        unsafe {
266            let obj: *mut c_void = msg_send_0(class.as_ptr(), sel!(resourceStatePassDescriptor));
267            if obj.is_null() {
268                None
269            } else {
270                let _: *mut c_void = msg_send_0(obj, sel!(retain));
271                Self::from_raw(obj)
272            }
273        }
274    }
275
276    /// Create from a raw pointer.
277    ///
278    /// # Safety
279    ///
280    /// The pointer must be a valid descriptor object.
281    #[inline]
282    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
283        NonNull::new(ptr).map(Self)
284    }
285
286    /// Get the raw pointer.
287    #[inline]
288    pub fn as_raw(&self) -> *mut c_void {
289        self.0.as_ptr()
290    }
291
292    /// Get the sample buffer attachments array.
293    ///
294    /// C++ equivalent: `ResourceStatePassSampleBufferAttachmentDescriptorArray* sampleBufferAttachments() const`
295    pub fn sample_buffer_attachments(
296        &self,
297    ) -> Option<ResourceStatePassSampleBufferAttachmentDescriptorArray> {
298        unsafe {
299            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(sampleBufferAttachments));
300            if ptr.is_null() {
301                None
302            } else {
303                let _: *mut c_void = msg_send_0(ptr, sel!(retain));
304                ResourceStatePassSampleBufferAttachmentDescriptorArray::from_raw(ptr)
305            }
306        }
307    }
308}
309
310impl Default for ResourceStatePassDescriptor {
311    fn default() -> Self {
312        Self::new().expect("failed to create ResourceStatePassDescriptor")
313    }
314}
315
316impl Clone for ResourceStatePassDescriptor {
317    fn clone(&self) -> Self {
318        unsafe {
319            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
320        }
321        Self(self.0)
322    }
323}
324
325impl Drop for ResourceStatePassDescriptor {
326    fn drop(&mut self) {
327        unsafe {
328            msg_send_0::<()>(self.as_ptr(), sel!(release));
329        }
330    }
331}
332
333impl Referencing for ResourceStatePassDescriptor {
334    #[inline]
335    fn as_ptr(&self) -> *const c_void {
336        self.0.as_ptr()
337    }
338}
339
340unsafe impl Send for ResourceStatePassDescriptor {}
341unsafe impl Sync for ResourceStatePassDescriptor {}
342
343impl std::fmt::Debug for ResourceStatePassDescriptor {
344    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
345        f.debug_struct("ResourceStatePassDescriptor").finish()
346    }
347}
348
349#[cfg(test)]
350mod tests {
351    use super::*;
352
353    #[test]
354    fn test_resource_state_pass_descriptor_size() {
355        assert_eq!(
356            std::mem::size_of::<ResourceStatePassDescriptor>(),
357            std::mem::size_of::<*mut c_void>()
358        );
359    }
360
361    #[test]
362    fn test_resource_state_pass_sample_buffer_attachment_descriptor_size() {
363        assert_eq!(
364            std::mem::size_of::<ResourceStatePassSampleBufferAttachmentDescriptor>(),
365            std::mem::size_of::<*mut c_void>()
366        );
367    }
368}