Skip to main content

mtl_gpu/texture/
view_descriptor.rs

1//! Configuration for creating texture views.
2
3use std::ffi::c_void;
4use std::ptr::NonNull;
5
6use mtl_foundation::Referencing;
7use mtl_sys::{msg_send_0, msg_send_1, sel};
8
9use crate::enums::{PixelFormat, TextureSwizzleChannels, TextureType};
10
11/// Configuration for creating texture views.
12///
13/// C++ equivalent: `MTL::TextureViewDescriptor`
14#[repr(transparent)]
15pub struct TextureViewDescriptor(pub(crate) NonNull<c_void>);
16
17impl TextureViewDescriptor {
18    /// Create a new texture view descriptor.
19    ///
20    /// C++ equivalent: `static TextureViewDescriptor* alloc()->init()`
21    pub fn new() -> Option<Self> {
22        unsafe {
23            let class = mtl_sys::Class::get("MTLTextureViewDescriptor")?;
24            let ptr: *mut c_void = msg_send_0(class.as_ptr(), sel!(alloc));
25            if ptr.is_null() {
26                return None;
27            }
28            let ptr: *mut c_void = msg_send_0(ptr, sel!(init));
29            Self::from_raw(ptr)
30        }
31    }
32
33    /// Create a TextureViewDescriptor from a raw pointer.
34    ///
35    /// # Safety
36    ///
37    /// The pointer must be a valid Metal texture view descriptor object.
38    #[inline]
39    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
40        NonNull::new(ptr).map(Self)
41    }
42
43    /// Get the raw pointer.
44    #[inline]
45    pub fn as_raw(&self) -> *mut c_void {
46        self.0.as_ptr()
47    }
48
49    // =========================================================================
50    // Properties - Getters
51    // =========================================================================
52
53    /// Get the pixel format.
54    #[inline]
55    pub fn pixel_format(&self) -> PixelFormat {
56        unsafe { msg_send_0(self.as_ptr(), sel!(pixelFormat)) }
57    }
58
59    /// Get the texture type.
60    #[inline]
61    pub fn texture_type(&self) -> TextureType {
62        unsafe { msg_send_0(self.as_ptr(), sel!(textureType)) }
63    }
64
65    /// Get the level range.
66    #[inline]
67    pub fn level_range(&self) -> mtl_foundation::Range {
68        unsafe { msg_send_0(self.as_ptr(), sel!(levelRange)) }
69    }
70
71    /// Get the slice range.
72    #[inline]
73    pub fn slice_range(&self) -> mtl_foundation::Range {
74        unsafe { msg_send_0(self.as_ptr(), sel!(sliceRange)) }
75    }
76
77    /// Get the swizzle channels.
78    #[inline]
79    pub fn swizzle(&self) -> TextureSwizzleChannels {
80        unsafe { msg_send_0(self.as_ptr(), sel!(swizzle)) }
81    }
82
83    // =========================================================================
84    // Properties - Setters
85    // =========================================================================
86
87    /// Set the pixel format.
88    #[inline]
89    pub fn set_pixel_format(&self, pixel_format: PixelFormat) {
90        unsafe {
91            msg_send_1::<(), PixelFormat>(self.as_ptr(), sel!(setPixelFormat:), pixel_format);
92        }
93    }
94
95    /// Set the texture type.
96    #[inline]
97    pub fn set_texture_type(&self, texture_type: TextureType) {
98        unsafe {
99            msg_send_1::<(), TextureType>(self.as_ptr(), sel!(setTextureType:), texture_type);
100        }
101    }
102
103    /// Set the level range.
104    #[inline]
105    pub fn set_level_range(&self, range: mtl_foundation::Range) {
106        unsafe {
107            msg_send_1::<(), mtl_foundation::Range>(self.as_ptr(), sel!(setLevelRange:), range);
108        }
109    }
110
111    /// Set the slice range.
112    #[inline]
113    pub fn set_slice_range(&self, range: mtl_foundation::Range) {
114        unsafe {
115            msg_send_1::<(), mtl_foundation::Range>(self.as_ptr(), sel!(setSliceRange:), range);
116        }
117    }
118
119    /// Set the swizzle channels.
120    #[inline]
121    pub fn set_swizzle(&self, swizzle: TextureSwizzleChannels) {
122        unsafe {
123            msg_send_1::<(), TextureSwizzleChannels>(self.as_ptr(), sel!(setSwizzle:), swizzle);
124        }
125    }
126}
127
128impl Default for TextureViewDescriptor {
129    fn default() -> Self {
130        Self::new().expect("failed to create texture view descriptor")
131    }
132}
133
134impl Clone for TextureViewDescriptor {
135    fn clone(&self) -> Self {
136        unsafe {
137            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(copy));
138            Self::from_raw(ptr).expect("failed to copy texture view descriptor")
139        }
140    }
141}
142
143impl Drop for TextureViewDescriptor {
144    fn drop(&mut self) {
145        unsafe {
146            msg_send_0::<()>(self.as_ptr(), sel!(release));
147        }
148    }
149}
150
151impl Referencing for TextureViewDescriptor {
152    #[inline]
153    fn as_ptr(&self) -> *const c_void {
154        self.0.as_ptr()
155    }
156}
157
158unsafe impl Send for TextureViewDescriptor {}
159unsafe impl Sync for TextureViewDescriptor {}
160
161impl std::fmt::Debug for TextureViewDescriptor {
162    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
163        f.debug_struct("TextureViewDescriptor")
164            .field("pixel_format", &self.pixel_format())
165            .field("texture_type", &self.texture_type())
166            .finish()
167    }
168}