Add prototype support for descriptor arrays of images

This commit is contained in:
Pierre Krieger 2017-04-01 12:11:53 +02:00
parent 86869ab4d6
commit 4818f365e9
3 changed files with 105 additions and 40 deletions

View File

@ -22,6 +22,7 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
set: u32,
binding: u32,
desc_ty: String,
array_count: u64,
readonly: bool,
}
@ -50,13 +51,14 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
}).next().expect(&format!("Uniform `{}` is missing a binding", name));
// Find informations about the kind of binding for this descriptor.
let (desc_ty, readonly) = descriptor_infos(doc, pointed_ty, false).expect(&format!("Couldn't find relevant type for uniform `{}` (type {}, maybe unimplemented)", name, pointed_ty));
let (desc_ty, readonly, array_count) = descriptor_infos(doc, pointed_ty, false).expect(&format!("Couldn't find relevant type for uniform `{}` (type {}, maybe unimplemented)", name, pointed_ty));
descriptors.push(Descriptor {
name: name,
desc_ty: desc_ty,
set: descriptor_set,
binding: binding,
array_count: array_count,
readonly: readonly,
});
}
@ -80,11 +82,11 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
let descriptor_body = descriptors.iter().map(|d| {
format!("({set}, {binding}) => Some(DescriptorDesc {{
ty: {desc_ty},
array_count: 1,
array_count: {array_count},
stages: self.0.clone(),
readonly: {readonly},
}}),", set = d.set, binding = d.binding, desc_ty = d.desc_ty,
readonly = if d.readonly { "true" } else { "false" })
}}),", set = d.set, binding = d.binding, desc_ty = d.desc_ty, array_count = d.array_count,
readonly = if d.readonly { "true" } else { "false" })
}).collect::<Vec<_>>().concat();
@ -194,12 +196,12 @@ fn pointer_variable_ty(doc: &parse::Spirv, variable: u32) -> u32 {
}).next().unwrap()
}
/// Returns a `DescriptorDescTy` constructor and a bool indicating whether the descriptor is
/// read-only.
/// Returns a `DescriptorDescTy` constructor, a bool indicating whether the descriptor is
/// read-only, and the number of array elements.
///
/// See also section 14.5.2 of the Vulkan specs: Descriptor Set Interface
fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sampled: bool)
-> Option<(String, bool)>
-> Option<(String, bool, u64)>
{
doc.instructions.iter().filter_map(|i| {
match i {
@ -233,7 +235,7 @@ fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sa
content: DescriptorBufferContentDesc::F32, // FIXME: wrong
}})", if is_ssbo { "true" } else { "false "});
Some((desc, true))
Some((desc, true, 1))
},
&parse::Instruction::TypeImage { result_id, ref dim, arrayed, ms, sampled,
@ -263,7 +265,7 @@ fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sa
array_layers: {}
}}", ms, arrayed);
Some((desc, true))
Some((desc, true, 1))
} else if let &enums::Dim::DimBuffer = dim {
// We are a texel buffer.
@ -272,7 +274,7 @@ fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sa
format: None, // TODO: specify format if known
}}", !sampled);
Some((desc, true))
Some((desc, true, 1))
} else {
// We are a sampled or storage image.
@ -296,7 +298,7 @@ fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sa
array_layers: {},
}})", ty, sampled, dim, ms, arrayed);
Some((desc, true))
Some((desc, true, 1))
}
},
@ -308,7 +310,20 @@ fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sa
&parse::Instruction::TypeSampler { result_id } if result_id == pointed_ty => {
let desc = format!("DescriptorDescTy::Sampler");
Some((desc, true))
Some((desc, true, 1))
},
&parse::Instruction::TypeArray { result_id, type_id, length_id } if result_id == pointed_ty => {
let (desc, readonly, arr) = match descriptor_infos(doc, type_id, false) {
None => return None,
Some(v) => v,
};
assert_eq!(arr, 1); // TODO: implement?
let len = doc.instructions.iter().filter_map(|e| {
match e { &parse::Instruction::Constant { result_id, ref data, .. } if result_id == length_id => Some(data.clone()), _ => None }
}).next().expect("failed to find array length");
let len = len.iter().rev().fold(0u64, |a, &b| (a << 32) | b as u64);
Some((desc, readonly, len))
},
_ => None, // TODO: other types

View File

