use std::borrow::Borrow;
use std::fmt;
use std::ops::Range;
use crate::buffer::Offset;
use crate::image::Layout;
use crate::pso::ShaderStageFlags;
use crate::Backend;
pub type DescriptorSetIndex = u16;
pub type DescriptorBinding = u32;
pub type DescriptorArrayIndex = usize;
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum DescriptorType {
Sampler = 0,
CombinedImageSampler = 1,
SampledImage = 2,
StorageImage = 3,
UniformTexelBuffer = 4,
StorageTexelBuffer = 5,
UniformBuffer = 6,
StorageBuffer = 7,
UniformBufferDynamic = 8,
StorageBufferDynamic = 9,
InputAttachment = 10,
}
#[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(Fail, Clone, Copy, Debug, PartialEq, Eq)]
pub enum AllocationError {
#[fail(display = "Host memory allocation failed.")]
OutOfHostMemory,
#[fail(display = "Device memory allocation failed.")]
OutOfDeviceMemory,
#[fail(display = "Descriptor pool memory allocation failed.")]
OutOfPoolMemory,
#[fail(display = "Descriptor pool is fragmented.")]
FragmentedPool,
#[fail(display = "Descriptor layout incompatible with pool.")]
IncompatibleLayout,
}
pub trait DescriptorPool<B: Backend>: Send + Sync + fmt::Debug {
unsafe fn allocate_set(
&mut self,
layout: &B::DescriptorSetLayout,
) -> Result<B::DescriptorSet, AllocationError> {
let mut sets = Vec::with_capacity(1);
self.allocate_sets(Some(layout), &mut sets)
.map(|_| sets.remove(0))
}
unsafe fn allocate_sets<I>(
&mut self,
layouts: I,
sets: &mut Vec<B::DescriptorSet>,
) -> Result<(), AllocationError>
where
I: IntoIterator,
I::Item: Borrow<B::DescriptorSetLayout>,
{
let base = sets.len();
for layout in layouts {
match self.allocate_set(layout.borrow()) {
Ok(set) => sets.push(set),
Err(e) => {
self.free_sets(sets.drain(base..));
return Err(e);
}
}
}
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)]
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)]
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, Range<Option<Offset>>),
UniformTexelBuffer(&'a B::BufferView),
StorageTexelBuffer(&'a B::BufferView),
}
#[allow(missing_docs)]
#[derive(Clone, Copy)]
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;
}
}