Skip to main content

ursus_core/render/gfx/descriptor/
desc.rs

1use crate::render::gfx::types::ShaderStage;
2use ash::vk;
3use std::ops::{BitOr, BitOrAssign};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum BindingKind {
7    CombinedImageSampler,
8    UniformBuffer { size: u64 },
9    StorageBuffer { size: u64 },
10    Sampler,
11    SampledImageArray,
12}
13
14#[derive(Debug, Clone, Copy)]
15pub struct DescriptorBindingDesc {
16    pub binding: u32,
17    pub kind: BindingKind,
18    pub stage: ShaderStage,
19    pub count: u32,
20    pub bindless: bool,
21    pub immutable_sampler: Option<vk::Sampler>,
22}
23
24#[derive(Debug, Clone, Default)]
25pub struct DescriptorSetDesc {
26    pub bindings: Vec<DescriptorBindingDesc>,
27}
28
29impl DescriptorSetDesc {
30    pub fn new() -> Self {
31        Self::default()
32    }
33
34    pub fn with_sampled_image(mut self, binding: u32, stage: ShaderStage) -> Self {
35        self.bindings.push(DescriptorBindingDesc {
36            binding,
37            kind: BindingKind::CombinedImageSampler,
38            stage,
39            count: 1,
40            bindless: false,
41            immutable_sampler: None,
42        });
43        self
44    }
45
46    pub fn with_uniform_buffer<T>(mut self, binding: u32, stage: ShaderStage) -> Self {
47        self.bindings.push(DescriptorBindingDesc {
48            binding,
49            kind: BindingKind::UniformBuffer { size: size_of::<T>() as u64 },
50            stage,
51            count: 1,
52            bindless: false,
53            immutable_sampler: None,
54        });
55        self
56    }
57
58    pub fn with_storage_buffer<T>(mut self, binding: u32, stage: ShaderStage) -> Self {
59        self.bindings.push(DescriptorBindingDesc {
60            binding,
61            kind: BindingKind::StorageBuffer { size: size_of::<T>() as u64 },
62            stage,
63            count: 1,
64            bindless: false,
65            immutable_sampler: None,
66        });
67        self
68    }
69
70    pub fn with_immutable_sampler(mut self, binding: u32, stage: ShaderStage, sampler: vk::Sampler) -> Self {
71        self.bindings.push(DescriptorBindingDesc {
72            binding,
73            kind: BindingKind::Sampler,
74            stage,
75            count: 1,
76            bindless: false,
77            immutable_sampler: Some(sampler),
78        });
79        self
80    }
81
82    pub fn with_bindless_sampled_images(mut self, binding: u32, stage: ShaderStage, max_count: u32) -> Self {
83        self.bindings.push(DescriptorBindingDesc {
84            binding,
85            kind: BindingKind::SampledImageArray,
86            stage,
87            count: max_count,
88            bindless: true,
89            immutable_sampler: None,
90        });
91        self
92    }
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq)]
96pub struct ImageUsage(u32);
97
98impl ImageUsage {
99    pub const COLOR_ATTACHMENT: Self = Self(1 << 0);
100    pub const DEPTH_ATTACHMENT: Self = Self(1 << 1);
101    pub const SAMPLED: Self = Self(1 << 2);
102    pub const TRANSFER_SRC: Self = Self(1 << 3);
103    pub const TRANSFER_DST: Self = Self(1 << 4);
104
105    pub const fn empty() -> Self {
106        Self(0)
107    }
108
109    pub const fn contains(self, other: Self) -> bool {
110        (self.0 & other.0) == other.0
111    }
112
113    pub(crate) fn to_vk(self) -> vk::ImageUsageFlags {
114        let mut out = vk::ImageUsageFlags::empty();
115        if self.contains(Self::COLOR_ATTACHMENT) {
116            out |= vk::ImageUsageFlags::COLOR_ATTACHMENT;
117        }
118        if self.contains(Self::DEPTH_ATTACHMENT) {
119            out |= vk::ImageUsageFlags::DEPTH_STENCIL_ATTACHMENT;
120        }
121        if self.contains(Self::SAMPLED) {
122            out |= vk::ImageUsageFlags::SAMPLED;
123        }
124        if self.contains(Self::TRANSFER_SRC) {
125            out |= vk::ImageUsageFlags::TRANSFER_SRC;
126        }
127        if self.contains(Self::TRANSFER_DST) {
128            out |= vk::ImageUsageFlags::TRANSFER_DST;
129        }
130        out
131    }
132}
133
134impl BitOr for ImageUsage {
135    type Output = Self;
136    fn bitor(self, rhs: Self) -> Self {
137        Self(self.0 | rhs.0)
138    }
139}
140
141impl BitOrAssign for ImageUsage {
142    fn bitor_assign(&mut self, rhs: Self) {
143        self.0 |= rhs.0;
144    }
145}