@ -710,12 +710,12 @@ macro_rules! smallvec {
impl DescriptorWrite {
#[inline]
pub fn storage_image<I>(binding: u32, image: &I) -> DescriptorWrite
pub fn storage_image<I>(binding: u32, array_element: u32, image: &I) -> DescriptorWrite
where I: ImageView
{
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!({
let layout = image.descriptor_set_storage_image_layout() as u32;
DescriptorWriteInner::StorageImage(image.inner().internal_object(), layout)
@ -724,21 +724,21 @@ impl DescriptorWrite {
}
#[inline]
pub fn sampler(binding: u32, sampler: &Arc<Sampler>) -> DescriptorWrite {
pub fn sampler(binding: u32, array_element: u32, sampler: &Arc<Sampler>) -> DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!(DescriptorWriteInner::Sampler(sampler.internal_object()))
}
}
#[inline]
pub fn sampled_image<I>(binding: u32, image: &I) -> DescriptorWrite
pub fn sampled_image<I>(binding: u32, array_element: u32, image: &I) -> DescriptorWrite
where I: ImageView
{
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!({
let layout = image.descriptor_set_sampled_image_layout() as u32;
DescriptorWriteInner::SampledImage(image.inner().internal_object(), layout)
@ -747,12 +747,12 @@ impl DescriptorWrite {
}
#[inline]
pub fn combined_image_sampler<I>(binding: u32, sampler: &Arc<Sampler>, image: &I) -> DescriptorWrite
pub fn combined_image_sampler<I>(binding: u32, array_element: u32, sampler: &Arc<Sampler>, image: &I) -> DescriptorWrite
where I: ImageView
{
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!({
let layout = image.descriptor_set_combined_image_sampler_layout() as u32;
DescriptorWriteInner::CombinedImageSampler(sampler.internal_object(), image.inner().internal_object(), layout)
@ -761,7 +761,7 @@ impl DescriptorWrite {
}
#[inline]
pub fn uniform_texel_buffer<'a, F, B>(binding: u32, view: &Arc<BufferView<F, B>>) -> DescriptorWrite
pub fn uniform_texel_buffer<'a, F, B>(binding: u32, array_element: u32, view: &Arc<BufferView<F, B>>) -> DescriptorWrite
where B: Buffer,
F: 'static + Send + Sync,
{
@ -769,13 +769,13 @@ impl DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!(DescriptorWriteInner::UniformTexelBuffer(view.internal_object())),
}
}
#[inline]
pub fn storage_texel_buffer<'a, F, B>(binding: u32, view: &Arc<BufferView<F, B>>) -> DescriptorWrite
pub fn storage_texel_buffer<'a, F, B>(binding: u32, array_element: u32, view: &Arc<BufferView<F, B>>) -> DescriptorWrite
where B: Buffer + 'static,
F: 'static + Send + Sync,
{
@ -783,13 +783,13 @@ impl DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!(DescriptorWriteInner::StorageTexelBuffer(view.internal_object())),
}
}
#[inline]
pub unsafe fn uniform_buffer<B>(binding: u32, buffer: &B) -> DescriptorWrite
pub unsafe fn uniform_buffer<B>(binding: u32, array_element: u32, buffer: &B) -> DescriptorWrite
where B: Buffer
{
let size = buffer.size();
@ -797,7 +797,7 @@ impl DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!({
DescriptorWriteInner::UniformBuffer(buffer.internal_object(), offset, size)
}),
@ -805,7 +805,7 @@ impl DescriptorWrite {
}
#[inline]
pub unsafe fn storage_buffer<B>(binding: u32, buffer: &B) -> DescriptorWrite
pub unsafe fn storage_buffer<B>(binding: u32, array_element: u32, buffer: &B) -> DescriptorWrite
where B: Buffer
{
let size = buffer.size();
@ -813,7 +813,7 @@ impl DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!({
DescriptorWriteInner::StorageBuffer(buffer.internal_object(), offset, size)
}),
@ -821,7 +821,7 @@ impl DescriptorWrite {
}
#[inline]
pub unsafe fn dynamic_uniform_buffer<B>(binding: u32, buffer: &B) -> DescriptorWrite
pub unsafe fn dynamic_uniform_buffer<B>(binding: u32, array_element: u32, buffer: &B) -> DescriptorWrite
where B: Buffer
{
let size = buffer.size();
@ -829,14 +829,14 @@ impl DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!(DescriptorWriteInner::DynamicUniformBuffer(buffer.internal_object(),
offset, size)),
}
}
#[inline]
pub unsafe fn dynamic_storage_buffer<B>(binding: u32, buffer: &B) -> DescriptorWrite
pub unsafe fn dynamic_storage_buffer<B>(binding: u32, array_element: u32, buffer: &B) -> DescriptorWrite
where B: Buffer
{
let size = buffer.size();
@ -844,19 +844,19 @@ impl DescriptorWrite {
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!(DescriptorWriteInner::DynamicStorageBuffer(buffer.internal_object(),
offset, size)),
}
}
#[inline]
pub fn input_attachment<I>(binding: u32, image: &I) -> DescriptorWrite
pub fn input_attachment<I>(binding: u32, array_element: u32, image: &I) -> DescriptorWrite
where I: ImageView
{
DescriptorWrite {
binding: binding,
first_array_element: 0,
first_array_element: array_element,
inner: smallvec!({
let layout = image.descriptor_set_input_attachment_layout() as u32;
DescriptorWriteInner::InputAttachment(image.inner().internal_object(), layout)

View File

@ -218,10 +218,10 @@ unsafe impl<L, R, T> SimpleDescriptorSetBufferExt<L, R> for T
assert!(desc.array_count == 1); // not implemented
i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::UniformBuffer => unsafe {
DescriptorWrite::uniform_buffer(binding_id as u32, &buffer)
DescriptorWrite::uniform_buffer(binding_id as u32, 0, &buffer)
},
DescriptorType::StorageBuffer => unsafe {
DescriptorWrite::storage_buffer(binding_id as u32, &buffer)
DescriptorWrite::storage_buffer(binding_id as u32, 0, &buffer)
},
_ => panic!()
});
@ -268,13 +268,13 @@ unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for T
assert!(desc.array_count == 1); // not implemented
i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::SampledImage => unsafe {
DescriptorWrite::sampled_image(binding_id as u32, &image_view)
DescriptorWrite::sampled_image(binding_id as u32, 0, &image_view)
},
DescriptorType::StorageImage => unsafe {
DescriptorWrite::storage_image(binding_id as u32, &image_view)
DescriptorWrite::storage_image(binding_id as u32, 0, &image_view)
},
DescriptorType::InputAttachment => unsafe {
DescriptorWrite::input_attachment(binding_id as u32, &image_view)
DescriptorWrite::input_attachment(binding_id as u32, 0, &image_view)
},
_ => panic!()
});
@ -316,7 +316,7 @@ unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for (T, Arc<Sampler>)
assert!(desc.array_count == 1); // not implemented
i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::CombinedImageSampler => unsafe {
DescriptorWrite::combined_image_sampler(binding_id as u32, &self.1, &image_view)
DescriptorWrite::combined_image_sampler(binding_id as u32, 0, &self.1, &image_view)
},
_ => panic!()
});
@ -341,6 +341,56 @@ unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for (T, Arc<Sampler>)
}
}
// TODO: DRY
unsafe impl<L, R, T> SimpleDescriptorSetImageExt<L, R> for Vec<(T, Arc<Sampler>)>
where T: IntoImageView, L: PipelineLayoutAbstract
{
type Out = (R, Vec<SimpleDescriptorSetImg<T::Target>>);
fn add_me(self, mut i: SimpleDescriptorSetBuilder<L, R>, name: &str)
-> SimpleDescriptorSetBuilder<L, Self::Out>
{
let (set_id, binding_id) = i.layout.desc().descriptor_by_name(name).unwrap(); // TODO: Result instead
assert_eq!(set_id, i.set_id); // TODO: Result instead
let desc = i.layout.desc().descriptor(set_id, binding_id).unwrap(); // TODO: Result instead
assert_eq!(desc.array_count as usize, self.len()); // not implemented
let mut imgs = Vec::new();
for (num, (img, sampler)) in self.into_iter().enumerate() {
let image_view = img.into_image_view();
i.writes.push(match desc.ty.ty().unwrap() {
DescriptorType::CombinedImageSampler => unsafe {
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, // FIXME:
num_mipmaps: 1, // FIXME:
first_layer: 0, // FIXME:
num_layers: 1, // FIXME:
layout: Layout::General, // FIXME:
stage: PipelineStages::none(), // FIXME:
access: AccessFlagBits::none(), // FIXME:
});
}
SimpleDescriptorSetBuilder {
layout: i.layout,
set_id: i.set_id,
writes: i.writes,
resources: (i.resources, imgs),
}
}
}
/*
/// Internal trait related to the `SimpleDescriptorSet` system.
pub unsafe trait SimpleDescriptorSetResourcesCollection {