Skip to main content

mtl_gpu/enums/
texture.rs

1//! Texture enumerations.
2//!
3//! Corresponds to `Metal/MTLTexture.hpp`.
4
5use mtl_foundation::{Integer, UInteger};
6
7/// Types of textures.
8///
9/// C++ equivalent: `MTL::TextureType`
10#[repr(transparent)]
11#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
12pub struct TextureType(pub UInteger);
13
14impl TextureType {
15    pub const TYPE_1D: Self = Self(0);
16    pub const TYPE_1D_ARRAY: Self = Self(1);
17    pub const TYPE_2D: Self = Self(2);
18    pub const TYPE_2D_ARRAY: Self = Self(3);
19    pub const TYPE_2D_MULTISAMPLE: Self = Self(4);
20    pub const TYPE_CUBE: Self = Self(5);
21    pub const TYPE_CUBE_ARRAY: Self = Self(6);
22    pub const TYPE_3D: Self = Self(7);
23    pub const TYPE_2D_MULTISAMPLE_ARRAY: Self = Self(8);
24    pub const TYPE_TEXTURE_BUFFER: Self = Self(9);
25}
26
27/// Texture swizzle values.
28///
29/// C++ equivalent: `MTL::TextureSwizzle`
30///
31/// Note: This uses uint8_t in C++, not NS::UInteger
32#[repr(transparent)]
33#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
34pub struct TextureSwizzle(pub u8);
35
36impl TextureSwizzle {
37    pub const ZERO: Self = Self(0);
38    pub const ONE: Self = Self(1);
39    pub const RED: Self = Self(2);
40    pub const GREEN: Self = Self(3);
41    pub const BLUE: Self = Self(4);
42    pub const ALPHA: Self = Self(5);
43}
44
45/// Texture compression type.
46///
47/// C++ equivalent: `MTL::TextureCompressionType`
48#[repr(transparent)]
49#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
50pub struct TextureCompressionType(pub Integer);
51
52impl TextureCompressionType {
53    pub const LOSSLESS: Self = Self(0);
54    pub const LOSSY: Self = Self(1);
55}
56
57/// Texture usage flags (bitflags).
58///
59/// C++ equivalent: `MTL::TextureUsage`
60#[repr(transparent)]
61#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
62pub struct TextureUsage(pub UInteger);
63
64impl TextureUsage {
65    pub const UNKNOWN: Self = Self(0);
66    pub const SHADER_READ: Self = Self(1);
67    pub const SHADER_WRITE: Self = Self(1 << 1);
68    pub const RENDER_TARGET: Self = Self(1 << 2);
69    pub const PIXEL_FORMAT_VIEW: Self = Self(1 << 4);
70    pub const SHADER_ATOMIC: Self = Self(1 << 5);
71
72    /// Returns the raw bits.
73    #[inline]
74    pub const fn bits(&self) -> UInteger {
75        self.0
76    }
77
78    /// Creates from raw bits.
79    #[inline]
80    pub const fn from_bits(bits: UInteger) -> Self {
81        Self(bits)
82    }
83
84    /// Check if empty.
85    #[inline]
86    pub const fn is_empty(&self) -> bool {
87        self.0 == 0
88    }
89
90    /// Check if contains all flags in other.
91    #[inline]
92    pub const fn contains(&self, other: Self) -> bool {
93        (self.0 & other.0) == other.0
94    }
95}
96
97impl std::ops::BitOr for TextureUsage {
98    type Output = Self;
99    #[inline]
100    fn bitor(self, rhs: Self) -> Self {
101        Self(self.0 | rhs.0)
102    }
103}
104
105impl std::ops::BitAnd for TextureUsage {
106    type Output = Self;
107    #[inline]
108    fn bitand(self, rhs: Self) -> Self {
109        Self(self.0 & rhs.0)
110    }
111}
112
113impl std::ops::BitOrAssign for TextureUsage {
114    #[inline]
115    fn bitor_assign(&mut self, rhs: Self) {
116        self.0 |= rhs.0;
117    }
118}
119
120/// Texture swizzle channels structure.
121///
122/// C++ equivalent: `MTL::TextureSwizzleChannels`
123#[repr(C, packed)]
124#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
125pub struct TextureSwizzleChannels {
126    pub red: TextureSwizzle,
127    pub green: TextureSwizzle,
128    pub blue: TextureSwizzle,
129    pub alpha: TextureSwizzle,
130}
131
132impl TextureSwizzleChannels {
133    /// Create a new TextureSwizzleChannels.
134    #[inline]
135    pub const fn new(
136        red: TextureSwizzle,
137        green: TextureSwizzle,
138        blue: TextureSwizzle,
139        alpha: TextureSwizzle,
140    ) -> Self {
141        Self {
142            red,
143            green,
144            blue,
145            alpha,
146        }
147    }
148
149    /// Create a new TextureSwizzleChannels (C++ style factory method).
150    ///
151    /// C++ equivalent: `static TextureSwizzleChannels Make(...)`
152    #[inline]
153    pub const fn make(
154        r: TextureSwizzle,
155        g: TextureSwizzle,
156        b: TextureSwizzle,
157        a: TextureSwizzle,
158    ) -> Self {
159        Self::new(r, g, b, a)
160    }
161
162    /// Get the default swizzle channels (identity mapping).
163    ///
164    /// C++ equivalent: `static TextureSwizzleChannels Default()`
165    #[inline]
166    pub const fn default_channels() -> Self {
167        Self {
168            red: TextureSwizzle::RED,
169            green: TextureSwizzle::GREEN,
170            blue: TextureSwizzle::BLUE,
171            alpha: TextureSwizzle::ALPHA,
172        }
173    }
174}
175
176impl Default for TextureSwizzleChannels {
177    fn default() -> Self {
178        Self::default_channels()
179    }
180}
181
182#[cfg(test)]
183mod tests {
184    use super::*;
185
186    #[test]
187    fn test_texture_type_values() {
188        assert_eq!(TextureType::TYPE_1D.0, 0);
189        assert_eq!(TextureType::TYPE_2D.0, 2);
190        assert_eq!(TextureType::TYPE_3D.0, 7);
191        assert_eq!(TextureType::TYPE_TEXTURE_BUFFER.0, 9);
192    }
193
194    #[test]
195    fn test_texture_swizzle_size() {
196        // TextureSwizzle uses u8 in C++
197        assert_eq!(std::mem::size_of::<TextureSwizzle>(), 1);
198    }
199
200    #[test]
201    fn test_texture_swizzle_channels_size() {
202        assert_eq!(std::mem::size_of::<TextureSwizzleChannels>(), 4);
203    }
204
205    #[test]
206    fn test_texture_usage_bitor() {
207        let usage = TextureUsage::SHADER_READ | TextureUsage::RENDER_TARGET;
208        assert!(usage.contains(TextureUsage::SHADER_READ));
209        assert!(usage.contains(TextureUsage::RENDER_TARGET));
210    }
211}