1
2use crate::prelude::*;
3use std::{
4 any::Any,
5 collections::{BTreeMap, BTreeSet, HashMap, HashSet, hash_map::Entry},
6 fmt::{self, Debug, Formatter},
7 ptr::null,
8 sync::Arc,
9};
10use shader_analyzer::*;
11use rspirv::spirv::*;
12
13pub trait VertexType: Copy + Clone + Sized + Default + Debug + FFIStruct + Any {}
15impl<T> VertexType for T where T: Copy + Clone + Sized + Default + Debug + FFIStruct + Any {}
16
17#[macro_export]
18macro_rules! derive_vertex_type {
19 ($item: item) => {
20 #[ffi_struct]
21 #[derive(Default, Debug, Clone, Copy)]
22 #[size_of_type (Vec1 = 4, Vec2 = 8, Vec3 = 12, Vec4 = 16)]
23 #[align_of_type(Vec1 = 4, Vec2 = 4, Vec3 = 4, Vec4 = 4)]
24 #[size_of_type (Mat1 = 4, Mat2 = 16, Mat3 = 36, Mat4 = 64)]
25 #[align_of_type(Mat1 = 4, Mat2 = 4, Mat3 = 4, Mat4 = 4)]
26 #[size_of_type (Mat1x1 = 4, Mat2x2 = 16, Mat3x3 = 36, Mat4x4 = 64)]
27 #[align_of_type(Mat1x1 = 4, Mat2x2 = 4, Mat3x3 = 4, Mat4x4 = 4)]
28 #[size_of_type (Mat1x2 = 8, Mat1x3 = 12, Mat1x4 = 16)]
29 #[align_of_type(Mat1x2 = 4, Mat1x3 = 4, Mat1x4 = 4)]
30 #[size_of_type (Mat2x1 = 8, Mat2x3 = 24, Mat2x4 = 32)]
31 #[align_of_type(Mat2x1 = 4, Mat2x3 = 4, Mat2x4 = 4)]
32 #[size_of_type (Mat2x3 = 24, Mat2x4 = 32)]
33 #[align_of_type(Mat2x3 = 4, Mat2x4 = 4)]
34 #[size_of_type (Mat3x2 = 24, Mat3x4 = 48)]
35 #[align_of_type(Mat3x2 = 4, Mat3x4 = 4)]
36 #[size_of_type (Mat4x2 = 32, Mat4x3 = 48)]
37 #[align_of_type(Mat4x2 = 4, Mat4x3 = 4)]
38 #[size_of_type (DVec1 = 8, DVec2 = 16, DVec3 = 24, DVec4 = 32)]
39 #[align_of_type(DVec1 = 4, DVec2 = 4, DVec3 = 4, DVec4 = 4)]
40 #[size_of_type (DMat1 = 8, DMat2 = 32, DMat3 = 72, DMat4 = 128)]
41 #[align_of_type(DMat1 = 4, DMat2 = 4, DMat3 = 4, DMat4 = 4)]
42 #[size_of_type (DMat1x1 = 8, DMat2x2 = 32, DMat3x3 = 72, DMat4x4 = 128)]
43 #[align_of_type(DMat1x1 = 4, DMat2x2 = 4, DMat3x3 = 4, DMat4x4 = 4)]
44 #[size_of_type (DMat1x2 = 16, DMat1x3 = 24, DMat1x4 = 32)]
45 #[align_of_type(DMat1x2 = 4, DMat1x3 = 4, DMat1x4 = 4)]
46 #[size_of_type (DMat2x1 = 16, DMat2x3 = 48, DMat2x4 = 64)]
47 #[align_of_type(DMat2x1 = 4, DMat2x3 = 4, DMat2x4 = 4)]
48 #[size_of_type (DMat2x3 = 48, DMat2x4 = 64)]
49 #[align_of_type(DMat2x3 = 4, DMat2x4 = 4)]
50 #[size_of_type (DMat3x2 = 48, DMat3x4 = 96)]
51 #[align_of_type(DMat3x2 = 4, DMat3x4 = 4)]
52 #[size_of_type (DMat4x2 = 64, DMat4x3 = 96)]
53 #[align_of_type(DMat4x2 = 4, DMat4x3 = 4)]
54 #[size_of_type (bool = 4)]
55 #[align_of_type(bool = 4)]
56 $item
57 };
58}
59
60#[derive(Debug)]
62pub struct DescriptorSetLayout {
63 pub device: Arc<VulkanDevice>,
65
66 pub(crate) descriptor_set_layout: VkDescriptorSetLayout,
68}
69
70impl DescriptorSetLayout {
71 pub fn new(device: Arc<VulkanDevice>, layout_ci: &VkDescriptorSetLayoutCreateInfo) -> Result<Self, VulkanError> {
73 let mut descriptor_set_layout = null();
74 device.vkcore.vkCreateDescriptorSetLayout(device.get_vk_device(), layout_ci, null(), &mut descriptor_set_layout)?;
75 Ok(Self {
76 device,
77 descriptor_set_layout,
78 })
79 }
80}
81
82impl Drop for DescriptorSetLayout {
83 fn drop(&mut self) {
84 proceed_run(self.device.vkcore.vkDestroyDescriptorSetLayout(self.device.get_vk_device(), self.descriptor_set_layout, null()));
85 }
86}
87
88pub(crate) fn through_array<'a>(array_info: &'a ArrayType, dimensions: &mut Vec<usize>) -> &'a VariableType {
91 dimensions.push(array_info.element_count);
92 if let VariableType::Array(sub_array_info) = &array_info.element_type {
93 through_array(sub_array_info, dimensions)
94 } else {
95 &array_info.element_type
96 }
97}
98
99pub(crate) fn dig_array(array_info: &ArrayType) -> (usize, &VariableType) {
102 let mut dimensions = Vec::new();
103 let var_type = through_array(array_info, &mut dimensions);
104 let mut total = 1;
105 for dim in dimensions.iter() {
106 total *= dim;
107 }
108 (total, var_type)
109}
110
111pub struct DescriptorSets {
113 pub device: Arc<VulkanDevice>,
115
116 pub desc_props: Arc<DescriptorProps>,
118
119 pub desc_pool: Arc<DescriptorPool>,
121
122 descriptor_set_layouts: BTreeMap<u32 , DescriptorSetLayout>,
124
125 descriptor_sets: BTreeMap<u32 , VkDescriptorSet>,
127
128 pub shaders: Arc<DrawShaders>,
130}
131
132#[derive(Debug, Clone)]
135pub struct WriteDescriptorSets {
136 pub write_descriptor_sets: Vec<VkWriteDescriptorSet>,
137 pub buffer_info: Vec<VkDescriptorBufferInfo>,
138 pub image_info: Vec<VkDescriptorImageInfo>,
139 pub texel_buffer_views: Vec<VkBufferView>,
140}
141
142impl WriteDescriptorSets {
143 pub(crate) fn new() -> Self {
145 Self {
146 write_descriptor_sets: Vec::new(),
147 buffer_info: Vec::new(),
148 image_info: Vec::new(),
149 texel_buffer_views: Vec::new(),
150 }
151 }
152
153 fn pass(&mut self, descriptor_sets: &DescriptorSets, shaders: &DrawShaders, pass_for_cap: bool) -> Result<bool, VulkanError> {
155 self.buffer_info.clear();
156 self.image_info.clear();
157 self.texel_buffer_views.clear();
158 self.write_descriptor_sets.clear();
159 let mut num_buffer_info = 0;
160 let mut num_image_info = 0;
161 let mut num_texel_buffer_views = 0;
162 let mut num_wds = 0;
163 let buffer_info_ptr = self.buffer_info.as_ptr();
164 let image_info_ptr = self.image_info.as_ptr();
165 let texel_buffer_views_ptr = self.texel_buffer_views.as_ptr();
166 let mut processed_vars = HashSet::new();
167 let desc_props = descriptor_sets.desc_props.clone();
168 for (_, shader) in shaders.iter_shaders() {
169 for var in shader.get_vars() {
170 if let VariableLayout::Descriptor{set, binding, input_attachment_index: iai} = var.layout {
171 let var_ident = format!("{set}_{binding}_{iai:?}_\"{}\"", var.var_name);
172 if processed_vars.contains(&var_ident) {
173 continue;
174 } else {
175 processed_vars.insert(var_ident);
176 }
177 let mut dimensions = Vec::new();
178 let (total_element_count, var_type) = match &var.var_type {
179 VariableType::Array(array_info) => {
180 let var_type = through_array(array_info, &mut dimensions);
181 let mut total = 1;
182 for dim in dimensions.iter() {
183 total *= dim;
184 }
185 (total, var_type)
186 },
187 _ => (1, &var.var_type),
188 };
189 match var.storage_class {
190 StorageClass::Uniform => {
191 if pass_for_cap {
192 match var_type {
193 VariableType::Struct(_) => {
194 num_buffer_info += total_element_count;
195 num_wds += 1;
196 }
197 VariableType::Image(_) => {
198 num_texel_buffer_views += total_element_count;
199 num_wds += 1;
200 }
201 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform {}: {others:?}", var.var_name))),
202 }
203 } else {
204 match var_type {
205 VariableType::Struct(s) => {
206 let buffers: Vec<_> = desc_props.get_desc_props_uniform_buffers(set, binding, total_element_count)?;
207 let buffer_info_index = self.buffer_info.len();
208 for buffer in buffers.iter() {
209 let struct_data: HashMap<&str, (usize, usize)> = buffer.iter_members().map(|(name, member_info)|(name, (member_info.offset, member_info.size))).collect();
210 for member in s.members.iter() {
211 let name: &str = &member.member_name;
212 if let Some((offset, size)) = struct_data.get(&name) {
213 let var_size = member.member_type.size_of()?;
214 let var_offset = member.member_offset as usize;
215 if *offset != var_offset || *size != var_size {
216 eprintln!("For descriptor set: {set}, binding: {binding}: Uniform buffer struct member `{name}` has offset = {offset} in Rust while {var_offset} in shader input; and has size = {size} in Rust while {var_size} in shader input");
217 }
218 }
219 }
220 self.buffer_info.push(VkDescriptorBufferInfo {
221 buffer: buffer.get_vk_buffer(),
222 offset: 0,
223 range: buffer.get_size(),
224 });
225 }
226 self.write_descriptor_sets.push(VkWriteDescriptorSet {
227 sType: VkStructureType::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
228 pNext: null(),
229 dstSet: *descriptor_sets.get(&set).unwrap(),
230 dstBinding: binding,
231 dstArrayElement: 0,
232 descriptorCount: total_element_count as u32,
233 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
234 pImageInfo: null(),
235 pBufferInfo: &self.buffer_info[buffer_info_index],
236 pTexelBufferView: null(),
237 });
238 }
239 VariableType::Image(_) => {
240 let buffers: Vec<_> = desc_props.get_desc_props_uniform_texel_buffers(set, binding, total_element_count)?;
241 let texel_buffer_views_index = self.texel_buffer_views.len();
242 for buffer in buffers.iter() {
243 self.texel_buffer_views.push(buffer.get_vk_buffer_view());
244 }
245 self.write_descriptor_sets.push(VkWriteDescriptorSet {
246 sType: VkStructureType::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
247 pNext: null(),
248 dstSet: *descriptor_sets.get(&set).unwrap(),
249 dstBinding: binding,
250 dstArrayElement: 0,
251 descriptorCount: total_element_count as u32,
252 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
253 pImageInfo: null(),
254 pBufferInfo: null(),
255 pTexelBufferView: &self.texel_buffer_views[texel_buffer_views_index],
256 });
257 }
258 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform {}: {others:?}", var.var_name))),
259 }
260 }
261 }
262 StorageClass::StorageBuffer => {
263 if pass_for_cap {
264 match var_type {
265 VariableType::Struct(_) => {
266 num_buffer_info += total_element_count;
267 num_wds += 1;
268 }
269 VariableType::Image(_) => {
270 num_texel_buffer_views += total_element_count;
271 num_wds += 1;
272 }
273 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of storage buffer {}: {others:?}", var.var_name))),
274 }
275 } else {
276 match var_type {
277 VariableType::Struct(s) => {
278 let buffers: Vec<_> = desc_props.get_desc_props_storage_buffers(set, binding, total_element_count)?;
279 let buffer_info_index = self.buffer_info.len();
280 for buffer in buffers.iter() {
281 let struct_data: HashMap<&str, (usize, usize)> = buffer.iter_members().map(|(name, member_info)|(name, (member_info.offset, member_info.size))).collect();
282 for member in s.members.iter() {
283 let name: &str = &member.member_name;
284 if let Some((offset, size)) = struct_data.get(&name) {
285 let var_size = member.member_type.size_of()?;
286 let var_offset = member.member_offset as usize;
287 if *offset != var_offset || *size != var_size {
288 eprintln!("For descriptor set: {set}, binding: {binding}: Storage buffer struct member `{name}` has offset = {offset} in Rust while {var_offset} in shader input; and has size = {size} in Rust while {var_size} in shader input");
289 }
290 }
291 }
292 self.buffer_info.push(VkDescriptorBufferInfo {
293 buffer: buffer.get_vk_buffer(),
294 offset: 0,
295 range: buffer.get_size(),
296 });
297 }
298 self.write_descriptor_sets.push(VkWriteDescriptorSet {
299 sType: VkStructureType::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
300 pNext: null(),
301 dstSet: *descriptor_sets.get(&set).unwrap(),
302 dstBinding: binding,
303 dstArrayElement: 0,
304 descriptorCount: total_element_count as u32,
305 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
306 pImageInfo: null(),
307 pBufferInfo: &self.buffer_info[buffer_info_index],
308 pTexelBufferView: null(),
309 });
310 }
311 VariableType::Image(_) => {
312 let buffers: Vec<_> = desc_props.get_desc_props_storage_texel_buffers(set, binding, total_element_count)?;
313 let texel_buffer_views_index = self.texel_buffer_views.len();
314 for buffer in buffers.iter() {
315 self.texel_buffer_views.push(buffer.get_vk_buffer_view());
316 }
317 self.write_descriptor_sets.push(VkWriteDescriptorSet {
318 sType: VkStructureType::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
319 pNext: null(),
320 dstSet: *descriptor_sets.get(&set).unwrap(),
321 dstBinding: binding,
322 dstArrayElement: 0,
323 descriptorCount: total_element_count as u32,
324 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
325 pImageInfo: null(),
326 pBufferInfo: null(),
327 pTexelBufferView: &self.texel_buffer_views[texel_buffer_views_index],
328 });
329 }
330 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of storage buffer {}: {others:?}", var.var_name))),
331 }
332 }
333 }
334 StorageClass::UniformConstant => {
335 match var_type {
336 VariableType::Literal(literal_type) => {
337 if literal_type == "sampler" {
338 if pass_for_cap {
339 num_image_info += total_element_count;
340 num_wds += 1;
341 }
342 else {
343 let samplers: Vec<VkSampler> = desc_props.get_desc_props_samplers(set, binding, total_element_count)?.iter().map(|s|s.get_vk_sampler()).collect();
344 let image_info_index = self.image_info.len();
345 for sampler in samplers.iter() {
346 self.image_info.push(VkDescriptorImageInfo {
347 sampler: *sampler,
348 imageView: null(),
349 imageLayout: VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED,
350 });
351 }
352 self.write_descriptor_sets.push(VkWriteDescriptorSet {
353 sType: VkStructureType::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
354 pNext: null(),
355 dstSet: *descriptor_sets.get(&set).unwrap(),
356 dstBinding: binding,
357 dstArrayElement: 0,
358 descriptorCount: total_element_count as u32,
359 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_SAMPLER,
360 pImageInfo: &self.image_info[image_info_index],
361 pBufferInfo: null(),
362 pTexelBufferView: null(),
363 });
364 }
365 } else {
366 return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform constant input {literal_type}.")));
367 }
368 }
369 VariableType::Image(_) => {
370 if pass_for_cap {
371 num_image_info += total_element_count;
372 num_wds += 1;
373 } else {
374 let textures: Vec<TextureForSample> = desc_props.get_desc_props_textures(set, binding, total_element_count)?;
375 let image_info_index = self.image_info.len();
376 for texture in textures.iter() {
377 self.image_info.push(VkDescriptorImageInfo {
378 sampler: texture.sampler.get_vk_sampler(),
379 imageView: texture.texture.get_vk_image_view(),
380 imageLayout: VkImageLayout::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
381 });
382 }
383 self.write_descriptor_sets.push(VkWriteDescriptorSet {
384 sType: VkStructureType::VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
385 pNext: null(),
386 dstSet: *descriptor_sets.get(&set).unwrap(),
387 dstBinding: binding,
388 dstArrayElement: 0,
389 descriptorCount: total_element_count as u32,
390 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
391 pImageInfo: &self.image_info[image_info_index],
392 pBufferInfo: null(),
393 pTexelBufferView: null(),
394 });
395 }
396 }
397 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform constant {}: {others:?}", var.var_name))),
398 }
399 }
400 _ => {}
402 }
403 }
404 }
405 }
406 if pass_for_cap {
407 self.buffer_info.reserve(num_buffer_info);
408 self.image_info.reserve(num_image_info);
409 self.texel_buffer_views.reserve(num_texel_buffer_views);
410 self.write_descriptor_sets.reserve(num_wds);
411 }
412 if buffer_info_ptr != self.buffer_info.as_ptr() ||
413 image_info_ptr != self.image_info.as_ptr() ||
414 texel_buffer_views_ptr != self.texel_buffer_views.as_ptr() {
415 Ok(false)
416 } else {
417 Ok(true)
418 }
419 }
420
421 pub fn build(device: Arc<VulkanDevice>, descriptor_sets: &DescriptorSets, shaders: &DrawShaders) -> Result<(), VulkanError> {
423 let mut ret = Self::new();
424 ret.pass(descriptor_sets, shaders, true)?;
425 assert!(ret.pass(descriptor_sets, shaders, false)?, "The vector pointer changed while pushing data into it, but its capacity should be enough not to trigger the internal memory reallocation. Redesign of the code is needed.");
426 if !ret.write_descriptor_sets.is_empty() {
427 device.vkcore.vkUpdateDescriptorSets(device.get_vk_device(), ret.write_descriptor_sets.len() as u32, ret.write_descriptor_sets.as_ptr(), 0, null())?;
428 }
429 Ok(())
430 }
431}
432
433impl DescriptorSets {
434 pub fn new(device: Arc<VulkanDevice>, desc_pool: Arc<DescriptorPool>, shaders: Arc<DrawShaders>, desc_props: Arc<DescriptorProps>) -> Result<Self, VulkanError> {
436 let mut samplers: HashMap<u32 , HashMap<u32 , Vec<VkSampler>>> = HashMap::new();
437 let mut layout_bindings: HashMap<u32 , HashMap<u32 , VkDescriptorSetLayoutBinding>> = HashMap::new();
438 for (shader_stage, shader) in shaders.iter_shaders() {
439 let shader_stage = shader_stage as VkShaderStageFlags;
440 for var in shader.get_vars() {
441 if let VariableLayout::Descriptor{set, binding, input_attachment_index: _} = var.layout {
442 let (total_element_count, var_type) = match &var.var_type {
443 VariableType::Array(array_info) => dig_array(array_info),
444 others => (1, others),
445 };
446 match var.storage_class {
447 StorageClass::UniformConstant => match var_type {
448 VariableType::Literal(literal_type) => {
449 if literal_type == "sampler" {
450 let samplers = Self::get_samplers_from_map(&mut samplers, set, binding, || Ok(desc_props.get_desc_props_samplers(set, binding, total_element_count)?.iter().map(|s|s.get_vk_sampler()).collect()))?;
451 Self::update_desc_set_layout_binding(&mut layout_bindings, set, binding, VkDescriptorSetLayoutBinding {
452 binding,
453 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_SAMPLER,
454 descriptorCount: total_element_count as u32,
455 stageFlags: shader_stage,
456 pImmutableSamplers: samplers.as_ptr(),
457 })?;
458 } else {
459 return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform constant {}: {var_type:?}", var.var_name)));
460 }
461 }
462 VariableType::Image(_) => {
463 let samplers = Self::get_samplers_from_map(&mut samplers, set, binding, || Ok(desc_props.get_desc_props_textures(set, binding, total_element_count)?.iter().map(|t|t.sampler.get_vk_sampler()).collect()))?;
464 Self::update_desc_set_layout_binding(&mut layout_bindings, set, binding, VkDescriptorSetLayoutBinding {
465 binding,
466 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
467 descriptorCount: total_element_count as u32,
468 stageFlags: shader_stage,
469 pImmutableSamplers: samplers.as_ptr(),
470 })?;
471 }
472 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform constant {}: {others:?}", var.var_name))),
473 }
474 StorageClass::Uniform => match var_type {
475 VariableType::Struct(_) => {
476 Self::update_desc_set_layout_binding(&mut layout_bindings, set, binding, VkDescriptorSetLayoutBinding {
477 binding,
478 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
479 descriptorCount: total_element_count as u32,
480 stageFlags: shader_stage,
481 pImmutableSamplers: null(),
482 })?;
483 }
484 VariableType::Image(_) => {
485 Self::update_desc_set_layout_binding(&mut layout_bindings, set, binding, VkDescriptorSetLayoutBinding {
486 binding,
487 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,
488 descriptorCount: total_element_count as u32,
489 stageFlags: shader_stage,
490 pImmutableSamplers: null(),
491 })?;
492 }
493 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of uniform {}: {others:?}", var.var_name))),
494 }
495 StorageClass::StorageBuffer => match var_type {
496 VariableType::Struct(_) => {
497 Self::update_desc_set_layout_binding(&mut layout_bindings, set, binding, VkDescriptorSetLayoutBinding {
498 binding,
499 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
500 descriptorCount: total_element_count as u32,
501 stageFlags: shader_stage,
502 pImmutableSamplers: null(),
503 })?;
504 }
505 VariableType::Image(_) => {
506 Self::update_desc_set_layout_binding(&mut layout_bindings, set, binding, VkDescriptorSetLayoutBinding {
507 binding,
508 descriptorType: VkDescriptorType::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER,
509 descriptorCount: total_element_count as u32,
510 stageFlags: shader_stage,
511 pImmutableSamplers: null(),
512 })?;
513 }
514 others => return Err(VulkanError::ShaderInputTypeUnsupported(format!("Unknown type of storage buffer {}: {others:?}", var.var_name))),
515 }
516 _ => {}
518 }
519 }
520 }
521 }
522 let mut bindings_of_set: BTreeMap<u32 , Vec<VkDescriptorSetLayoutBinding>> = BTreeMap::new();
523 for (set, bindings) in layout_bindings.iter() {
524 for (_, binding_val) in bindings.iter() {
525 let array = if let Some(array) = bindings_of_set.get_mut(set) {
526 array
527 } else {
528 bindings_of_set.insert(*set, Vec::new());
529 bindings_of_set.get_mut(set).unwrap()
530 };
531 array.push(*binding_val);
532 }
533 }
534 let mut descriptor_set_layouts: BTreeMap<u32 , DescriptorSetLayout> = BTreeMap::new();
535 for (set, dslb) in bindings_of_set.iter() {
536 let layout_ci = VkDescriptorSetLayoutCreateInfo {
537 sType: VkStructureType::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
538 pNext: null(),
539 flags: 0,
540 bindingCount: dslb.len() as u32,
541 pBindings: dslb.as_ptr(),
542 };
543 descriptor_set_layouts.insert(*set, DescriptorSetLayout::new(device.clone(), &layout_ci)?);
544 }
545 let layout_array: Vec<VkDescriptorSetLayout> = descriptor_set_layouts.values().map(|v|v.descriptor_set_layout).collect();
546 if layout_array.is_empty() {
547 Ok(Self {
548 device,
549 desc_props,
550 desc_pool,
551 descriptor_set_layouts,
552 descriptor_sets: BTreeMap::new(),
553 shaders,
554 })
555 } else {
556 let desc_sets_ai = VkDescriptorSetAllocateInfo {
557 sType: VkStructureType::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
558 pNext: null(),
559 descriptorPool: desc_pool.get_vk_pool(),
560 descriptorSetCount: layout_array.len() as u32,
561 pSetLayouts: layout_array.as_ptr(),
562 };
563 let mut descriptor_set_array: Vec<VkDescriptorSet> = Vec::with_capacity(layout_array.len());
564 device.vkcore.vkAllocateDescriptorSets(device.get_vk_device(), &desc_sets_ai, descriptor_set_array.as_mut_ptr())?;
565 unsafe {descriptor_set_array.set_len(layout_array.len())};
566 let descriptor_sets: BTreeMap<u32, VkDescriptorSet> = layout_bindings.keys().enumerate().map(|(index, set)|(*set, descriptor_set_array[index])).collect();
567 let ret = Self {
568 device: device.clone(),
569 desc_props,
570 desc_pool,
571 descriptor_set_layouts,
572 descriptor_sets,
573 shaders: shaders.clone(),
574 };
575 WriteDescriptorSets::build(device, &ret, &shaders)?;
576 Ok(ret)
577 }
578 }
579
580 pub fn get_descriptor_sets(&self) -> &BTreeMap<u32, VkDescriptorSet> {
582 &self.descriptor_sets
583 }
584
585 pub fn get_descriptor_set_layouts(&self) -> &BTreeMap<u32, DescriptorSetLayout> {
587 &self.descriptor_set_layouts
588 }
589
590 pub fn get(&self, set_number: &u32) -> Option<&VkDescriptorSet> {
592 self.descriptor_sets.get(set_number)
593 }
594
595 fn update_desc_set_layout_binding(map: &mut HashMap<u32, HashMap<u32, VkDescriptorSetLayoutBinding>>, set: u32, binding: u32, mut item: VkDescriptorSetLayoutBinding) -> Result<(), VulkanError> {
597 if let Some(bindings) = map.get_mut(&set) {
598 if let Some(existing) = bindings.get_mut(&binding) {
599 let prev_stage = vk_shader_stage_flags_to_string(existing.stageFlags);
600 let curr_stage = vk_shader_stage_flags_to_string(item.stageFlags);
601 if existing.descriptorType != item.descriptorType {
602 let prev_type = existing.descriptorType;
603 let curr_type = item.descriptorType;
604 Err(VulkanError::ShaderInputTypeMismatch(format!("In `layout(set = {set}, binding = {binding})`: descriptor type mismatch: one at `{prev_stage}` is `{prev_type:?}`, another at `{curr_stage}` is `{curr_type:?}`")))
605 } else if existing.descriptorCount != item.descriptorCount {
606 let prev_count = existing.descriptorCount;
607 let curr_count = item.descriptorCount;
608 Err(VulkanError::ShaderInputTypeMismatch(format!("In `layout(set = {set}, binding = {binding})`: descriptor count mismatch: one at `{prev_stage}` is `{prev_count}`, another at `{curr_stage}` is `{curr_count}`")))
609 } else if existing.pImmutableSamplers != item.pImmutableSamplers {
610 let prev_samplers = existing.pImmutableSamplers;
611 let curr_samplers = item.pImmutableSamplers;
612 Err(VulkanError::ShaderInputTypeMismatch(format!("In `layout(set = {set}, binding = {binding})`: descriptor samplers mismatch: one at `{prev_stage}` is `{prev_samplers:?}`, another at `{curr_stage}` is `{curr_samplers:?}`")))
613 } else {
614 existing.stageFlags |= item.stageFlags;
615 Ok(())
616 }
617 } else {
618 item.binding = binding;
619 bindings.insert(binding, item);
620 Ok(())
621 }
622 } else {
623 item.binding = binding;
624 map.insert(set, [(binding, item)].into_iter().collect());
625 Ok(())
626 }
627 }
628
629 fn get_samplers_from_map(map: &mut HashMap<u32, HashMap<u32, Vec<VkSampler>>>, set: u32, binding: u32, on_create: impl FnOnce() -> Result<Vec<VkSampler>, VulkanError>) -> Result<&[VkSampler], VulkanError> {
631 if let Entry::Vacant(e) = map.entry(set) {
632 e.insert(HashMap::new());
633 }
634 let bindings = map.get_mut(&set).unwrap();
635 if let Entry::Vacant(e) = bindings.entry(binding) {
636 e.insert(on_create()?);
637 }
638 Ok(bindings.get(&binding).unwrap())
639 }
640}
641
642impl Clone for DescriptorSets {
643 fn clone(&self) -> Self {
644 Self::new(self.device.clone(), self.desc_pool.clone(), self.shaders.clone(), self.desc_props.clone()).unwrap()
645 }
646}
647
648impl Drop for DescriptorSets {
649 fn drop(&mut self) {
650 let descriptor_set_array: Vec<VkDescriptorSet> = self.descriptor_sets.values().copied().collect();
651 if !descriptor_set_array.is_empty() {
652 proceed_run(self.device.vkcore.vkFreeDescriptorSets(self.device.get_vk_device(), self.desc_pool.get_vk_pool(), descriptor_set_array.len() as u32, descriptor_set_array.as_ptr()));
653 }
654 }
655}
656
657impl Debug for DescriptorSets {
658 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
659 f.debug_struct("DescriptorSets")
660 .field("desc_props", &self.desc_props)
661 .field("desc_pool", &self.desc_pool)
662 .field("descriptor_set_layouts", &self.descriptor_set_layouts)
663 .field("descriptor_sets", &self.descriptor_sets)
664 .field("shaders", &self.shaders)
665 .finish()
666 }
667}
668
669unsafe impl Send for DescriptorSets {}
670unsafe impl Sync for DescriptorSets {}
671
672#[derive(Clone)]
674pub struct PipelineBuilder {
675 pub device: Arc<VulkanDevice>,
677
678 pub mesh: Arc<GenericMeshWithMaterial>,
680
681 pub shaders: Arc<DrawShaders>,
683
684 pub descriptor_sets: Arc<DescriptorSets>,
686
687 pub renderpass: Arc<VulkanRenderPass>,
689
690 pub pipeline_cache: Arc<VulkanPipelineCache>,
692
693 pub rasterization_state_ci: VkPipelineRasterizationStateCreateInfo,
695
696 pub msaa_state_ci: VkPipelineMultisampleStateCreateInfo,
698
699 pub depth_stenctil_ci: VkPipelineDepthStencilStateCreateInfo,
701
702 pub color_blend_state_ci: VkPipelineColorBlendStateCreateInfo,
704
705 pub color_blend_attachment_states: Vec<VkPipelineColorBlendAttachmentState>,
707
708 pub dynamic_states: HashSet<VkDynamicState>,
710
711 pipeline_layout: VkPipelineLayout,
713}
714
715impl PipelineBuilder {
716 pub fn new(device: Arc<VulkanDevice>, mesh: Arc<GenericMeshWithMaterial>, shaders: Arc<DrawShaders>, desc_pool: Arc<DescriptorPool>, desc_props: Arc<DescriptorProps>, renderpass: Arc<VulkanRenderPass>, pipeline_cache: Arc<VulkanPipelineCache>) -> Result<Self, VulkanError> {
718 let descriptor_sets = Arc::new(DescriptorSets::new(device.clone(), desc_pool.clone(), shaders.clone(), desc_props.clone())?);
719 let mut desc_set_layouts: Vec<VkDescriptorSetLayout> = Vec::with_capacity(5);
720 let mut push_constant_ranges: Vec<VkPushConstantRange> = Vec::with_capacity(5);
721 for dsl in descriptor_sets.get_descriptor_set_layouts().values() {
722 desc_set_layouts.push(dsl.descriptor_set_layout);
723 }
724 for (stage, shader) in shaders.iter_shaders() {
725 for var in shader.get_vars() {
726 if StorageClass::PushConstant != var.storage_class {
727 continue;
728 }
729 match &var.var_type {
730 VariableType::Struct(st) => {
731 for member in st.members.iter() {
732 let size = (((member.size_of()? - 1) / 4 + 1) * 4) as u32;
733 push_constant_ranges.push(VkPushConstantRange {
734 stageFlags: stage as VkShaderStageFlags,
735 offset: member.member_offset,
736 size,
737 });
738 }
739 }
740 _ => {
741 let size = (((var.size_of()? - 1) / 4 + 1) * 4) as u32;
742 push_constant_ranges.push(VkPushConstantRange {
743 stageFlags: stage as VkShaderStageFlags,
744 offset: 0,
745 size,
746 });
747 }
748 }
749 }
750 }
751 let rasterization_state_ci = VkPipelineRasterizationStateCreateInfo {
752 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
753 pNext: null(),
754 flags: 0,
755 depthClampEnable: 0,
756 rasterizerDiscardEnable: 0,
757 polygonMode: VkPolygonMode::VK_POLYGON_MODE_FILL,
758 cullMode: VkCullModeFlagBits::VK_CULL_MODE_BACK_BIT as VkCullModeFlags,
759 frontFace: VkFrontFace::VK_FRONT_FACE_COUNTER_CLOCKWISE,
760 depthBiasEnable: 0,
761 depthBiasConstantFactor: 0.0,
762 depthBiasClamp: 0.0,
763 depthBiasSlopeFactor: 1.0,
764 lineWidth: 1.0,
765 };
766 let msaa_state_ci = VkPipelineMultisampleStateCreateInfo {
767 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
768 pNext: null(),
769 flags: 0,
770 rasterizationSamples: VkSampleCountFlagBits::VK_SAMPLE_COUNT_1_BIT,
771 sampleShadingEnable: 0,
772 minSampleShading: 0.0,
773 pSampleMask: null(),
774 alphaToCoverageEnable: 0,
775 alphaToOneEnable: 0,
776 };
777 let depth_stenctil_ci = VkPipelineDepthStencilStateCreateInfo {
778 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
779 pNext: null(),
780 flags: 0,
781 depthTestEnable: 1,
782 depthWriteEnable: 1,
783 depthCompareOp: VkCompareOp::VK_COMPARE_OP_LESS_OR_EQUAL,
784 depthBoundsTestEnable: 0,
785 stencilTestEnable: 0,
786 front: VkStencilOpState {
787 failOp: VkStencilOp::VK_STENCIL_OP_KEEP,
788 passOp: VkStencilOp::VK_STENCIL_OP_KEEP,
789 depthFailOp: VkStencilOp::VK_STENCIL_OP_KEEP,
790 compareOp: VkCompareOp::VK_COMPARE_OP_NEVER,
791 compareMask: 0xFFFFFFFF,
792 writeMask: 0xFFFFFFFF,
793 reference: 0,
794 },
795 back: VkStencilOpState {
796 failOp: VkStencilOp::VK_STENCIL_OP_KEEP,
797 passOp: VkStencilOp::VK_STENCIL_OP_KEEP,
798 depthFailOp: VkStencilOp::VK_STENCIL_OP_KEEP,
799 compareOp: VkCompareOp::VK_COMPARE_OP_NEVER,
800 compareMask: 0xFFFFFFFF,
801 writeMask: 0xFFFFFFFF,
802 reference: 0,
803 },
804 minDepthBounds: 0.0,
805 maxDepthBounds: 0.0,
806 };
807 let mut color_blend_attachment_states: Vec<VkPipelineColorBlendAttachmentState> = Vec::with_capacity(renderpass.attachments.len());
808 for attachment in renderpass.attachments.iter() {
809 if !attachment.is_depth_stencil {
810 color_blend_attachment_states.push(VkPipelineColorBlendAttachmentState {
811 blendEnable: 0,
812 srcColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_SRC_ALPHA,
813 dstColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
814 colorBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
815 srcAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_SRC_ALPHA,
816 dstAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
817 alphaBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
818 colorWriteMask: VkColorComponentFlagBits::combine(&[
819 VkColorComponentFlagBits::VK_COLOR_COMPONENT_R_BIT,
820 VkColorComponentFlagBits::VK_COLOR_COMPONENT_G_BIT,
821 VkColorComponentFlagBits::VK_COLOR_COMPONENT_B_BIT,
822 VkColorComponentFlagBits::VK_COLOR_COMPONENT_A_BIT,
823 ]),
824 });
825 }
826 }
827 let color_blend_state_ci = VkPipelineColorBlendStateCreateInfo {
828 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
829 pNext: null(),
830 flags: 0,
831 logicOpEnable: 0,
832 logicOp: VkLogicOp::VK_LOGIC_OP_COPY,
833 attachmentCount: 0,
834 pAttachments: null(),
835 blendConstants: [0_f32; 4_usize],
836 };
837 let pipeline_layout_ci = VkPipelineLayoutCreateInfo {
838 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
839 pNext: null(),
840 flags: 0,
841 setLayoutCount: desc_set_layouts.len() as u32,
842 pSetLayouts: desc_set_layouts.as_ptr(),
843 pushConstantRangeCount: push_constant_ranges.len() as u32,
844 pPushConstantRanges: push_constant_ranges.as_ptr(),
845 };
846 let dynamic_states = [
847 VkDynamicState::VK_DYNAMIC_STATE_VIEWPORT,
848 VkDynamicState::VK_DYNAMIC_STATE_SCISSOR,
849 ].into_iter().collect();
850 let mut pipeline_layout = null();
851 device.vkcore.vkCreatePipelineLayout(device.get_vk_device(), &pipeline_layout_ci, null(), &mut pipeline_layout)?;
852 Ok(Self {
853 device,
854 mesh,
855 shaders,
856 descriptor_sets,
857 renderpass,
858 pipeline_cache,
859 rasterization_state_ci,
860 msaa_state_ci,
861 depth_stenctil_ci,
862 color_blend_state_ci,
863 color_blend_attachment_states,
864 dynamic_states,
865 pipeline_layout,
866 })
867 }
868
869 pub fn set_depth_clamp_mode(mut self, enabled: bool) -> Self {
871 self.rasterization_state_ci.depthClampEnable = if enabled {1} else {0};
872 self
873 }
874
875 pub fn set_disable_fragment_stage(mut self, disabled: bool) -> Self {
877 self.rasterization_state_ci.rasterizerDiscardEnable = if disabled {1} else {0};
878 self
879 }
880
881 pub fn set_polygon_mode(mut self, mode: VkPolygonMode) -> Self {
883 self.rasterization_state_ci.polygonMode = mode;
884 self
885 }
886
887 pub fn set_cull_mode(mut self, mode: VkCullModeFlags) -> Self {
889 self.rasterization_state_ci.cullMode = mode;
890 self
891 }
892
893 pub fn set_front_face(mut self, front_face: VkFrontFace) -> Self {
895 self.rasterization_state_ci.frontFace = front_face;
896 self
897 }
898
899 pub fn enable_depth_bias(mut self, constant: f32, slope_scale: f32, clamp: f32) -> Self {
901 self.rasterization_state_ci.depthBiasEnable = 1;
902 self.rasterization_state_ci.depthBiasConstantFactor = constant;
903 self.rasterization_state_ci.depthBiasClamp = clamp;
904 self.rasterization_state_ci.depthBiasSlopeFactor= slope_scale;
905 self
906 }
907
908 pub fn disable_depth_bias(mut self) -> Self {
910 self.rasterization_state_ci.depthBiasEnable = 0;
911 self
912 }
913
914 pub fn set_line_width(mut self, line_width: f32) -> Self {
916 self.rasterization_state_ci.lineWidth = line_width;
917 self
918 }
919
920 pub fn set_msaa_samples(mut self, msaa_samples: VkSampleCountFlagBits) -> Self {
922 self.msaa_state_ci.rasterizationSamples = msaa_samples;
923 self
924 }
925
926 pub fn set_msaa_alpha_to_coverage(mut self, enabled: bool) -> Self {
928 self.msaa_state_ci.alphaToCoverageEnable = if enabled {1} else {0};
929 self
930 }
931
932 pub fn set_msaa_super_sampling(mut self, quality: Option<f32>) -> Self {
934 if let Some(quality) = quality {
935 self.msaa_state_ci.sampleShadingEnable = 1;
936 self.msaa_state_ci.minSampleShading = quality;
937 } else {
938 self.msaa_state_ci.sampleShadingEnable = 0;
939 }
940 self
941 }
942
943 pub fn set_depth_test(mut self, enabled: bool) -> Self {
945 self.depth_stenctil_ci.depthTestEnable = if enabled {1} else {0};
946 self
947 }
948
949 pub fn set_depth_write(mut self, enabled: bool) -> Self {
951 self.depth_stenctil_ci.depthWriteEnable = if enabled {1} else {0};
952 self
953 }
954
955 pub fn set_depth_compare_mode(mut self, mode: VkCompareOp) -> Self {
957 self.depth_stenctil_ci.depthCompareOp = mode;
958 self
959 }
960
961 pub fn set_depth_bound_test_mode(mut self, bounds: Option<(f32, f32)>) -> Self {
963 if let Some((min_bound, max_bound)) = bounds {
964 self.depth_stenctil_ci.depthBoundsTestEnable = 1;
965 self.depth_stenctil_ci.minDepthBounds = min_bound;
966 self.depth_stenctil_ci.maxDepthBounds = max_bound;
967 } else {
968 self.depth_stenctil_ci.depthBoundsTestEnable = 0;
969 }
970 self
971 }
972
973 pub fn set_stencil_test(mut self, enabled: bool) -> Self {
975 self.depth_stenctil_ci.stencilTestEnable = if enabled {1} else {0};
976 self
977 }
978
979 pub fn set_stencil_mode(mut self, front_face: VkStencilOpState, back_face: VkStencilOpState) -> Self {
981 self.depth_stenctil_ci.front = front_face;
982 self.depth_stenctil_ci.back = back_face;
983 self
984 }
985
986 pub fn normal_blend_mode() -> VkPipelineColorBlendAttachmentState {
988 VkPipelineColorBlendAttachmentState {
989 blendEnable: 1,
990 srcColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_SRC_ALPHA,
991 dstColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
992 colorBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
993 srcAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_SRC_ALPHA,
994 dstAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
995 alphaBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
996 colorWriteMask: VkColorComponentFlagBits::combine(&[
997 VkColorComponentFlagBits::VK_COLOR_COMPONENT_R_BIT,
998 VkColorComponentFlagBits::VK_COLOR_COMPONENT_G_BIT,
999 VkColorComponentFlagBits::VK_COLOR_COMPONENT_B_BIT,
1000 VkColorComponentFlagBits::VK_COLOR_COMPONENT_A_BIT,
1001 ]),
1002 }
1003 }
1004
1005 pub fn additive_blend_mode() -> VkPipelineColorBlendAttachmentState {
1007 VkPipelineColorBlendAttachmentState {
1008 blendEnable: 1,
1009 srcColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE,
1010 dstColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE,
1011 colorBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
1012 srcAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE,
1013 dstAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ONE,
1014 alphaBlendOp: VkBlendOp::VK_BLEND_OP_MAX,
1015 colorWriteMask: VkColorComponentFlagBits::combine(&[
1016 VkColorComponentFlagBits::VK_COLOR_COMPONENT_R_BIT,
1017 VkColorComponentFlagBits::VK_COLOR_COMPONENT_G_BIT,
1018 VkColorComponentFlagBits::VK_COLOR_COMPONENT_B_BIT,
1019 VkColorComponentFlagBits::VK_COLOR_COMPONENT_A_BIT,
1020 ]),
1021 }
1022 }
1023
1024 pub fn disabled_blend_mode() -> VkPipelineColorBlendAttachmentState {
1026 VkPipelineColorBlendAttachmentState {
1027 blendEnable: 0,
1028 srcColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ZERO,
1029 dstColorBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ZERO,
1030 colorBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
1031 srcAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ZERO,
1032 dstAlphaBlendFactor: VkBlendFactor::VK_BLEND_FACTOR_ZERO,
1033 alphaBlendOp: VkBlendOp::VK_BLEND_OP_ADD,
1034 colorWriteMask: VkColorComponentFlagBits::combine(&[
1035 VkColorComponentFlagBits::VK_COLOR_COMPONENT_R_BIT,
1036 VkColorComponentFlagBits::VK_COLOR_COMPONENT_G_BIT,
1037 VkColorComponentFlagBits::VK_COLOR_COMPONENT_B_BIT,
1038 VkColorComponentFlagBits::VK_COLOR_COMPONENT_A_BIT,
1039 ]),
1040 }
1041 }
1042
1043 pub fn set_color_blend_mode(mut self, attachment_index: usize, color_blend_mode: VkPipelineColorBlendAttachmentState) -> Self {
1045 self.color_blend_attachment_states[attachment_index] = color_blend_mode;
1046 self
1047 }
1048
1049 pub fn add_dynamic_state(mut self, dynamic_state: VkDynamicState) -> Self {
1051 self.dynamic_states.insert(dynamic_state);
1052 self
1053 }
1054
1055 pub fn remove_dynamic_state(mut self, dynamic_state: VkDynamicState) -> Self {
1057 self.dynamic_states.remove(&dynamic_state);
1058 self
1059 }
1060
1061 pub fn build(self) -> Result<Pipeline, VulkanError> {
1063 Pipeline::new(self)
1064 }
1065}
1066
1067impl Debug for PipelineBuilder {
1068 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1069 f.debug_struct("PipelineBuilder")
1070 .field("mesh", &self.mesh)
1071 .field("shaders", &self.shaders)
1072 .field("descriptor_sets", &self.descriptor_sets)
1073 .field("renderpass", &self.renderpass)
1074 .field("pipeline_cache", &self.pipeline_cache)
1075 .field("rasterization_state_ci", &self.rasterization_state_ci)
1076 .field("msaa_state_ci", &self.msaa_state_ci)
1077 .field("depth_stenctil_ci", &self.depth_stenctil_ci)
1078 .field("color_blend_state_ci", &self.color_blend_state_ci)
1079 .field("color_blend_attachment_states", &self.color_blend_attachment_states)
1080 .field("dynamic_states", &self.dynamic_states)
1081 .field("pipeline_layout", &self.pipeline_layout)
1082 .finish()
1083 }
1084}
1085
1086impl Drop for PipelineBuilder {
1087 fn drop(&mut self) {
1088 if !self.pipeline_layout.is_null() {
1089 proceed_run(self.device.vkcore.vkDestroyPipelineLayout(self.device.get_vk_device(), self.pipeline_layout, null()))
1090 }
1091 }
1092}
1093
1094pub struct Pipeline {
1098 pub device: Arc<VulkanDevice>,
1100
1101 pub mesh: Arc<GenericMeshWithMaterial>,
1103
1104 pub shaders: Arc<DrawShaders>,
1106
1107 pub renderpass: Arc<VulkanRenderPass>,
1109
1110 pub pipeline_cache: Arc<VulkanPipelineCache>,
1112
1113 pub descriptor_sets: Arc<DescriptorSets>,
1115
1116 descriptor_sets_to_bind: BTreeMap<u32, Vec<VkDescriptorSet>>,
1118
1119 pipeline_layout: VkPipelineLayout,
1121
1122 pipeline: VkPipeline,
1124}
1125
1126#[derive(Debug, Clone, Copy)]
1127struct VertexMemberInfo<'a> {
1128 name: &'a str,
1129 type_name: &'static str,
1130 row_format: VkFormat,
1131 num_rows: u32,
1132 offset: u32,
1133 size: usize,
1134}
1135
1136impl Pipeline {
1137 pub fn new(mut builder: PipelineBuilder) -> Result<Self, VulkanError> {
1139 let device = builder.device.clone();
1140 let mesh = builder.mesh.clone();
1141 let shaders = builder.shaders.clone();
1142 let renderpass = builder.renderpass.clone();
1143 let pipeline_cache = builder.pipeline_cache.clone();
1144 let descriptor_sets = builder.descriptor_sets.clone();
1145 let pipeline_layout = builder.pipeline_layout;
1146 builder.pipeline_layout = null();
1147 let shader_stages: Vec<VkPipelineShaderStageCreateInfo> = shaders.iter_shaders().map(|(stage, shader)| VkPipelineShaderStageCreateInfo {
1148 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1149 pNext: null(),
1150 flags: 0,
1151 stage,
1152 module: shader.get_vk_shader(),
1153 pName: shader.get_entry_point().as_ptr(),
1154 pSpecializationInfo: null(),
1155 }).collect();
1156 let type_id_to_info = TypeInfo::get_map_of_type_id_to_info();
1157 let mut mesh_vertex_inputs: BTreeMap<u32, VertexMemberInfo> = BTreeMap::new();
1158 let mut mesh_instance_inputs: BTreeMap<u32, VertexMemberInfo> = BTreeMap::new();
1159 let vertex_stride = mesh.geometry.get_vertex_stride();
1160 let instance_stride = mesh.geometry.get_instance_stride();
1161 let topology = mesh.geometry.get_primitive_type();
1162 let mut cur_binding_number = 0;
1163 for (name, var) in mesh.geometry.iter_vertex_buffer_struct_members() {
1164 if let Some(info) = type_id_to_info.get(&var.type_id) {
1165 mesh_vertex_inputs.insert(cur_binding_number, VertexMemberInfo {
1166 name,
1167 type_name: info.type_name,
1168 row_format: info.row_format,
1169 num_rows: info.num_rows,
1170 offset: var.offset as u32,
1171 size: info.size,
1172 });
1173 cur_binding_number += 1;
1174 } else {
1175 panic!("Unknown member {var:?} of the vertex struct.`");
1176 }
1177 }
1178 if let Some(instance_member_iter) = mesh.geometry.iter_instance_buffer_struct_members() {
1179 for (name, var) in instance_member_iter {
1180 if let Some(info) = type_id_to_info.get(&var.type_id) {
1181 mesh_instance_inputs.insert(cur_binding_number, VertexMemberInfo {
1182 name,
1183 type_name: info.type_name,
1184 row_format: info.row_format,
1185 num_rows: info.num_rows,
1186 offset: var.offset as u32,
1187 size: info.size,
1188 });
1189 cur_binding_number += 1;
1190 } else {
1191 panic!("Unknown member {var:?} of the instance struct.");
1192 }
1193 }
1194 }
1195 let mut vertex_input_bindings: Vec<VkVertexInputBindingDescription> = Vec::with_capacity(2);
1196 vertex_input_bindings.push(VkVertexInputBindingDescription {
1197 binding: 0,
1198 stride: vertex_stride as u32,
1199 inputRate: VkVertexInputRate::VK_VERTEX_INPUT_RATE_VERTEX,
1200 });
1201 if !mesh_instance_inputs.is_empty() {
1202 vertex_input_bindings.push(VkVertexInputBindingDescription {
1203 binding: 1,
1204 stride: instance_stride as u32,
1205 inputRate: VkVertexInputRate::VK_VERTEX_INPUT_RATE_INSTANCE,
1206 });
1207 }
1208 let mut vertex_attrib_bindings: Vec<VkVertexInputAttributeDescription> = Vec::with_capacity(mesh_vertex_inputs.len() + mesh_instance_inputs.len());
1209 let mut ignored_vertex_inputs: BTreeSet<u32> = mesh_vertex_inputs.keys().cloned().collect();
1210 let mut ignored_instance_inputs: BTreeSet<u32> = mesh_instance_inputs.keys().cloned().collect();
1211 for var in shaders.vertex_shader.get_vars() {
1212 if let VariableLayout::Location(location) = var.layout {
1213 if let Some(member_info) = mesh_vertex_inputs.get(&location) && ignored_vertex_inputs.contains(&location) {
1214 ignored_vertex_inputs.remove(&location);
1215 let row_stride = member_info.size as u32 / member_info.num_rows;
1216 for row in 0..member_info.num_rows {
1217 vertex_attrib_bindings.push(VkVertexInputAttributeDescription {
1218 location: location + row,
1219 binding: 0,
1220 format: member_info.row_format,
1221 offset: member_info.offset + row * row_stride,
1222 });
1223 }
1224 } else if let Some(member_info) = mesh_instance_inputs.get(&location) && ignored_instance_inputs.contains(&location) {
1225 ignored_instance_inputs.remove(&location);
1226 let row_stride = member_info.size as u32 / member_info.num_rows;
1227 for row in 0..member_info.num_rows {
1228 vertex_attrib_bindings.push(VkVertexInputAttributeDescription {
1229 location: location + row,
1230 binding: 1,
1231 format: member_info.row_format,
1232 offset: member_info.offset + row * row_stride,
1233 });
1234 }
1235 }
1236 }
1237 }
1238 if !ignored_vertex_inputs.is_empty() {
1239 eprintln!("Ignored vertex input locations: {ignored_vertex_inputs:?}");
1240 }
1241 if !ignored_instance_inputs.is_empty() {
1242 eprintln!("Ignored instance input locations: {ignored_instance_inputs:?}");
1243 }
1244 let vertex_input_state_ci = VkPipelineVertexInputStateCreateInfo {
1245 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1246 pNext: null(),
1247 flags: 0,
1248 vertexBindingDescriptionCount: vertex_input_bindings.len() as u32,
1249 pVertexBindingDescriptions: vertex_input_bindings.as_ptr(),
1250 vertexAttributeDescriptionCount: vertex_attrib_bindings.len() as u32,
1251 pVertexAttributeDescriptions: vertex_attrib_bindings.as_ptr(),
1252 };
1253 let input_assembly_state_ci = VkPipelineInputAssemblyStateCreateInfo {
1254 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1255 pNext: null(),
1256 flags: 0,
1257 topology,
1258 primitiveRestartEnable: 0,
1259 };
1260 let viewport_state_ci = VkPipelineViewportStateCreateInfo {
1261 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1262 pNext: null(),
1263 flags: 0,
1264 viewportCount: 1,
1265 pViewports: null(),
1266 scissorCount: 1,
1267 pScissors: null(),
1268 };
1269 builder.color_blend_state_ci.attachmentCount = builder.color_blend_attachment_states.len() as u32;
1270 builder.color_blend_state_ci.pAttachments = builder.color_blend_attachment_states.as_ptr();
1271 let dynamic_states: Vec<VkDynamicState> = builder.dynamic_states.clone().into_iter().collect();
1272 let dynamic_state_ci = VkPipelineDynamicStateCreateInfo {
1273 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1274 pNext: null(),
1275 flags: 0,
1276 dynamicStateCount: dynamic_states.len() as u32,
1277 pDynamicStates: dynamic_states.as_ptr(),
1278 };
1279 let tessellation_state_ci = VkPipelineTessellationStateCreateInfo {
1280 sType: VkStructureType::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
1281 pNext: null(),
1282 flags: 0,
1283 patchControlPoints: if let Some(tcs) = &shaders.tessellation_control_shader {tcs.get_tessellation_output_vertices().unwrap_or(0)} else {0},
1284 };
1285 let pipeline_ci = VkGraphicsPipelineCreateInfo {
1286 sType: VkStructureType::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1287 pNext: null(),
1288 flags: 0,
1289 stageCount: shader_stages.len() as u32,
1290 pStages: shader_stages.as_ptr(),
1291 pVertexInputState: &vertex_input_state_ci,
1292 pInputAssemblyState: &input_assembly_state_ci,
1293 pTessellationState: if tessellation_state_ci.patchControlPoints == 0 {null()} else {&tessellation_state_ci},
1294 pViewportState: &viewport_state_ci,
1295 pRasterizationState: &builder.rasterization_state_ci,
1296 pMultisampleState: &builder.msaa_state_ci,
1297 pDepthStencilState: &builder.depth_stenctil_ci,
1298 pColorBlendState: &builder.color_blend_state_ci,
1299 pDynamicState: &dynamic_state_ci,
1300 layout: pipeline_layout,
1301 renderPass: renderpass.get_vk_renderpass(),
1302 subpass: 0,
1303 basePipelineHandle: null(),
1304 basePipelineIndex: 0,
1305 };
1306 let mut pipeline = null();
1307 device.vkcore.vkCreateGraphicsPipelines(device.get_vk_device(), pipeline_cache.get_vk_pipeline_cache(), 1, &pipeline_ci, null(), &mut pipeline)?;
1308 let mut descriptor_sets_to_bind: BTreeMap<u32, Vec<VkDescriptorSet>> = BTreeMap::new();
1309 let descriptor_sets_map = descriptor_sets.get_descriptor_sets();
1310 if !descriptor_sets_map.is_empty() {
1311 let first_set = *descriptor_sets_map.keys().next().unwrap();
1312 let last_set = *descriptor_sets_map.last_key_value().unwrap().0;
1313 let mut prev_set = None;
1314 for i in first_set..=last_set {
1315 if let Some(set) = descriptor_sets_map.get(&i) {
1316 if let Some(first_set) = &prev_set {
1317 descriptor_sets_to_bind.get_mut(first_set).unwrap().push(*set);
1318 } else {
1319 prev_set = Some(i);
1320 descriptor_sets_to_bind.insert(i, vec![*set]);
1321 }
1322 } else {
1323 prev_set = None;
1324 }
1325 }
1326 }
1327 Ok(Self {
1328 device,
1329 mesh,
1330 shaders,
1331 renderpass,
1332 pipeline_cache,
1333 descriptor_sets,
1334 descriptor_sets_to_bind,
1335 pipeline_layout,
1336 pipeline,
1337 })
1338 }
1339
1340 pub(crate) fn get_vk_pipeline(&self) -> VkPipeline {
1342 self.pipeline
1343 }
1344
1345 fn bind_descriptor_sets(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
1347 for (first_set, sets) in self.descriptor_sets_to_bind.iter() {
1348 self.device.vkcore.vkCmdBindDescriptorSets(cmdbuf, VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, self.pipeline_layout, *first_set, sets.len() as u32, sets.as_ptr(), 0, null())?;
1349 }
1350 Ok(())
1351 }
1352
1353 pub fn prepare_data(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
1355 self.mesh.geometry.flush(cmdbuf)?;
1356 Ok(())
1357 }
1358
1359 pub fn draw(&self, cmdbuf: VkCommandBuffer) -> Result<(), VulkanError> {
1361 let vkcore = &self.device.vkcore;
1362 self.bind_descriptor_sets(cmdbuf)?;
1363 vkcore.vkCmdBindPipeline(cmdbuf, VkPipelineBindPoint::VK_PIPELINE_BIND_POINT_GRAPHICS, self.pipeline)?;
1364 let vertex_buffer = self.mesh.geometry.get_vk_vertex_buffer();
1365 let index_buffer = self.mesh.geometry.get_vk_index_buffer();
1366 let instance_buffer = self.mesh.geometry.get_vk_instance_buffer();
1367 let command_buffer = self.mesh.geometry.get_vk_command_buffer();
1368 let vertex_count = self.mesh.geometry.get_vertex_count() as u32;
1369 let index_count = self.mesh.geometry.get_index_count() as u32;
1370 let instance_count = self.mesh.geometry.get_instance_count() as u32;
1371 let command_count = self.mesh.geometry.get_command_count() as u32;
1372 let index_type = self.mesh.geometry.get_index_type().unwrap_or(VkIndexType::VK_INDEX_TYPE_UINT16);
1373 let command_stride = self.mesh.geometry.get_command_stride() as u32;
1374 if let Some(index_buffer) = index_buffer {
1375 vkcore.vkCmdBindIndexBuffer(cmdbuf, index_buffer, 0, index_type)?;
1376 }
1377 if let Some(instance_buffer) = instance_buffer {
1378 let vertex_buffers = [vertex_buffer, instance_buffer];
1379 let offsets = [0, 0];
1380 vkcore.vkCmdBindVertexBuffers(cmdbuf, 0, vertex_buffers.len() as u32, vertex_buffers.as_ptr(), offsets.as_ptr())?;
1381 } else {
1382 let vertex_buffers = [vertex_buffer];
1383 let offsets = [0];
1384 vkcore.vkCmdBindVertexBuffers(cmdbuf, 0, vertex_buffers.len() as u32, vertex_buffers.as_ptr(), offsets.as_ptr())?;
1385 }
1386 match (index_buffer, command_buffer) {
1387 (None, None) => vkcore.vkCmdDraw(cmdbuf, vertex_count, instance_count, 0, 0)?,
1388 (Some(_), None) => vkcore.vkCmdDrawIndexed(cmdbuf, index_count, instance_count, 0, 0, 0)?,
1389 (None, Some(buffer)) => vkcore.vkCmdDrawIndirect(cmdbuf, buffer, 0, command_count, command_stride)?,
1390 (Some(_), Some(buffer)) => vkcore.vkCmdDrawIndexedIndirect(cmdbuf, buffer, 0, command_count, command_stride)?,
1391 }
1392 Ok(())
1393 }
1394}
1395
1396impl Debug for Pipeline {
1397 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
1398 f.debug_struct("Pipeline")
1399 .field("mesh", &self.mesh)
1400 .field("shaders", &self.shaders)
1401 .field("renderpass", &self.renderpass)
1402 .field("pipeline_cache", &self.pipeline_cache)
1403 .field("descriptor_sets", &self.descriptor_sets)
1404 .field("descriptor_sets_to_bind", &self.descriptor_sets_to_bind)
1405 .field("pipeline_layout", &self.pipeline_layout)
1406 .field("pipeline", &self.pipeline)
1407 .finish()
1408 }
1409}
1410
1411impl Drop for Pipeline {
1412 fn drop(&mut self) {
1413 proceed_run(self.device.wait_idle());
1414 proceed_run(self.device.vkcore.vkDestroyPipelineLayout(self.device.get_vk_device(), self.pipeline_layout, null()));
1415 proceed_run(self.device.vkcore.vkDestroyPipeline(self.device.get_vk_device(), self.pipeline, null()));
1416 }
1417}
1418
1419unsafe impl Send for Pipeline {}
1420unsafe impl Sync for Pipeline {}