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