Skip to main content

mtl_gpu/argument/
texture_binding.rs

1//! Texture binding information.
2
3use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::{Referencing, UInteger};
7use mtl_sys::{msg_send_0, sel};
8
9use crate::enums::{BindingAccess, BindingType, DataType, TextureType};
10
11/// Texture binding information.
12///
13/// C++ equivalent: `MTL::TextureBinding`
14#[repr(transparent)]
15pub struct TextureBinding(pub(crate) NonNull<c_void>);
16
17impl TextureBinding {
18    /// Create from a raw pointer.
19    ///
20    /// # Safety
21    ///
22    /// The pointer must be a valid Metal TextureBinding.
23    #[inline]
24    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
25        NonNull::new(ptr).map(Self)
26    }
27
28    /// Get the raw pointer.
29    #[inline]
30    pub fn as_raw(&self) -> *mut c_void {
31        self.0.as_ptr()
32    }
33
34    // Inherited from Binding
35
36    /// Get the access mode.
37    #[inline]
38    pub fn access(&self) -> BindingAccess {
39        unsafe { msg_send_0(self.as_ptr(), sel!(access)) }
40    }
41
42    /// Get the index.
43    #[inline]
44    pub fn index(&self) -> UInteger {
45        unsafe { msg_send_0(self.as_ptr(), sel!(index)) }
46    }
47
48    /// Check if this is an argument.
49    #[inline]
50    pub fn is_argument(&self) -> bool {
51        unsafe { msg_send_0(self.as_ptr(), sel!(isArgument)) }
52    }
53
54    /// Check if this binding is used.
55    #[inline]
56    pub fn is_used(&self) -> bool {
57        unsafe { msg_send_0(self.as_ptr(), sel!(isUsed)) }
58    }
59
60    /// Get the name.
61    pub fn name(&self) -> Option<String> {
62        unsafe {
63            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(name));
64            if ptr.is_null() {
65                return None;
66            }
67            let utf8_ptr: *const std::ffi::c_char =
68                mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
69            if utf8_ptr.is_null() {
70                return None;
71            }
72            let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
73            Some(c_str.to_string_lossy().into_owned())
74        }
75    }
76
77    /// Get the binding type.
78    #[inline]
79    pub fn binding_type(&self) -> BindingType {
80        unsafe { msg_send_0(self.as_ptr(), sel!(type)) }
81    }
82
83    // TextureBinding-specific
84
85    /// Get the array length.
86    ///
87    /// C++ equivalent: `NS::UInteger arrayLength() const`
88    #[inline]
89    pub fn array_length(&self) -> UInteger {
90        unsafe { msg_send_0(self.as_ptr(), sel!(arrayLength)) }
91    }
92
93    /// Check if this is a depth texture.
94    ///
95    /// C++ equivalent: `bool isDepthTexture() const`
96    #[inline]
97    pub fn is_depth_texture(&self) -> bool {
98        unsafe { msg_send_0(self.as_ptr(), sel!(isDepthTexture)) }
99    }
100
101    /// Get the texture data type.
102    ///
103    /// C++ equivalent: `DataType textureDataType() const`
104    #[inline]
105    pub fn texture_data_type(&self) -> DataType {
106        unsafe { msg_send_0(self.as_ptr(), sel!(textureDataType)) }
107    }
108
109    /// Get the texture type.
110    ///
111    /// C++ equivalent: `TextureType textureType() const`
112    #[inline]
113    pub fn texture_type(&self) -> TextureType {
114        unsafe { msg_send_0(self.as_ptr(), sel!(textureType)) }
115    }
116
117    /// Check if this is a depth texture (deprecated).
118    ///
119    /// C++ equivalent: `bool depthTexture() const`
120    #[deprecated(note = "Use is_depth_texture instead")]
121    #[inline]
122    pub fn depth_texture(&self) -> bool {
123        unsafe { msg_send_0(self.as_ptr(), sel!(depthTexture)) }
124    }
125}
126
127impl Clone for TextureBinding {
128    fn clone(&self) -> Self {
129        unsafe {
130            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
131        }
132        Self(self.0)
133    }
134}
135
136impl Drop for TextureBinding {
137    fn drop(&mut self) {
138        unsafe {
139            msg_send_0::<()>(self.as_ptr(), sel!(release));
140        }
141    }
142}
143
144impl Referencing for TextureBinding {
145    #[inline]
146    fn as_ptr(&self) -> *const c_void {
147        self.0.as_ptr()
148    }
149}
150
151unsafe impl Send for TextureBinding {}
152unsafe impl Sync for TextureBinding {}