ursus_core/render/gfx/descriptor/
desc.rs1use 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}