Fix variable count descriptor set allocations (#1702)

* fix variable count descriptor set allocations

* remove option
This commit is contained in:
Austin Johnson 2021-09-13 07:55:55 -05:00 committed by GitHub
parent a8c8257565
commit 9b9b9a4ec9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 1 deletions

View File

@ -33,6 +33,8 @@ pub struct DescriptorSetLayout {
desc: DescriptorSetDesc,
// Number of descriptors.
descriptors_count: DescriptorsCount,
// Number of descriptors in a variable count descriptor. Will be zero if no variable count descriptors are present.
variable_descriptor_count: u32,
}
impl DescriptorSetLayout {
@ -50,6 +52,7 @@ impl DescriptorSetLayout {
{
let desc = desc.into();
let mut descriptors_count = DescriptorsCount::zero();
let mut variable_descriptor_count = 0;
let bindings = desc.bindings();
let mut bindings_vk = Vec::with_capacity(bindings.len());
let mut binding_flags_vk = Vec::with_capacity(bindings.len());
@ -130,6 +133,7 @@ impl DescriptorSetLayout {
));
}
variable_descriptor_count = desc.descriptor_count;
// TODO: should these be settable separately by the user?
binding_flags |= ash::vk::DescriptorBindingFlags::VARIABLE_DESCRIPTOR_COUNT;
binding_flags |= ash::vk::DescriptorBindingFlags::PARTIALLY_BOUND;
@ -191,6 +195,7 @@ impl DescriptorSetLayout {
device,
desc,
descriptors_count,
variable_descriptor_count,
})
}
@ -204,6 +209,12 @@ impl DescriptorSetLayout {
&self.descriptors_count
}
/// Returns the number of descriptors in a variable count descriptor. This will return zero if there are no variable count descriptors present.
#[inline]
pub fn variable_descriptor_count(&self) -> u32 {
self.variable_descriptor_count
}
/// Returns the number of binding slots in the set.
#[inline]
pub fn num_bindings(&self) -> u32 {

View File

@ -157,6 +157,8 @@ impl UnsafeDescriptorPool {
where
I: IntoIterator<Item = &'l DescriptorSetLayout>,
{
let mut variable_descriptor_counts: SmallVec<[_; 8]> = SmallVec::new();
let layouts: SmallVec<[_; 8]> = layouts
.into_iter()
.map(|l| {
@ -166,17 +168,20 @@ impl UnsafeDescriptorPool {
"Tried to allocate from a pool with a set layout of a different \
device"
);
variable_descriptor_counts.push(l.variable_descriptor_count());
l.internal_object()
})
.collect();
self.alloc_impl(&layouts)
self.alloc_impl(&layouts, &variable_descriptor_counts)
}
// Actual implementation of `alloc`. Separated so that it is not inlined.
unsafe fn alloc_impl(
&mut self,
layouts: &SmallVec<[ash::vk::DescriptorSetLayout; 8]>,
variable_descriptor_counts: &SmallVec<[u32; 8]>,
) -> Result<UnsafeDescriptorPoolAllocIter, DescriptorPoolAllocError> {
let num = layouts.len();
@ -186,10 +191,25 @@ impl UnsafeDescriptorPool {
});
}
let variable_desc_count_alloc_info = if variable_descriptor_counts.iter().any(|c| *c != 0) {
Some(ash::vk::DescriptorSetVariableDescriptorCountAllocateInfo {
descriptor_set_count: layouts.len() as u32,
p_descriptor_counts: variable_descriptor_counts.as_ptr(),
.. Default::default()
})
} else {
None
};
let infos = ash::vk::DescriptorSetAllocateInfo {
descriptor_pool: self.pool,
descriptor_set_count: layouts.len() as u32,
p_set_layouts: layouts.as_ptr(),
p_next: if let Some(next) = variable_desc_count_alloc_info.as_ref() {
next as *const _ as *const _
} else {
ptr::null()
},
..Default::default()
};