use { crate::gfx_apis::vulkan::{VulkanError, device::VulkanDevice, sampler::VulkanSampler}, arrayvec::ArrayVec, ash::{ ext::descriptor_buffer, vk::{ DescriptorSetLayout, DescriptorSetLayoutBinding, DescriptorSetLayoutCreateFlags, DescriptorSetLayoutCreateInfo, DescriptorType, DeviceSize, ShaderStageFlags, }, }, std::{rc::Rc, slice}, }; pub(super) struct VulkanDescriptorSetLayout { pub(super) device: Rc, pub(super) layout: DescriptorSetLayout, pub(super) size: DeviceSize, pub(super) offsets: ArrayVec, pub(super) _sampler: Option>, } impl Drop for VulkanDescriptorSetLayout { fn drop(&mut self) { unsafe { self.device .device .destroy_descriptor_set_layout(self.layout, None); } } } impl VulkanDevice { pub(super) fn create_tex_legacy_descriptor_set_layout( self: &Rc, sampler: &Rc, ) -> Result, VulkanError> { let immutable_sampler = [sampler.sampler]; let binding = DescriptorSetLayoutBinding::default() .stage_flags(ShaderStageFlags::FRAGMENT) .immutable_samplers(&immutable_sampler) .descriptor_count(1) .descriptor_type(DescriptorType::COMBINED_IMAGE_SAMPLER); let create_info = DescriptorSetLayoutCreateInfo::default() .bindings(slice::from_ref(&binding)) .flags(DescriptorSetLayoutCreateFlags::PUSH_DESCRIPTOR_KHR); let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) }; let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; Ok(Rc::new(VulkanDescriptorSetLayout { device: self.clone(), layout, size: 0, offsets: Default::default(), _sampler: Some(sampler.clone()), })) } pub(super) fn create_tex_sampler_descriptor_set_layout( self: &Rc, sampler: &Rc, ) -> Result, VulkanError> { let immutable_sampler = [sampler.sampler]; let binding = DescriptorSetLayoutBinding::default() .stage_flags(ShaderStageFlags::FRAGMENT) .immutable_samplers(&immutable_sampler) .descriptor_count(1) .descriptor_type(DescriptorType::SAMPLER); let create_info = DescriptorSetLayoutCreateInfo::default() .bindings(slice::from_ref(&binding)) .flags(DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT); let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) }; let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; let db = self.descriptor_buffer.as_ref().unwrap(); let size = self.get_descriptor_set_size(db, layout); let mut offsets = ArrayVec::new(); unsafe { offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0)); } Ok(Rc::new(VulkanDescriptorSetLayout { device: self.clone(), layout, size, offsets, _sampler: Some(sampler.clone()), })) } pub(super) fn create_tex_resource_descriptor_set_layout( self: &Rc, ) -> Result, VulkanError> { let bindings = [ DescriptorSetLayoutBinding::default() .binding(0) .stage_flags(ShaderStageFlags::FRAGMENT) .descriptor_count(1) .descriptor_type(DescriptorType::SAMPLED_IMAGE), DescriptorSetLayoutBinding::default() .binding(1) .stage_flags(ShaderStageFlags::FRAGMENT) .descriptor_count(1) .descriptor_type(DescriptorType::UNIFORM_BUFFER), DescriptorSetLayoutBinding::default() .binding(2) .stage_flags(ShaderStageFlags::FRAGMENT) .descriptor_count(1) .descriptor_type(DescriptorType::UNIFORM_BUFFER), DescriptorSetLayoutBinding::default() .binding(3) .stage_flags(ShaderStageFlags::FRAGMENT) .descriptor_count(1) .descriptor_type(DescriptorType::UNIFORM_BUFFER), ]; let create_info = DescriptorSetLayoutCreateInfo::default() .bindings(&bindings) .flags(DescriptorSetLayoutCreateFlags::DESCRIPTOR_BUFFER_EXT); let layout = unsafe { self.device.create_descriptor_set_layout(&create_info, None) }; let layout = layout.map_err(VulkanError::CreateDescriptorSetLayout)?; let db = self.descriptor_buffer.as_ref().unwrap(); let size = self.get_descriptor_set_size(db, layout); let mut offsets = ArrayVec::new(); unsafe { offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 0)); offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 1)); offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 2)); offsets.push(db.get_descriptor_set_layout_binding_offset(layout, 3)); } Ok(Rc::new(VulkanDescriptorSetLayout { device: self.clone(), layout, size, offsets, _sampler: None, })) } fn get_descriptor_set_size( &self, db: &descriptor_buffer::Device, layout: DescriptorSetLayout, ) -> DeviceSize { let mut size = unsafe { db.get_descriptor_set_layout_size(layout) }; size = (size + self.descriptor_buffer_offset_mask) & !self.descriptor_buffer_offset_mask; size } }