ursus_core/render/gfx/sampler/
desc.rs1use ash::vk;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
4pub enum Filter {
5 Nearest,
6 Linear,
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum AddressMode {
11 ClampToEdge,
12 ClampToBorderOpaqueWhite,
13}
14
15#[derive(Debug, Clone, Copy)]
16pub struct SamplerDesc {
17 pub filter: Filter,
18 pub address_mode: AddressMode,
19 pub compare_less_or_equal: bool,
20}
21
22impl SamplerDesc {
23 pub fn linear_clamp() -> Self {
24 Self { filter: Filter::Linear, address_mode: AddressMode::ClampToEdge, compare_less_or_equal: false }
25 }
26 pub fn nearest_clamp() -> Self {
27 Self { filter: Filter::Nearest, address_mode: AddressMode::ClampToEdge, compare_less_or_equal: false }
28 }
29 pub fn shadow_compare() -> Self {
30 Self {
31 filter: Filter::Linear,
32 address_mode: AddressMode::ClampToBorderOpaqueWhite,
33 compare_less_or_equal: true,
34 }
35 }
36}
37
38pub fn create_from_desc(device: &ash::Device, desc: SamplerDesc) -> anyhow::Result<vk::Sampler> {
39 let filter = match desc.filter {
40 Filter::Nearest => vk::Filter::NEAREST,
41 Filter::Linear => vk::Filter::LINEAR,
42 };
43 let address_mode = match desc.address_mode {
44 AddressMode::ClampToEdge => vk::SamplerAddressMode::CLAMP_TO_EDGE,
45 AddressMode::ClampToBorderOpaqueWhite => vk::SamplerAddressMode::CLAMP_TO_BORDER,
46 };
47
48 let mut info = vk::SamplerCreateInfo::default()
49 .mag_filter(filter)
50 .min_filter(filter)
51 .address_mode_u(address_mode)
52 .address_mode_v(address_mode);
53
54 if matches!(desc.address_mode, AddressMode::ClampToBorderOpaqueWhite) {
55 info = info.border_color(vk::BorderColor::FLOAT_OPAQUE_WHITE);
56 }
57
58 if desc.compare_less_or_equal {
59 info = info.compare_enable(true).compare_op(vk::CompareOp::LESS_OR_EQUAL);
60 }
61
62 Ok(unsafe { device.create_sampler(&info, None)? })
63}