Correctly synchronize resources in descriptor sets

This commit is contained in:
Pierre Krieger 2017-07-20 15:37:47 +02:00
parent 68ab76c481
commit 05c104d63c
5 changed files with 315 additions and 115 deletions

View File

@ -2028,12 +2028,52 @@ impl<'b, P> SyncCommandBufferBuilderBindDescriptorSets<'b, P> {
fn into_final_command(self: Box<Self>) -> Box<FinalCommand + Send + Sync> {
struct Fin(SmallVec<[Box<DescriptorSet + Send + Sync>; 12]>);
impl FinalCommand for Fin {
/* TODO: implement buffer() and image() */
fn buffer(&self, mut num: usize) -> &BufferAccess {
for set in self.0.iter() {
if let Some(buf) = set.buffer(num) {
return buf.0;
}
num -= set.num_buffers();
}
panic!()
}
fn image(&self, mut num: usize) -> &ImageAccess {
for set in self.0.iter() {
if let Some(img) = set.image(num) {
return img.0;
}
num -= set.num_images();
}
panic!()
}
}
Box::new(Fin(self.inner))
}
fn buffer(&self, mut num: usize) -> &BufferAccess {
for set in self.inner.iter() {
if let Some(buf) = set.buffer(num) {
return buf.0;
}
num -= set.num_buffers();
}
panic!()
}
fn image(&self, mut num: usize) -> &ImageAccess {
for set in self.inner.iter() {
if let Some(img) = set.image(num) {
return img.0;
}
num -= set.num_images();
}
panic!()
}
}
let total_buffers_num = self.inner.iter().map(|d| d.num_buffers()).fold(0, |a, b| a + b);
let total_images_num = self.inner.iter().map(|d| d.num_images()).fold(0, |a, b| a + b);
self.builder
.commands
.lock()
@ -2047,7 +2087,51 @@ impl<'b, P> SyncCommandBufferBuilderBindDescriptorSets<'b, P> {
dynamic_offsets: Some(dynamic_offsets),
}));
// FIXME: add resources
for n in 0 .. total_buffers_num {
self.builder
.prev_cmd_resource(KeyTy::Buffer,
n,
false, // TODO: wrong
PipelineStages { // TODO: wrong
all_graphics: true,
..PipelineStages::none()
},
AccessFlagBits { // TODO: wrong
uniform_read: true,
input_attachment_read: true,
shader_read: true,
shader_write: true,
color_attachment_read: true,
color_attachment_write: true,
depth_stencil_attachment_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined,
ImageLayout::Undefined)?;
}
for n in 0 .. total_images_num {
self.builder
.prev_cmd_resource(KeyTy::Image,
n,
false, // TODO: wrong
PipelineStages { // TODO: wrong
all_graphics: true,
..PipelineStages::none()
},
AccessFlagBits { // TODO: wrong
uniform_read: true,
input_attachment_read: true,
shader_read: true,
shader_write: true,
color_attachment_read: true,
color_attachment_write: true,
depth_stencil_attachment_read: true,
..AccessFlagBits::none()
},
ImageLayout::Undefined, // TODO: wrong
ImageLayout::Undefined)?; // TODO: wrong
}
Ok(())
}

View File

