use std::sync::Arc;
use buffer::BufferAccess;
use buffer::BufferViewRef;
use buffer::Buffer;
use descriptor::descriptor::DescriptorDesc;
use descriptor::descriptor::DescriptorType;
use descriptor::descriptor_set::DescriptorSet;
use descriptor::descriptor_set::DescriptorSetDesc;
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
use descriptor::descriptor_set::DescriptorPool;
use descriptor::descriptor_set::DescriptorPoolAlloc;
use descriptor::descriptor_set::UnsafeDescriptorSet;
use descriptor::descriptor_set::DescriptorWrite;
use descriptor::descriptor_set::StdDescriptorPool;
use descriptor::pipeline_layout::PipelineLayoutAbstract;
use device::Device;
use device::DeviceOwned;
use image::ImageAccess;
use image::ImageView;
use image::ImageLayout;
use sampler::Sampler;
use sync::AccessFlagBits;
use sync::PipelineStages;
pub struct SimpleDescriptorSet<R, P = Arc<StdDescriptorPool>> where P: DescriptorPool {
inner: P::Alloc,
resources: R,
layout: Arc<UnsafeDescriptorSetLayout>
}
impl<R, P> SimpleDescriptorSet<R, P> where P: DescriptorPool {
#[inline]
pub fn set_layout(&self) -> &Arc<UnsafeDescriptorSetLayout> {
&self.layout
}
}
unsafe impl<R, P> DescriptorSet for SimpleDescriptorSet<R, P> where P: DescriptorPool {
#[inline]
fn inner(&self) -> &UnsafeDescriptorSet {
self.inner.inner()
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
unimplemented!()
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
unimplemented!()
}
}
unsafe impl<R, P> DescriptorSetDesc for SimpleDescriptorSet<R, P> where P: DescriptorPool {
#[inline]
fn num_bindings(&self) -> usize {
unimplemented!() }
#[inline]
fn descriptor(&self, binding: usize) -> Option<DescriptorDesc> {
unimplemented!() }
}
#[macro_export]
macro_rules! simple_descriptor_set {
($layout:expr, $set_num:expr, {$($name:ident: $val:expr),*$(,)*}) => ({
#[allow(unused_imports)]
use $crate::descriptor::descriptor_set::SimpleDescriptorSetBuilder;
#[allow(unused_imports)]
use $crate::descriptor::descriptor_set::SimpleDescriptorSetBufferExt;
#[allow(unused_imports)]
use $crate::descriptor::descriptor_set::SimpleDescriptorSetImageExt;
let builder = SimpleDescriptorSetBuilder::new($layout, $set_num);
$(
let builder = $val.add_me(builder, stringify!($name));
)*
builder.build()
});
}
pub struct SimpleDescriptorSetBuilder<L, R> {
layout: L,
set_id: usize,
writes: Vec<DescriptorWrite>,
resources: R,
}
impl<L> SimpleDescriptorSetBuilder<L, ()> where L: PipelineLayoutAbstract {
pub fn new(layout: L, set_id: usize) -> SimpleDescriptorSetBuilder<L, ()> {
assert!(layout.num_sets() > set_id);
let cap = layout.num_bindings_in_set(set_id).unwrap_or(0);
SimpleDescriptorSetBuilder {
layout: layout,
set_id: set_id,
writes: Vec::with_capacity(cap),
resources: (),
}
}
}
impl<L, R> SimpleDescriptorSetBuilder<L, R> where L: PipelineLayoutAbstract {
pub fn build(self) -> SimpleDescriptorSet<R, Arc<StdDescriptorPool>> {
let pool = Device::standard_descriptor_pool(self.layout.device());
let set_layout = self.layout.descriptor_set_layout(self.set_id).unwrap().clone();
let set = unsafe {
let mut set = pool.alloc(&set_layout).unwrap(); set.inner_mut().write(pool.device(), self.writes.into_iter());
set
};
SimpleDescriptorSet {
inner: set,
resources: self.resources,
layout: set_layout,
}
}
}
pub unsafe trait SimpleDescriptorSetBufferExt<L, R> {
type Out;
fn add_me(self, i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>;
}
unsafe impl<L, R, T> SimpleDescriptorSetBufferExt<L, R> for T
where T: Buffer, L: PipelineLayoutAbstract
{
type Out = (R, SimpleDescriptorSetBuf<T::Access>);
fn add_me(self, mut i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>
{
let buffer = self.access();
let (set_id, binding_id) = i.layout.descriptor_by_name(name).unwrap(); assert_eq!(set_id, i.set_id); let desc = i.layout.descriptor(set_id, binding_id).unwrap();
assert!(desc.array_count == 1); i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::UniformBuffer => unsafe {
DescriptorWrite::uniform_buffer(binding_id as u32, 0, &buffer)
},
DescriptorType::StorageBuffer => unsafe {
DescriptorWrite::storage_buffer(binding_id as u32, 0, &buffer)
},
_ => panic!()
});
SimpleDescriptorSetBuilder {
layout: i.layout,
set_id: i.set_id,
writes: i.writes,
resources: (i.resources, SimpleDescriptorSetBuf {
buffer: buffer,
write: !desc.readonly,
stage: PipelineStages::none(), access: AccessFlagBits::none(), })
}
}
}
pub unsafe trait SimpleDescriptorSetImageExt<L, R> {
type Out;
fn add_me(self, i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>;
}
unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for T
where T: ImageView, L: PipelineLayoutAbstract
{
type Out = (R, SimpleDescriptorSetImg<T::Access>);
fn add_me(self, mut i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>
{
let image_view = self.access();
let (set_id, binding_id) = i.layout.descriptor_by_name(name).unwrap(); assert_eq!(set_id, i.set_id); let desc = i.layout.descriptor(set_id, binding_id).unwrap();
assert!(desc.array_count == 1); i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::SampledImage => {
DescriptorWrite::sampled_image(binding_id as u32, 0, &image_view)
},
DescriptorType::StorageImage => {
DescriptorWrite::storage_image(binding_id as u32, 0, &image_view)
},
DescriptorType::InputAttachment => {
DescriptorWrite::input_attachment(binding_id as u32, 0, &image_view)
},
_ => panic!()
});
SimpleDescriptorSetBuilder {
layout: i.layout,
set_id: i.set_id,
writes: i.writes,
resources: (i.resources, SimpleDescriptorSetImg {
image: image_view,
sampler: None,
write: !desc.readonly,
first_mipmap: 0, num_mipmaps: 1, first_layer: 0, num_layers: 1, layout: ImageLayout::General, stage: PipelineStages::none(), access: AccessFlagBits::none(), })
}
}
}
unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for (T, Arc<Sampler>)
where T: ImageView, L: PipelineLayoutAbstract
{
type Out = (R, SimpleDescriptorSetImg<T::Access>);
fn add_me(self, mut i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>
{
let image_view = self.0.access();
let (set_id, binding_id) = i.layout.descriptor_by_name(name).unwrap(); assert_eq!(set_id, i.set_id); let desc = i.layout.descriptor(set_id, binding_id).unwrap();
assert!(desc.array_count == 1); i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::CombinedImageSampler => {
DescriptorWrite::combined_image_sampler(binding_id as u32, 0, &self.1, &image_view)
},
_ => panic!()
});
SimpleDescriptorSetBuilder {
layout: i.layout,
set_id: i.set_id,
writes: i.writes,
resources: (i.resources, SimpleDescriptorSetImg {
image: image_view,
sampler: Some(self.1),
write: !desc.readonly,
first_mipmap: 0, num_mipmaps: 1, first_layer: 0, num_layers: 1, layout: ImageLayout::General, stage: PipelineStages::none(), access: AccessFlagBits::none(), })
}
}
}
unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for Vec<(T, Arc<Sampler>)>
where T: ImageView, L: PipelineLayoutAbstract
{
type Out = (R, Vec<SimpleDescriptorSetImg<T::Access>>);
fn add_me(self, mut i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>
{
let (set_id, binding_id) = i.layout.descriptor_by_name(name).unwrap(); assert_eq!(set_id, i.set_id); let desc = i.layout.descriptor(set_id, binding_id).unwrap();
assert_eq!(desc.array_count as usize, self.len());
let mut imgs = Vec::new();
for (num, (img, sampler)) in self.into_iter().enumerate() {
let image_view = img.access();
i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::CombinedImageSampler => {
DescriptorWrite::combined_image_sampler(binding_id as u32, num as u32,
&sampler, &image_view)
},
_ => panic!()
});
imgs.push(SimpleDescriptorSetImg {
image: image_view,
sampler: Some(sampler),
write: !desc.readonly,
first_mipmap: 0, num_mipmaps: 1, first_layer: 0, num_layers: 1, layout: ImageLayout::General, stage: PipelineStages::none(), access: AccessFlagBits::none(), });
}
SimpleDescriptorSetBuilder {
layout: i.layout,
set_id: i.set_id,
writes: i.writes,
resources: (i.resources, imgs),
}
}
}
pub struct SimpleDescriptorSetBuf<B> {
buffer: B,
write: bool,
stage: PipelineStages,
access: AccessFlagBits,
}
pub struct SimpleDescriptorSetBufView<V> where V: BufferViewRef {
view: V,
write: bool,
stage: PipelineStages,
access: AccessFlagBits,
}
pub struct SimpleDescriptorSetImg<I> {
image: I,
sampler: Option<Arc<Sampler>>,
write: bool,
first_mipmap: u32,
num_mipmaps: u32,
first_layer: u32,
num_layers: u32,
layout: ImageLayout,
stage: PipelineStages,
access: AccessFlagBits,
}