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