easy_wgpu/
bind_group_layout.rs1use core::num::NonZeroU64;
2
3#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)]
6pub struct BindGroupLayoutDesc {
7 label: Option<String>,
8 entries: Vec<wgpu::BindGroupLayoutEntry>,
9}
10impl BindGroupLayoutDesc {
11 pub fn into_bind_group_layout(self, device: &wgpu::Device) -> wgpu::BindGroupLayout {
12 let desc = wgpu::BindGroupLayoutDescriptor {
13 entries: self.entries.as_slice(),
14 label: self.label.as_deref(),
15 };
16 device.create_bind_group_layout(&desc)
17 }
18 pub fn empty() -> Self {
19 Self {
20 label: Some(String::from("emtpy_bgl")),
21 entries: Vec::new(),
22 }
23 }
24}
25
26pub struct BindGroupLayoutBuilder {
44 layout_desc: Option<BindGroupLayoutDesc>,
45 last_binding_number: u32,
46}
47impl Default for BindGroupLayoutBuilder {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52impl BindGroupLayoutBuilder {
53 pub fn new() -> Self {
54 Self {
55 layout_desc: Some(BindGroupLayoutDesc::empty()),
56 last_binding_number: 0,
57 }
58 }
59
60 #[must_use]
63 pub fn label(mut self, label: &str) -> Self {
64 self.layout_desc.as_mut().unwrap().label = Some(String::from(label));
65 self
66 }
67
68 #[must_use]
69 pub fn add_entry_empty(mut self) -> Self {
70 self.last_binding_number += 1;
71 self
72 }
73
74 #[must_use]
77 pub fn add_entry_tex(mut self, visibility: wgpu::ShaderStages, sample_type: wgpu::TextureSampleType) -> Self {
78 let binding_number = self.last_binding_number;
81 let entry = wgpu::BindGroupLayoutEntry {
83 binding: binding_number, visibility,
85 ty: wgpu::BindingType::Texture {
86 multisampled: false,
87 view_dimension: wgpu::TextureViewDimension::D2,
88 sample_type,
89 },
90 count: None,
91 };
92 self.layout_desc.as_mut().unwrap().entries.push(entry);
94 self.last_binding_number += 1;
95 self
96 }
97
98 #[must_use]
101 pub fn add_entries_tex(self, visibility: wgpu::ShaderStages, sample_type: wgpu::TextureSampleType, num_textures: usize) -> Self {
102 let mut builder = self;
103 for _i in 0..num_textures {
104 builder = builder.add_entry_tex(visibility, sample_type);
105 }
106 builder
107 }
108
109 #[must_use]
112 pub fn add_entry_cubemap(mut self, visibility: wgpu::ShaderStages, sample_type: wgpu::TextureSampleType) -> Self {
113 let binding_number = self.last_binding_number;
116 let entry = wgpu::BindGroupLayoutEntry {
118 binding: binding_number, visibility,
120 ty: wgpu::BindingType::Texture {
121 multisampled: false,
122 view_dimension: wgpu::TextureViewDimension::Cube,
123 sample_type,
124 },
125 count: None,
126 };
127 self.layout_desc.as_mut().unwrap().entries.push(entry);
129 self.last_binding_number += 1;
130 self
131 }
132
133 #[must_use]
136 pub fn add_entry_sampler(mut self, visibility: wgpu::ShaderStages, sampler_type: wgpu::SamplerBindingType) -> Self {
137 let binding_number = self.last_binding_number;
140 let entry = wgpu::BindGroupLayoutEntry {
142 binding: binding_number, visibility,
144 ty: wgpu::BindingType::Sampler(sampler_type),
145 count: None,
146 };
147 self.layout_desc.as_mut().unwrap().entries.push(entry);
149 self.last_binding_number += 1;
150 self
151 }
152
153 #[must_use]
156 pub fn add_entry_uniform(mut self, visibility: wgpu::ShaderStages, has_dynamic_offset: bool, _min_binding_size: Option<NonZeroU64>) -> Self {
157 let binding_number = self.last_binding_number;
160 let entry = wgpu::BindGroupLayoutEntry {
167 binding: binding_number, visibility,
169 ty: wgpu::BindingType::Buffer {
170 ty: wgpu::BufferBindingType::Uniform,
171 has_dynamic_offset, min_binding_size: None,
174 },
175 count: None,
176 };
177 self.layout_desc.as_mut().unwrap().entries.push(entry);
179 self.last_binding_number += 1;
180 self
181 }
182
183 pub fn build(&mut self) -> BindGroupLayoutDesc {
186 self.layout_desc.take().unwrap()
187 }
188}