From e4025c5eb7df73aa43843176d8223f4592475750 Mon Sep 17 00:00:00 2001 From: marc0246 <40955683+marc0246@users.noreply.github.com> Date: Tue, 24 Oct 2023 16:23:17 +0200 Subject: [PATCH] Add a `StandardDescriptorSetAllocatorCreateInfo` (#2366) * Add `StandardDescriptorSetAllocatorCreateInfo` * Fix tests and examples --- examples/src/bin/async-update.rs | 3 +- examples/src/bin/basic-compute-shader.rs | 3 +- examples/src/bin/deferred/frame/system.rs | 1 + examples/src/bin/dynamic-buffers.rs | 3 +- examples/src/bin/dynamic-local-size.rs | 3 +- examples/src/bin/gl-interop.rs | 3 +- examples/src/bin/image-self-copy-blit/main.rs | 3 +- examples/src/bin/image/main.rs | 3 +- examples/src/bin/immutable-sampler/main.rs | 3 +- examples/src/bin/indirect.rs | 3 +- examples/src/bin/interactive_fractal/app.rs | 1 + .../src/bin/multi_window_game_of_life/app.rs | 1 + examples/src/bin/push-constants.rs | 3 +- examples/src/bin/runtime_array/main.rs | 3 +- examples/src/bin/self-copy-buffer.rs | 3 +- examples/src/bin/shader-include/main.rs | 3 +- examples/src/bin/shader-types-sharing.rs | 3 +- examples/src/bin/simple-particles.rs | 3 +- examples/src/bin/specialization-constants.rs | 3 +- examples/src/bin/teapot/main.rs | 3 +- examples/src/bin/texture_array/main.rs | 3 +- vulkano/src/command_buffer/auto/mod.rs | 3 +- vulkano/src/descriptor_set/allocator.rs | 77 +++++++++++++++---- vulkano/src/pipeline/compute.rs | 4 +- 24 files changed, 104 insertions(+), 37 deletions(-) diff --git a/examples/src/bin/async-update.rs b/examples/src/bin/async-update.rs index b5072d3434..449a63e9c6 100644 --- a/examples/src/bin/async-update.rs +++ b/examples/src/bin/async-update.rs @@ -483,7 +483,8 @@ fn main() { }; let mut framebuffers = window_size_dependent_setup(&images, render_pass.clone(), &mut viewport); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); // A byproduct of always using the same set of uniform buffers is that we can also create one // descriptor set for each, reusing them in the same way as the buffers. diff --git a/examples/src/bin/basic-compute-shader.rs b/examples/src/bin/basic-compute-shader.rs index 58d6a06066..873687f0a5 100644 --- a/examples/src/bin/basic-compute-shader.rs +++ b/examples/src/bin/basic-compute-shader.rs @@ -160,7 +160,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/deferred/frame/system.rs b/examples/src/bin/deferred/frame/system.rs index 3d58ea7752..7e36c04abb 100644 --- a/examples/src/bin/deferred/frame/system.rs +++ b/examples/src/bin/deferred/frame/system.rs @@ -203,6 +203,7 @@ impl FrameSystem { let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( gfx_queue.device().clone(), + Default::default(), )); // Initialize the three lighting systems. Note that we need to pass to them the subpass diff --git a/examples/src/bin/dynamic-buffers.rs b/examples/src/bin/dynamic-buffers.rs index 2fb3da4bca..32338ca571 100644 --- a/examples/src/bin/dynamic-buffers.rs +++ b/examples/src/bin/dynamic-buffers.rs @@ -154,7 +154,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/dynamic-local-size.rs b/examples/src/bin/dynamic-local-size.rs index 619d826597..ab6543834f 100644 --- a/examples/src/bin/dynamic-local-size.rs +++ b/examples/src/bin/dynamic-local-size.rs @@ -211,7 +211,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/gl-interop.rs b/examples/src/bin/gl-interop.rs index 6d1bdee18b..6e7d31e235 100644 --- a/examples/src/bin/gl-interop.rs +++ b/examples/src/bin/gl-interop.rs @@ -261,7 +261,8 @@ mod linux { } }); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/image-self-copy-blit/main.rs b/examples/src/bin/image-self-copy-blit/main.rs index dee126a682..d5d70842ca 100644 --- a/examples/src/bin/image-self-copy-blit/main.rs +++ b/examples/src/bin/image-self-copy-blit/main.rs @@ -210,7 +210,8 @@ fn main() { ) .unwrap(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let mut uploads = AutoCommandBufferBuilder::primary( diff --git a/examples/src/bin/image/main.rs b/examples/src/bin/image/main.rs index 7ef8b6a663..55c1876476 100644 --- a/examples/src/bin/image/main.rs +++ b/examples/src/bin/image/main.rs @@ -210,7 +210,8 @@ fn main() { ) .unwrap(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let mut uploads = AutoCommandBufferBuilder::primary( diff --git a/examples/src/bin/immutable-sampler/main.rs b/examples/src/bin/immutable-sampler/main.rs index 6cb548809e..a0a7b4c11a 100644 --- a/examples/src/bin/immutable-sampler/main.rs +++ b/examples/src/bin/immutable-sampler/main.rs @@ -216,7 +216,8 @@ fn main() { ) .unwrap(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let mut uploads = AutoCommandBufferBuilder::primary( diff --git a/examples/src/bin/indirect.rs b/examples/src/bin/indirect.rs index bde6c9d942..52dc7c6870 100644 --- a/examples/src/bin/indirect.rs +++ b/examples/src/bin/indirect.rs @@ -370,7 +370,8 @@ fn main() { let mut recreate_swapchain = false; let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/interactive_fractal/app.rs b/examples/src/bin/interactive_fractal/app.rs index 82f6d38a42..fa188322ab 100644 --- a/examples/src/bin/interactive_fractal/app.rs +++ b/examples/src/bin/interactive_fractal/app.rs @@ -70,6 +70,7 @@ impl FractalApp { )); let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( gfx_queue.device().clone(), + Default::default(), )); FractalApp { diff --git a/examples/src/bin/multi_window_game_of_life/app.rs b/examples/src/bin/multi_window_game_of_life/app.rs index f40966850c..aa0c774920 100644 --- a/examples/src/bin/multi_window_game_of_life/app.rs +++ b/examples/src/bin/multi_window_game_of_life/app.rs @@ -117,6 +117,7 @@ impl Default for App { )); let descriptor_set_allocator = Arc::new(StandardDescriptorSetAllocator::new( context.device().clone(), + Default::default(), )); App { diff --git a/examples/src/bin/push-constants.rs b/examples/src/bin/push-constants.rs index 672b7666a1..789c515ccc 100644 --- a/examples/src/bin/push-constants.rs +++ b/examples/src/bin/push-constants.rs @@ -142,7 +142,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/runtime_array/main.rs b/examples/src/bin/runtime_array/main.rs index 0e367280a6..2561849e05 100644 --- a/examples/src/bin/runtime_array/main.rs +++ b/examples/src/bin/runtime_array/main.rs @@ -270,7 +270,8 @@ fn main() { ) .unwrap(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let mut uploads = AutoCommandBufferBuilder::primary( diff --git a/examples/src/bin/self-copy-buffer.rs b/examples/src/bin/self-copy-buffer.rs index 1f2dad12ed..19776e25e3 100644 --- a/examples/src/bin/self-copy-buffer.rs +++ b/examples/src/bin/self-copy-buffer.rs @@ -134,7 +134,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/shader-include/main.rs b/examples/src/bin/shader-include/main.rs index be3561157b..c2dcf46281 100644 --- a/examples/src/bin/shader-include/main.rs +++ b/examples/src/bin/shader-include/main.rs @@ -142,7 +142,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/shader-types-sharing.rs b/examples/src/bin/shader-types-sharing.rs index bd6d05b748..33a7f4d69c 100644 --- a/examples/src/bin/shader-types-sharing.rs +++ b/examples/src/bin/shader-types-sharing.rs @@ -235,7 +235,8 @@ fn main() { let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); // Prepare test array `[0, 1, 2, 3....]`. let data_buffer = Buffer::from_iter( diff --git a/examples/src/bin/simple-particles.rs b/examples/src/bin/simple-particles.rs index 55ffd7fc4b..4798492c04 100644 --- a/examples/src/bin/simple-particles.rs +++ b/examples/src/bin/simple-particles.rs @@ -327,7 +327,8 @@ fn main() { } let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/specialization-constants.rs b/examples/src/bin/specialization-constants.rs index aae8ee980a..5b087d0305 100644 --- a/examples/src/bin/specialization-constants.rs +++ b/examples/src/bin/specialization-constants.rs @@ -143,7 +143,8 @@ fn main() { }; let memory_allocator = Arc::new(StandardMemoryAllocator::new_default(device.clone())); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/teapot/main.rs b/examples/src/bin/teapot/main.rs index 7f133f16f3..4001228816 100644 --- a/examples/src/bin/teapot/main.rs +++ b/examples/src/bin/teapot/main.rs @@ -258,7 +258,8 @@ fn main() { let mut previous_frame_end = Some(sync::now(device.clone()).boxed()); let rotation_start = Instant::now(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); diff --git a/examples/src/bin/texture_array/main.rs b/examples/src/bin/texture_array/main.rs index e85c42e82e..34e3fe8418 100644 --- a/examples/src/bin/texture_array/main.rs +++ b/examples/src/bin/texture_array/main.rs @@ -212,7 +212,8 @@ fn main() { ) .unwrap(); - let descriptor_set_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let descriptor_set_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let command_buffer_allocator = StandardCommandBufferAllocator::new(device.clone(), Default::default()); let mut uploads = AutoCommandBufferBuilder::primary( diff --git a/vulkano/src/command_buffer/auto/mod.rs b/vulkano/src/command_buffer/auto/mod.rs index c84f08d47d..dd29630cd3 100644 --- a/vulkano/src/command_buffer/auto/mod.rs +++ b/vulkano/src/command_buffer/auto/mod.rs @@ -773,7 +773,8 @@ mod tests { ) .unwrap(); - let ds_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let ds_allocator = + StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let set = PersistentDescriptorSet::new( &ds_allocator, diff --git a/vulkano/src/descriptor_set/allocator.rs b/vulkano/src/descriptor_set/allocator.rs index bc1dd4bb86..a01dfc0823 100644 --- a/vulkano/src/descriptor_set/allocator.rs +++ b/vulkano/src/descriptor_set/allocator.rs @@ -35,8 +35,6 @@ use thread_local::ThreadLocal; const MAX_POOLS: usize = 32; -const MAX_SETS: usize = 256; - /// Types that manage the memory of descriptor sets. /// /// # Safety @@ -96,6 +94,7 @@ pub trait DescriptorSetAlloc: Send + Sync { pub struct StandardDescriptorSetAllocator { device: InstanceOwnedDebugWrapper>, pools: ThreadLocal>>, + create_info: StandardDescriptorSetAllocatorCreateInfo, } #[derive(Debug)] @@ -112,10 +111,14 @@ unsafe impl Send for Entry {} impl StandardDescriptorSetAllocator { /// Creates a new `StandardDescriptorSetAllocator`. #[inline] - pub fn new(device: Arc) -> StandardDescriptorSetAllocator { + pub fn new( + device: Arc, + create_info: StandardDescriptorSetAllocatorCreateInfo, + ) -> StandardDescriptorSetAllocator { StandardDescriptorSetAllocator { device: InstanceOwnedDebugWrapper(device), pools: ThreadLocal::new(), + create_info, } } @@ -154,15 +157,15 @@ unsafe impl DescriptorSetAllocator for StandardDescriptorSetAllocator { let entry = unsafe { &mut *pools.get() }.get_or_try_insert(layout.id(), || { if max_count == 0 { - FixedEntry::new(layout.clone()).map(Entry::Fixed) + FixedEntry::new(layout.clone(), &self.create_info).map(Entry::Fixed) } else { - VariableEntry::new(layout.clone()).map(Entry::Variable) + VariableEntry::new(layout.clone(), &self.create_info).map(Entry::Variable) } })?; match entry { Entry::Fixed(entry) => entry.allocate(), - Entry::Variable(entry) => entry.allocate(variable_descriptor_count), + Entry::Variable(entry) => entry.allocate(variable_descriptor_count, &self.create_info), } } } @@ -199,10 +202,13 @@ struct FixedEntry { } impl FixedEntry { - fn new(layout: Arc) -> Result> { + fn new( + layout: Arc, + create_info: &StandardDescriptorSetAllocatorCreateInfo, + ) -> Result> { Ok(FixedEntry { - pool: FixedPool::new(&layout, MAX_SETS)?, - set_count: MAX_SETS, + pool: FixedPool::new(&layout, create_info.set_count)?, + set_count: create_info.set_count, layout, }) } @@ -304,11 +310,14 @@ struct VariableEntry { } impl VariableEntry { - fn new(layout: Arc) -> Result> { + fn new( + layout: Arc, + create_info: &StandardDescriptorSetAllocatorCreateInfo, + ) -> Result> { let reserve = Arc::new(ArrayQueue::new(MAX_POOLS)); Ok(VariableEntry { - pool: VariablePool::new(&layout, reserve.clone())?, + pool: VariablePool::new(&layout, reserve.clone(), create_info.set_count)?, reserve, layout, allocations: 0, @@ -318,15 +327,16 @@ impl VariableEntry { fn allocate( &mut self, variable_descriptor_count: u32, + create_info: &StandardDescriptorSetAllocatorCreateInfo, ) -> Result> { - if self.allocations >= MAX_SETS { + if self.allocations >= create_info.set_count { self.pool = if let Some(inner) = self.reserve.pop() { Arc::new(VariablePool { inner: ManuallyDrop::new(inner), reserve: self.reserve.clone(), }) } else { - VariablePool::new(&self.layout, self.reserve.clone())? + VariablePool::new(&self.layout, self.reserve.clone(), create_info.set_count)? }; self.allocations = 0; } @@ -380,17 +390,18 @@ impl VariablePool { fn new( layout: &Arc, reserve: Arc>, + set_count: usize, ) -> Result, VulkanError> { DescriptorPool::new( layout.device().clone(), DescriptorPoolCreateInfo { - max_sets: MAX_SETS as u32, + max_sets: set_count as u32, pool_sizes: layout .descriptor_counts() .iter() .map(|(&ty, &count)| { assert!(ty != DescriptorType::InlineUniformBlock); - (ty, count * MAX_SETS as u32) + (ty, count * set_count as u32) }) .collect(), ..Default::default() @@ -423,6 +434,40 @@ impl Drop for VariablePool { } } +/// Parameters to create a new `StandardDescriptorSetAllocator`. +#[derive(Clone, Debug)] +pub struct StandardDescriptorSetAllocatorCreateInfo { + /// How many descriptor sets should be allocated per pool. + /// + /// Each time a thread allocates using some descriptor set layout, and either no pools were + /// initialized yet or all pools are full, a new pool is allocated for that thread and + /// descriptor set layout combination. This option tells the allocator how many descriptor sets + /// should be allocated for that pool. For fixed-size descriptor set layouts, it always + /// allocates exactly this many descriptor sets at once for the pool, as that is more + /// performant than allocating them one-by-one. For descriptor set layouts with a variable + /// descriptor count, it allocates a pool capable of holding exactly this many descriptor sets, + /// but doesn't allocate any descriptor sets since the variable count isn't known. What this + /// means is that you should make sure that this isn't too large, so that you don't end up + /// wasting too much memory. You also don't want this to be too low, because that on the other + /// hand would mean that the pool would have to be reset more often, or that more pools would + /// need to be created, depending on the lifetime of the descriptor sets. + /// + /// The default value is `256`. + pub set_count: usize, + + pub _ne: crate::NonExhaustive, +} + +impl Default for StandardDescriptorSetAllocatorCreateInfo { + #[inline] + fn default() -> Self { + StandardDescriptorSetAllocatorCreateInfo { + set_count: 256, + _ne: crate::NonExhaustive(()), + } + } +} + /// A descriptor set allocated from a [`StandardDescriptorSetAllocator`]. #[derive(Debug)] pub struct StandardDescriptorSetAlloc { @@ -554,7 +599,7 @@ mod tests { ) .unwrap(); - let allocator = StandardDescriptorSetAllocator::new(device); + let allocator = StandardDescriptorSetAllocator::new(device, Default::default()); let pool1 = if let AllocParent::Fixed(pool) = &allocator.allocate(&layout, 0).unwrap().parent { diff --git a/vulkano/src/pipeline/compute.rs b/vulkano/src/pipeline/compute.rs index b2f3f20525..b9a8ce81d7 100644 --- a/vulkano/src/pipeline/compute.rs +++ b/vulkano/src/pipeline/compute.rs @@ -549,7 +549,7 @@ mod tests { ) .unwrap(); - let ds_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let ds_allocator = StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let set = PersistentDescriptorSet::new( &ds_allocator, pipeline.layout().set_layouts().get(0).unwrap().clone(), @@ -680,7 +680,7 @@ mod tests { ) .unwrap(); - let ds_allocator = StandardDescriptorSetAllocator::new(device.clone()); + let ds_allocator = StandardDescriptorSetAllocator::new(device.clone(), Default::default()); let set = PersistentDescriptorSet::new( &ds_allocator, pipeline.layout().set_layouts().get(0).unwrap().clone(),