144 lines
5.7 KiB
Rust
144 lines
5.7 KiB
Rust
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<VulkanDevice>,
|
|
pub(super) layout: DescriptorSetLayout,
|
|
pub(super) size: DeviceSize,
|
|
pub(super) offsets: ArrayVec<DeviceSize, 4>,
|
|
pub(super) _sampler: Option<Rc<VulkanSampler>>,
|
|
}
|
|
|
|
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<Self>,
|
|
sampler: &Rc<VulkanSampler>,
|
|
) -> Result<Rc<VulkanDescriptorSetLayout>, 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<Self>,
|
|
sampler: &Rc<VulkanSampler>,
|
|
) -> Result<Rc<VulkanDescriptorSetLayout>, 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<Self>,
|
|
) -> Result<Rc<VulkanDescriptorSetLayout>, 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
|
|
}
|
|
}
|