1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
use ash::version::DeviceV1_0; use ash::vk; use std::ffi::CString; use std::path::PathBuf; use crate::utils::{load_file, to_vec32}; use crate::low::vkstate::VulkanState; pub struct VkShader<'a> { pub bytecode: Vec<u32>, pub module: vk::ShaderModule, pub layouts_bindings: Vec<vk::DescriptorSetLayoutBinding>, pub layout: Vec<vk::DescriptorSetLayout>, pub pipeline: Option<vk::PipelineLayout>, pub entry_point: CString, state: &'a VulkanState, } impl<'a> VkShader<'a> { pub fn new(state: &'a VulkanState, path: &PathBuf, entry_point: CString) -> Self { let shader_bytecode = to_vec32(load_file(path).expect("[ERR] Could not load shader file.")); let shader_module_create_info = vk::ShaderModuleCreateInfo::builder() .code(&shader_bytecode) .build(); let shader_module = unsafe { state .device .create_shader_module(&shader_module_create_info, None) .expect("[ERR] Could not create shader module.") }; VkShader { bytecode: shader_bytecode, module: shader_module, layouts_bindings: Vec::new(), layout: Vec::new(), pipeline: None, entry_point, state, } } pub fn add_layout_binding( &mut self, binding: u32, count: u32, descriptor_type: vk::DescriptorType, stage: vk::ShaderStageFlags, ) { let descriptor_layout_binding_info = vk::DescriptorSetLayoutBinding::builder() .binding(binding) .descriptor_type(descriptor_type) .descriptor_count(count) .stage_flags(stage); self.layouts_bindings .push(descriptor_layout_binding_info.build()); } pub fn create_pipeline_layout(&mut self) { let descriptor_layout_create_info = vk::DescriptorSetLayoutCreateInfo::builder().bindings(&self.layouts_bindings); let descriptor_layout = unsafe { self.state .device .create_descriptor_set_layout(&descriptor_layout_create_info, None) .expect("[ERR] Could not create Descriptor Layout.") }; self.layout.push(descriptor_layout); let pipeline_layout_create_info = vk::PipelineLayoutCreateInfo::builder().set_layouts(&self.layout); let pipeline_layout = unsafe { self.state .device .create_pipeline_layout(&pipeline_layout_create_info, None) .expect("[ERR] Could not create Pipeline Layout") }; self.pipeline = Some(pipeline_layout); } } impl<'a> Drop for VkShader<'a> { fn drop(&mut self) { unsafe { if let Some(pipeline) = self.pipeline { self.state.device.destroy_pipeline_layout(pipeline, None); } for descriptor in self.layout.iter() { self.state .device .destroy_descriptor_set_layout(*descriptor, None); } self.state.device.destroy_shader_module(self.module, None); } } }