bedrock/resources/
sampler.rs

1use crate::*;
2use derives::implements;
3
4pub trait Sampler: VkHandle<Handle = VkSampler> {}
5DerefContainerBracketImpl!(for Sampler {});
6GuardsImpl!(for Sampler {});
7
8#[derive(VkHandle, VkObject)]
9#[VkObject(type = VkSampler::OBJECT_TYPE)]
10pub struct SamplerObject<Device: VkHandle<Handle = VkDevice>>(pub(crate) VkSampler, pub(crate) Device);
11#[implements]
12impl<Device: VkHandle<Handle = VkDevice>> Drop for SamplerObject<Device> {
13    #[inline(always)]
14    fn drop(&mut self) {
15        unsafe {
16            crate::vkfn::destroy_sampler(self.1.native_ptr(), self.0, core::ptr::null());
17        }
18    }
19}
20unsafe impl<Device: VkHandle<Handle = VkDevice> + Sync> Sync for SamplerObject<Device> {}
21unsafe impl<Device: VkHandle<Handle = VkDevice> + Send> Send for SamplerObject<Device> {}
22impl<Device: VkHandle<Handle = VkDevice>> DeviceChildHandle for SamplerObject<Device> {
23    #[inline(always)]
24    fn device_handle(&self) -> VkDevice {
25        self.1.native_ptr()
26    }
27}
28impl<Device: crate::Device> DeviceChild for SamplerObject<Device> {
29    type ConcreteDevice = Device;
30
31    #[inline(always)]
32    fn device(&self) -> &Self::ConcreteDevice {
33        &self.1
34    }
35}
36impl<Device: VkHandle<Handle = VkDevice>> Sampler for SamplerObject<Device> {}
37impl<Device: VkHandle<Handle = VkDevice>> SamplerObject<Device> {
38    /// Constructs from raw values
39    /// # Safety
40    /// the resource must be created from the parent
41    pub const unsafe fn manage(handle: VkSampler, parent: Device) -> Self {
42        Self(handle, parent)
43    }
44
45    /// Purges internal values (Drop will not be called for this resource)
46    pub const fn unmanage(self) -> (VkSampler, Device) {
47        let v = self.0;
48        let p = unsafe { core::ptr::read(&self.1) };
49        core::mem::forget(self);
50
51        (v, p)
52    }
53}
54impl<Device: VkHandle<Handle = VkDevice> + Clone> SamplerObject<&'_ Device> {
55    /// Owning parent object by cloning it.
56    #[inline(always)]
57    pub fn clone_parent(self) -> SamplerObject<Device> {
58        let r = SamplerObject(self.0, self.1.clone());
59        core::mem::forget(self);
60
61        r
62    }
63}
64impl<Device: crate::Device> SamplerObject<Device> {
65    /// Create a new sampler object
66    /// # Failures
67    /// On failure, this command returns
68    ///
69    /// * `VK_ERROR_OUT_OF_HOST_MEMORY`
70    /// * `VK_ERROR_OUT_OF_DEVICE_MEMORY`
71    /// * `VK_ERROR_TOO_MANY_OBJECTS`
72    #[implements]
73    pub fn new(device: Device, info: &SamplerCreateInfo) -> crate::Result<Self> {
74        Ok(unsafe { Self::manage(device.new_sampler_raw(info, None)?, device) })
75    }
76}
77
78#[repr(transparent)]
79#[derive(Clone)]
80pub struct SamplerCreateInfo(VkSamplerCreateInfo);
81impl Default for SamplerCreateInfo {
82    #[inline(always)]
83    fn default() -> Self {
84        Self::new()
85    }
86}
87impl SamplerCreateInfo {
88    /// Initialize by default sampler parameters: Linear Filtering, Repeat addressing, no anisotrophy and no lod biases
89    pub const fn new() -> Self {
90        Self(VkSamplerCreateInfo {
91            sType: VkSamplerCreateInfo::TYPE,
92            pNext: core::ptr::null(),
93            flags: 0,
94            magFilter: FilterMode::Linear as _,
95            minFilter: FilterMode::Linear as _,
96            mipmapMode: MipmapFilterMode::Linear as _,
97            addressModeU: AddressingMode::Repeat as _,
98            addressModeV: AddressingMode::Repeat as _,
99            addressModeW: AddressingMode::Repeat as _,
100            mipLodBias: 0.0,
101            anisotropyEnable: false as _,
102            compareEnable: false as _,
103            compareOp: CompareOp::Always as _,
104            minLod: 0.0,
105            maxLod: 0.0,
106            borderColor: BorderColor::TransparentBlackF as _,
107            unnormalizedCoordinates: false as _,
108            maxAnisotropy: 1.0,
109        })
110    }
111
112    pub const unsafe fn from_raw(raw: VkSamplerCreateInfo) -> Self {
113        Self(raw)
114    }
115
116    pub const fn into_raw(self) -> VkSamplerCreateInfo {
117        self.0
118    }
119
120    /// The magnification and the minification filters to apply to lookups.
121    /// Default: Magnification=`FilterMode::Linear`, Minification=`FilterMode::Linear`
122    pub const fn filter(mut self, mag: FilterMode, min: FilterMode) -> Self {
123        self.0.magFilter = mag as _;
124        self.0.minFilter = min as _;
125
126        self
127    }
128
129    /// The mipmap filter to apply to lookups.
130    /// Default: `MipmapFilterMode::Linear`
131    pub const fn mip_filter(mut self, f: MipmapFilterMode) -> Self {
132        self.0.mipmapMode = f as _;
133
134        self
135    }
136
137    /// The addressing mode for outside [0..1] range for U, V and W coordinates.
138    /// Default: U=`AddressingMode::Repeat`, V=`AddressinMode::Repeat`, W=`AddressingMode::Repeat`
139    pub const fn addressing(mut self, u: AddressingMode, v: AddressingMode, w: AddressingMode) -> Self {
140        self.0.addressModeU = u as _;
141        self.0.addressModeV = v as _;
142        self.0.addressModeW = w as _;
143
144        self
145    }
146
147    /// The bias to be added to mipmap LOD calculation and bias provided by image sampling functions in SPIR-V,
148    /// as described in the `Level-of-Detail Operation` section in Vulkan Specification.
149    /// Default: 0.0
150    pub const fn lod_bias(mut self, bias: f32) -> Self {
151        self.0.mipLodBias = bias;
152
153        self
154    }
155
156    /// The anisotropy value clamp. Specifying `None` switches off the anisotropic filtering
157    /// Default: `None`
158    pub const fn max_anisotropy(mut self, level: Option<f32>) -> Self {
159        self.0.anisotropyEnable = level.is_some() as _;
160        if let Some(l) = level {
161            self.0.maxAnisotropy = l;
162        }
163
164        self
165    }
166
167    /// The comparison function to apply to fetched data before filtering
168    /// as described in the `Depth Compare Operation` section in Vulkan Specification.
169    /// Specifying `None` switches off the comparison against a reference value during lookups.
170    /// Default: `None`
171    pub const fn comparison(mut self, op: Option<CompareOp>) -> Self {
172        self.0.compareEnable = op.is_some() as _;
173        if let Some(c) = op {
174            self.0.compareOp = c as _;
175        }
176
177        self
178    }
179
180    /// The values used to clamp the computed level-of-detail value,
181    /// as described in the `Level-of-Detail Operation` section in Vulkan Specification.
182    /// Default: min_lod=0.0, max_lod=0.0
183    /// # Panics
184    /// `max_lod` must be greater than or equal to `min_lod`
185    pub const fn lod_clamp(mut self, min_lod: f32, max_lod: f32) -> Self {
186        assert!(max_lod >= min_lod);
187        self.0.minLod = min_lod;
188        self.0.maxLod = max_lod;
189
190        self
191    }
192
193    /// Whether to use unnormalized or normalized texel coordinates to address texels of the image.
194    /// Default: `false`
195    /// # Safety
196    /// User must meet the constraints as described in the "Valid Usage" section in the `VkSamplerCreateInfo` manual page
197    pub const unsafe fn unnormalized_coordinates(mut self, use_unnormalized: bool) -> Self {
198        self.0.unnormalizedCoordinates = use_unnormalized as _;
199
200        self
201    }
202}
203
204/// Specify behavior of sampling with texture coordinates outside an image
205#[repr(C)]
206#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
207pub enum AddressingMode {
208    /// The repeat wrap mode
209    Repeat = VK_SAMPLER_ADDRESS_MODE_REPEAT as _,
210    /// The mirrored repeat wrap mode
211    MirroredRepeat = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT as _,
212    /// The clamp to edge wrap mode
213    ClampToEdge = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE as _,
214    /// The clamp to border wrap mode
215    ClampToBorder = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER as _,
216    /// The mirror clamp to edge wrap mode
217    #[cfg(feature = "VK_KHR_sampler_mirror_clamp_to_edge")]
218    MirrorClampToEdge = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE as _,
219}
220
221/// Specify filter used for texture lookups
222#[repr(C)]
223#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
224pub enum FilterMode {
225    /// Nearest filtering
226    Nearest = VK_FILTER_NEAREST as _,
227    /// Linear filtering
228    Linear = VK_FILTER_LINEAR as _,
229}
230
231/// Specify mipmap mode used for texture lookups
232#[repr(C)]
233#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
234pub enum MipmapFilterMode {
235    /// Nearest filtering
236    Nearest = VK_SAMPLER_MIPMAP_MODE_NEAREST as _,
237    /// Linear filtering
238    Linear = VK_SAMPLER_MIPMAP_MODE_LINEAR as _,
239}
240
241/// Specify border color used for texture lookups
242#[repr(C)]
243#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)]
244pub enum BorderColor {
245    /// A transparent, floating-point format, black color
246    TransparentBlackF = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK as _,
247    /// A transparent, integer format, black color
248    TransparentBlackI = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK as _,
249    /// An opaque, floating-point format, black color
250    OpaqueBlackF = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK as _,
251    /// An opaque, integer format, black color
252    OpaqueBlackI = VK_BORDER_COLOR_INT_OPAQUE_BLACK as _,
253    /// An opaque, floating-point format, white color
254    OpaqueWhiteF = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE as _,
255    /// An opaque, integer format, white color
256    OpaqueWhiteI = VK_BORDER_COLOR_INT_OPAQUE_WHITE as _,
257}