use std::{borrow::Borrow, fmt, iter};
use crate::{buffer::SubRange, image::Layout, pso::ShaderStageFlags, Backend, PseudoVec};
pub type DescriptorSetIndex = u16;
pub type DescriptorBinding = u32;
pub type DescriptorArrayIndex = usize;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BufferDescriptorType {
Storage {
read_only: bool,
},
Uniform,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum BufferDescriptorFormat {
Structured {
dynamic_offset: bool,
},
Texel,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum ImageDescriptorType {
Sampled {
with_sampler: bool,
},
Storage {
read_only: bool,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DescriptorType {
Sampler,
Image {
ty: ImageDescriptorType,
},
Buffer {
ty: BufferDescriptorType,
format: BufferDescriptorFormat,
},
InputAttachment,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DescriptorSetLayoutBinding {
pub binding: DescriptorBinding,
pub ty: DescriptorType,
pub count: DescriptorArrayIndex,
pub stage_flags: ShaderStageFlags,
pub immutable_samplers: bool,
}
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct DescriptorRangeDesc {
pub ty: DescriptorType,
pub count: usize,
}
#[derive(Clone, Debug, PartialEq)]
pub enum AllocationError {
Host,
Device,
OutOfPoolMemory,
FragmentedPool,
IncompatibleLayout,
}
impl std::fmt::Display for AllocationError {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AllocationError::Host => {
write!(fmt, "Failed to allocate descriptor set: Out of host memory")
}
AllocationError::Device => write!(
fmt,
"Failed to allocate descriptor set: Out of device memory"
),
AllocationError::OutOfPoolMemory => {
write!(fmt, "Failed to allocate descriptor set: Out of pool memory")
}
AllocationError::FragmentedPool => {
write!(fmt, "Failed to allocate descriptor set: Pool is fragmented")
}
AllocationError::IncompatibleLayout => write!(
fmt,
"Failed to allocate descriptor set: Incompatible layout"
),
}
}
}
impl std::error::Error for AllocationError {}
pub trait DescriptorPool<B: Backend>: Send + Sync + fmt::Debug {
unsafe fn allocate_set(
&mut self,
layout: &B::DescriptorSetLayout,
) -> Result<B::DescriptorSet, AllocationError> {
let mut result = PseudoVec(None);
self.allocate(iter::once(layout), &mut result)?;
Ok(result.0.unwrap())
}
unsafe fn allocate<I, E>(&mut self, layouts: I, list: &mut E) -> Result<(), AllocationError>
where
I: IntoIterator,
I::Item: Borrow<B::DescriptorSetLayout>,
E: Extend<B::DescriptorSet>,
{
for layout in layouts {
let set = self.allocate_set(layout.borrow())?;
list.extend(iter::once(set));
}
Ok(())
}
unsafe fn free_sets<I>(&mut self, descriptor_sets: I)
where
I: IntoIterator<Item = B::DescriptorSet>;
unsafe fn reset(&mut self);
}
#[allow(missing_docs)]
#[derive(Debug)]
pub struct DescriptorSetWrite<'a, B: Backend, WI>
where
WI: IntoIterator,
WI::Item: Borrow<Descriptor<'a, B>>,
{
pub set: &'a B::DescriptorSet,
pub binding: DescriptorBinding,
pub array_offset: DescriptorArrayIndex,
pub descriptors: WI,
}
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub enum Descriptor<'a, B: Backend> {
Sampler(&'a B::Sampler),
Image(&'a B::ImageView, Layout),
CombinedImageSampler(&'a B::ImageView, Layout, &'a B::Sampler),
Buffer(&'a B::Buffer, SubRange),
TexelBuffer(&'a B::BufferView),
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug)]
pub struct DescriptorSetCopy<'a, B: Backend> {
pub src_set: &'a B::DescriptorSet,
pub src_binding: DescriptorBinding,
pub src_array_offset: DescriptorArrayIndex,
pub dst_set: &'a B::DescriptorSet,
pub dst_binding: DescriptorBinding,
pub dst_array_offset: DescriptorArrayIndex,
pub count: usize,
}
bitflags! {
pub struct DescriptorPoolCreateFlags: u32 {
const FREE_DESCRIPTOR_SET = 0x1;
}
}