@ -7,12 +7,9 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use buffer::BufferAccess;
use descriptor::descriptor::DescriptorDesc;
use descriptor::descriptor_set::DescriptorSet;
use descriptor::descriptor_set::DescriptorSetDesc;
use image::ImageAccess;
use std::iter;
/// A collection of descriptor set objects.
pub unsafe trait DescriptorSetsCollection {
@ -21,18 +18,14 @@ pub unsafe trait DescriptorSetsCollection {
/// Returns the number of descriptors in the set. Includes possibly empty descriptors.
///
/// Returns `None` if the set is out of range.
// TODO: remove ; user should just use `into_vec` instead
fn num_bindings_in_set(&self, set: usize) -> Option<usize>;
/// Returns the descriptor for the given binding of the given set.
///
/// Returns `None` if out of range.
// TODO: remove ; user should just use `into_vec` instead
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc>;
/// Returns the list of buffers used by this descriptor set. Includes buffer views.
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a>;
/// Returns the list of images used by this descriptor set. Includes image views.
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a>;
}
unsafe impl DescriptorSetsCollection for () {
@ -50,16 +43,6 @@ unsafe impl DescriptorSetsCollection for () {
fn descriptor(&self, set: usize, binding: usize) -> Option<DescriptorDesc> {
None
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
Box::new(iter::empty())
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
Box::new(iter::empty())
}
}
unsafe impl<T> DescriptorSetsCollection for T
@ -85,16 +68,6 @@ unsafe impl<T> DescriptorSetsCollection for T
_ => None,
}
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
DescriptorSet::buffers_list(self)
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
DescriptorSet::images_list(self)
}
}
macro_rules! impl_collection {
@ -158,32 +131,6 @@ macro_rules! impl_collection {
None
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
#![allow(non_snake_case)]
let &(ref first, $(ref $others,)*) = self;
let mut output = Vec::new();
output.extend(first.buffers_list());
$(
output.extend($others.buffers_list());
)*
Box::new(output.into_iter())
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
#![allow(non_snake_case)]
let &(ref first, $(ref $others,)*) = self;
let mut output = Vec::new();
output.extend(first.images_list());
$(
output.extend($others.images_list());
)*
Box::new(output.into_iter())
}
}
impl_collection!($($others),+);

View File

@ -78,13 +78,23 @@ pub unsafe trait DescriptorSet: DescriptorSetDesc {
/// Returns the inner `UnsafeDescriptorSet`.
fn inner(&self) -> &UnsafeDescriptorSet;
/// Returns the list of buffers used by this descriptor set. Includes buffer views.
// TODO: meh for boxing
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a>;
/// Returns the number of buffers within this descriptor set.
fn num_buffers(&self) -> usize;
/// Returns the `index`th buffer of this descriptor set, or `None` if out of range. Also
/// returns the index of the descriptor that uses this buffer.
///
/// The valid range is between 0 and `num_buffers()`.
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)>;
/// Returns the list of images used by this descriptor set. Includes image views.
// TODO: meh for boxing
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a>;
/// Returns the number of images within this descriptor set.
fn num_images(&self) -> usize;
/// Returns the `index`th image of this descriptor set, or `None` if out of range. Also returns
/// the index of the descriptor that uses this image.
///
/// The valid range is between 0 and `num_images()`.
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)>;
}
unsafe impl<T> DescriptorSet for T
@ -97,13 +107,23 @@ unsafe impl<T> DescriptorSet for T
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
(**self).buffers_list()
fn num_buffers(&self) -> usize {
(**self).num_buffers()
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
(**self).buffer(index)
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
(**self).images_list()
fn num_images(&self) -> usize {
(**self).num_images()
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
(**self).image(index)
}
}

View File

@ -32,11 +32,8 @@ use device::Device;
use device::DeviceOwned;
use format::Format;
use image::ImageAccess;
use image::ImageLayout;
use image::ImageViewAccess;
use sampler::Sampler;
use sync::AccessFlagBits;
use sync::PipelineStages;
use OomError;
use VulkanObject;
@ -88,20 +85,33 @@ impl PersistentDescriptorSet<()> {
}
}
unsafe impl<R, P> DescriptorSet for PersistentDescriptorSet<R, P> where P: DescriptorPoolAlloc {
unsafe impl<R, P> DescriptorSet for PersistentDescriptorSet<R, P>
where P: DescriptorPoolAlloc,
R: PersistentDescriptorSetResources
{
#[inline]
fn inner(&self) -> &UnsafeDescriptorSet {
self.inner.inner()
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
unimplemented!()
fn num_buffers(&self) -> usize {
self.resources.num_buffers()
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
unimplemented!()
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
self.resources.buffer(index)
}
#[inline]
fn num_images(&self) -> usize {
self.resources.num_images()
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
self.resources.image(index)
}
}
@ -419,9 +429,7 @@ impl<L, R> PersistentDescriptorSetBuilderArray<L, R> where L: PipelineLayoutAbst
writes: self.builder.writes,
resources: (self.builder.resources, PersistentDescriptorSetBuf {
buffer: buffer,
write: !readonly,
stage: PipelineStages::none(), // FIXME:
access: AccessFlagBits::none(), // FIXME:
descriptor_num: self.builder.binding_id as u32,
})
},
desc: self.desc,
@ -487,9 +495,7 @@ impl<L, R> PersistentDescriptorSetBuilderArray<L, R> where L: PipelineLayoutAbst
writes: self.builder.writes,
resources: (self.builder.resources, PersistentDescriptorSetBufView {
view: view,
write: !readonly,
stage: PipelineStages::none(), // FIXME:
access: AccessFlagBits::none(), // FIXME:
descriptor_num: self.builder.binding_id as u32,
})
},
desc: self.desc,
@ -581,14 +587,7 @@ impl<L, R> PersistentDescriptorSetBuilderArray<L, R> where L: PipelineLayoutAbst
writes: self.builder.writes,
resources: (self.builder.resources, PersistentDescriptorSetImg {
image: image_view,
write: !readonly,
first_mipmap: 0, // FIXME:
num_mipmaps: 1, // FIXME:
first_layer: 0, // FIXME:
num_layers: 1, // FIXME:
layout: ImageLayout::General, // FIXME:
stage: PipelineStages::none(), // FIXME:
access: AccessFlagBits::none(), // FIXME:
descriptor_num: self.builder.binding_id as u32,
})
},
desc: self.desc,
@ -646,14 +645,7 @@ impl<L, R> PersistentDescriptorSetBuilderArray<L, R> where L: PipelineLayoutAbst
writes: self.builder.writes,
resources: ((self.builder.resources, PersistentDescriptorSetImg {
image: image_view,
write: !readonly,
first_mipmap: 0, // FIXME:
num_mipmaps: 1, // FIXME:
first_layer: 0, // FIXME:
num_layers: 1, // FIXME:
layout: ImageLayout::General, // FIXME:
stage: PipelineStages::none(), // FIXME:
access: AccessFlagBits::none(), // FIXME:
descriptor_num: self.builder.binding_id as u32,
}), PersistentDescriptorSetSampler {
sampler: sampler,
}),
@ -772,12 +764,70 @@ fn image_match_desc<I>(image_view: &I, desc: &DescriptorImageDesc)
Ok(())
}
pub unsafe trait PersistentDescriptorSetResources {
fn num_buffers(&self) -> usize;
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)>;
fn num_images(&self) -> usize;
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)>;
}
unsafe impl PersistentDescriptorSetResources for () {
#[inline]
fn num_buffers(&self) -> usize {
0
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
None
}
#[inline]
fn num_images(&self) -> usize {
0
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
None
}
}
/// Internal object related to the `PersistentDescriptorSet` system.
pub struct PersistentDescriptorSetBuf<B> {
buffer: B,
write: bool,
stage: PipelineStages,
access: AccessFlagBits,
descriptor_num: u32,
}
unsafe impl<R, B> PersistentDescriptorSetResources for (R, PersistentDescriptorSetBuf<B>)
where R: PersistentDescriptorSetResources,
B: BufferAccess,
{
#[inline]
fn num_buffers(&self) -> usize {
self.0.num_buffers() + 1
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
if let Some(buf) = self.0.buffer(index) {
Some(buf)
} else if index == self.0.num_buffers() {
Some((&self.1.buffer, self.1.descriptor_num))
} else {
None
}
}
#[inline]
fn num_images(&self) -> usize {
self.0.num_images()
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
self.0.image(index)
}
}
/// Internal object related to the `PersistentDescriptorSet` system.
@ -785,22 +835,75 @@ pub struct PersistentDescriptorSetBufView<V>
where V: BufferViewRef
{
view: V,
write: bool,
stage: PipelineStages,
access: AccessFlagBits,
descriptor_num: u32,
}
unsafe impl<R, V> PersistentDescriptorSetResources for (R, PersistentDescriptorSetBufView<V>)
where R: PersistentDescriptorSetResources,
V: BufferViewRef,
{
#[inline]
fn num_buffers(&self) -> usize {
self.0.num_buffers() + 1
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
if let Some(buf) = self.0.buffer(index) {
Some(buf)
} else if index == self.0.num_buffers() {
Some((self.1.view.view().buffer(), self.1.descriptor_num))
} else {
None
}
}
#[inline]
fn num_images(&self) -> usize {
self.0.num_images()
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
self.0.image(index)
}
}
/// Internal object related to the `PersistentDescriptorSet` system.
pub struct PersistentDescriptorSetImg<I> {
image: I,
write: bool,
first_mipmap: u32,
num_mipmaps: u32,
first_layer: u32,
num_layers: u32,
layout: ImageLayout,
stage: PipelineStages,
access: AccessFlagBits,
descriptor_num: u32,
}
unsafe impl<R, I> PersistentDescriptorSetResources for (R, PersistentDescriptorSetImg<I>)
where R: PersistentDescriptorSetResources,
I: ImageAccess,
{
#[inline]
fn num_buffers(&self) -> usize {
self.0.num_buffers()
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
self.0.buffer(index)
}
#[inline]
fn num_images(&self) -> usize {
self.0.num_images() + 1
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
if let Some(img) = self.0.image(index) {
Some(img)
} else if index == self.0.num_images() {
Some((&self.1.image, self.1.descriptor_num))
} else {
None
}
}
}
/// Internal object related to the `PersistentDescriptorSet` system.
@ -808,6 +911,30 @@ pub struct PersistentDescriptorSetSampler {
sampler: Arc<Sampler>,
}
unsafe impl<R> PersistentDescriptorSetResources for (R, PersistentDescriptorSetSampler)
where R: PersistentDescriptorSetResources
{
#[inline]
fn num_buffers(&self) -> usize {
self.0.num_buffers()
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
self.0.buffer(index)
}
#[inline]
fn num_images(&self) -> usize {
self.0.num_images()
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
self.0.image(index)
}
}
/// Error related to the persistent descriptor set.
#[derive(Debug, Clone)]
pub enum PersistentDescriptorSetError {

View File

@ -78,13 +78,35 @@ unsafe impl<R, P> DescriptorSet for SimpleDescriptorSet<R, P>
}
#[inline]
fn buffers_list<'a>(&'a self) -> Box<Iterator<Item = &'a BufferAccess> + 'a> {
unimplemented!()
fn num_buffers(&self) -> usize {
// Note that since the simple descriptor set is deprecated, and since buffers and images
// within descriptor sets weren't supported before its deprecation, we just return a dummy
// value.
0
}
#[inline]
fn buffer(&self, index: usize) -> Option<(&BufferAccess, u32)> {
// Note that since the simple descriptor set is deprecated, and since buffers and images
// within descriptor sets weren't supported before its deprecation, we just return a dummy
// value.
None
}
#[inline]
fn images_list<'a>(&'a self) -> Box<Iterator<Item = &'a ImageAccess> + 'a> {
unimplemented!()
fn num_images(&self) -> usize {
// Note that since the simple descriptor set is deprecated, and since buffers and images
// within descriptor sets weren't supported before its deprecation, we just return a dummy
// value.
0
}
#[inline]
fn image(&self, index: usize) -> Option<(&ImageAccess, u32)> {
// Note that since the simple descriptor set is deprecated, and since buffers and images
// within descriptor sets weren't supported before its deprecation, we just return a dummy
// value.
None
}
}