aboutsummaryrefslogtreecommitdiff
path: root/src/descriptor_set/fixed_size_pool.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/descriptor_set/fixed_size_pool.rs')
-rw-r--r--src/descriptor_set/fixed_size_pool.rs604
1 files changed, 0 insertions, 604 deletions
diff --git a/src/descriptor_set/fixed_size_pool.rs b/src/descriptor_set/fixed_size_pool.rs
deleted file mode 100644
index 248f794..0000000
--- a/src/descriptor_set/fixed_size_pool.rs
+++ /dev/null
@@ -1,604 +0,0 @@
-// Copyright (c) 2017 The vulkano developers
-// Licensed under the Apache License, Version 2.0
-// <LICENSE-APACHE or
-// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
-// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
-// at your option. All files in the project carrying such
-// notice may not be copied, modified, or distributed except
-// according to those terms.
-
-//! Pool of descriptor sets of a specific capacity that are automatically reclaimed.
-//!
-//! You are encouraged to use this type when you need a different descriptor set at each frame, or
-//! regularly during the execution.
-//!
-//! # Example
-//!
-//! At initialization, create a `FixedSizeDescriptorSetsPool`.
-//!
-//! ```rust
-//! use vulkano::descriptor_set::FixedSizeDescriptorSetsPool;
-//! # use vulkano::pipeline::GraphicsPipelineAbstract;
-//! # use std::sync::Arc;
-//! # let graphics_pipeline: Arc<GraphicsPipelineAbstract> = return;
-//! // use vulkano::pipeline::GraphicsPipelineAbstract;
-//! // let graphics_pipeline: Arc<GraphicsPipelineAbstract> = ...;
-//!
-//! let layout = graphics_pipeline.layout().descriptor_set_layouts().get(0).unwrap();
-//! let pool = FixedSizeDescriptorSetsPool::new(layout.clone());
-//! ```
-//!
-//! You would then typically store the pool in a struct for later. Then whenever you need a
-//! descriptor set, call `pool.next()` to start the process of building it.
-//!
-//! ```rust
-//! # use std::sync::Arc;
-//! # use vulkano::descriptor_set::FixedSizeDescriptorSetsPool;
-//! # use vulkano::pipeline::GraphicsPipelineAbstract;
-//! # let mut pool: FixedSizeDescriptorSetsPool = return;
-//! let descriptor_set = pool.next()
-//! //.add_buffer(...)
-//! //.add_sampled_image(...)
-//! .build().unwrap();
-//! ```
-//!
-//! Note that `next()` requires exclusive (`mut`) access to the pool. You can use a `Mutex` around
-//! the pool if you can't provide this.
-
-use crate::buffer::BufferAccess;
-use crate::buffer::BufferViewRef;
-use crate::descriptor_set::layout::DescriptorSetLayout;
-use crate::descriptor_set::persistent::*;
-use crate::descriptor_set::pool::DescriptorPool;
-use crate::descriptor_set::pool::DescriptorPoolAlloc;
-use crate::descriptor_set::pool::DescriptorPoolAllocError;
-use crate::descriptor_set::pool::UnsafeDescriptorPool;
-use crate::descriptor_set::DescriptorSet;
-use crate::descriptor_set::UnsafeDescriptorSet;
-use crate::device::Device;
-use crate::device::DeviceOwned;
-use crate::image::view::ImageViewAbstract;
-use crate::sampler::Sampler;
-use crate::OomError;
-use crate::VulkanObject;
-use crossbeam_queue::SegQueue;
-use std::hash::Hash;
-use std::hash::Hasher;
-use std::sync::Arc;
-
-/// Pool of descriptor sets of a specific capacity that are automatically reclaimed.
-#[derive(Clone)]
-pub struct FixedSizeDescriptorSetsPool {
- layout: Arc<DescriptorSetLayout>,
- // We hold a local implementation of the `DescriptorPool` trait for our own purpose. Since we
- // don't want to expose this trait impl in our API, we use a separate struct.
- pool: LocalPool,
-}
-
-impl FixedSizeDescriptorSetsPool {
- /// Initializes a new pool. The pool is configured to allocate sets that corresponds to the
- /// parameters passed to this function.
- pub fn new(layout: Arc<DescriptorSetLayout>) -> FixedSizeDescriptorSetsPool {
- let device = layout.device().clone();
-
- FixedSizeDescriptorSetsPool {
- layout,
- pool: LocalPool {
- device,
- next_capacity: 3,
- current_pool: None,
- },
- }
- }
-
- /// Starts the process of building a new descriptor set.
- ///
- /// The set will corresponds to the set layout that was passed to `new`.
- #[inline]
- pub fn next(&mut self) -> FixedSizeDescriptorSetBuilder<()> {
- let inner = PersistentDescriptorSet::start(self.layout.clone());
-
- FixedSizeDescriptorSetBuilder { pool: self, inner }
- }
-}
-
-/// A descriptor set created from a `FixedSizeDescriptorSetsPool`.
-pub struct FixedSizeDescriptorSet<R> {
- inner: PersistentDescriptorSet<R, LocalPoolAlloc>,
-}
-
-unsafe impl<R> DescriptorSet for FixedSizeDescriptorSet<R>
-where
- R: PersistentDescriptorSetResources,
-{
- #[inline]
- fn inner(&self) -> &UnsafeDescriptorSet {
- self.inner.inner()
- }
-
- #[inline]
- fn layout(&self) -> &Arc<DescriptorSetLayout> {
- self.inner.layout()
- }
-
- #[inline]
- fn num_buffers(&self) -> usize {
- self.inner.num_buffers()
- }
-
- #[inline]
- fn buffer(&self, index: usize) -> Option<(&dyn BufferAccess, u32)> {
- self.inner.buffer(index)
- }
-
- #[inline]
- fn num_images(&self) -> usize {
- self.inner.num_images()
- }
-
- #[inline]
- fn image(&self, index: usize) -> Option<(&dyn ImageViewAbstract, u32)> {
- self.inner.image(index)
- }
-}
-
-unsafe impl<R> DeviceOwned for FixedSizeDescriptorSet<R> {
- #[inline]
- fn device(&self) -> &Arc<Device> {
- self.inner.device()
- }
-}
-
-impl<R> PartialEq for FixedSizeDescriptorSet<R>
-where
- R: PersistentDescriptorSetResources,
-{
- #[inline]
- fn eq(&self, other: &Self) -> bool {
- self.inner().internal_object() == other.inner().internal_object()
- && self.device() == other.device()
- }
-}
-
-impl<R> Eq for FixedSizeDescriptorSet<R> where R: PersistentDescriptorSetResources {}
-
-impl<R> Hash for FixedSizeDescriptorSet<R>
-where
- R: PersistentDescriptorSetResources,
-{
- #[inline]
- fn hash<H: Hasher>(&self, state: &mut H) {
- self.inner().internal_object().hash(state);
- self.device().hash(state);
- }
-}
-
-// The fields of this struct can be considered as fields of the `FixedSizeDescriptorSet`. They are
-// in a separate struct because we don't want to expose the fact that we implement the
-// `DescriptorPool` trait.
-#[derive(Clone)]
-struct LocalPool {
- // The `LocalPoolInner` struct contains an actual Vulkan pool. Every time it is full, we create
- // a new pool and replace the current one with the new one.
- current_pool: Option<Arc<LocalPoolInner>>,
- // Capacity to use when we create a new Vulkan pool.
- next_capacity: u32,
- // The Vulkan device.
- device: Arc<Device>,
-}
-
-struct LocalPoolInner {
- // The actual Vulkan descriptor pool. This field isn't actually used anywhere, but we need to
- // keep the pool alive in order to keep the descriptor sets valid.
- actual_pool: UnsafeDescriptorPool,
-
- // List of descriptor sets. When `alloc` is called, a descriptor will be extracted from this
- // list. When a `LocalPoolAlloc` is dropped, its descriptor set is put back in this list.
- reserve: SegQueue<UnsafeDescriptorSet>,
-}
-
-struct LocalPoolAlloc {
- // The `LocalPoolInner` we were allocated from. We need to keep a copy of it in each allocation
- // so that we can put back the allocation in the list in our `Drop` impl.
- pool: Arc<LocalPoolInner>,
-
- // The actual descriptor set, wrapped inside an `Option` so that we can extract it in our
- // `Drop` impl.
- actual_alloc: Option<UnsafeDescriptorSet>,
-}
-
-unsafe impl DescriptorPool for LocalPool {
- type Alloc = LocalPoolAlloc;
-
- fn alloc(&mut self, layout: &DescriptorSetLayout) -> Result<Self::Alloc, OomError> {
- loop {
- // Try to extract a descriptor from the current pool if any exist.
- // This is the most common case.
- if let Some(ref mut current_pool) = self.current_pool {
- if let Some(already_existing_set) = current_pool.reserve.pop() {
- return Ok(LocalPoolAlloc {
- actual_alloc: Some(already_existing_set),
- pool: current_pool.clone(),
- });
- }
- }
-
- // If we failed to grab an existing set, that means the current pool is full. Create a
- // new one of larger capacity.
- let count = *layout.descriptors_count() * self.next_capacity;
- let mut new_pool =
- UnsafeDescriptorPool::new(self.device.clone(), &count, self.next_capacity, false)?;
- let alloc = unsafe {
- match new_pool.alloc((0..self.next_capacity).map(|_| layout)) {
- Ok(iter) => {
- let stack = SegQueue::new();
- for elem in iter {
- stack.push(elem);
- }
- stack
- }
- Err(DescriptorPoolAllocError::OutOfHostMemory) => {
- return Err(OomError::OutOfHostMemory);
- }
- Err(DescriptorPoolAllocError::OutOfDeviceMemory) => {
- return Err(OomError::OutOfDeviceMemory);
- }
- Err(DescriptorPoolAllocError::FragmentedPool) => {
- // This can't happen as we don't free individual sets.
- unreachable!()
- }
- Err(DescriptorPoolAllocError::OutOfPoolMemory) => unreachable!(),
- }
- };
-
- self.next_capacity = self.next_capacity.saturating_mul(2);
- self.current_pool = Some(Arc::new(LocalPoolInner {
- actual_pool: new_pool,
- reserve: alloc,
- }));
- }
- }
-}
-
-unsafe impl DeviceOwned for LocalPool {
- #[inline]
- fn device(&self) -> &Arc<Device> {
- &self.device
- }
-}
-
-impl DescriptorPoolAlloc for LocalPoolAlloc {
- #[inline]
- fn inner(&self) -> &UnsafeDescriptorSet {
- self.actual_alloc.as_ref().unwrap()
- }
-
- #[inline]
- fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
- self.actual_alloc.as_mut().unwrap()
- }
-}
-
-impl Drop for LocalPoolAlloc {
- fn drop(&mut self) {
- let inner = self.actual_alloc.take().unwrap();
- self.pool.reserve.push(inner);
- }
-}
-
-/// Prototype of a `FixedSizeDescriptorSet`.
-///
-/// The template parameter `R` is an unspecified type that represents the list of resources.
-///
-/// See the docs of `FixedSizeDescriptorSetsPool` for an example.
-pub struct FixedSizeDescriptorSetBuilder<'a, R> {
- pool: &'a mut FixedSizeDescriptorSetsPool,
- inner: PersistentDescriptorSetBuilder<R>,
-}
-
-impl<'a, R> FixedSizeDescriptorSetBuilder<'a, R> {
- /// Builds a `FixedSizeDescriptorSet` from the builder.
- #[inline]
- pub fn build(self) -> Result<FixedSizeDescriptorSet<R>, PersistentDescriptorSetBuildError> {
- let inner = self.inner.build_with_pool(&mut self.pool.pool)?;
- Ok(FixedSizeDescriptorSet { inner })
- }
-
- /// Call this function if the next element of the set is an array in order to set the value of
- /// each element.
- ///
- /// Returns an error if the descriptor is empty.
- ///
- /// This function can be called even if the descriptor isn't an array, and it is valid to enter
- /// the "array", add one element, then leave.
- #[inline]
- pub fn enter_array(
- self,
- ) -> Result<FixedSizeDescriptorSetBuilderArray<'a, R>, PersistentDescriptorSetError> {
- Ok(FixedSizeDescriptorSetBuilderArray {
- pool: self.pool,
- inner: self.inner.enter_array()?,
- })
- }
-
- /// Skips the current descriptor if it is empty.
- #[inline]
- pub fn add_empty(
- self,
- ) -> Result<FixedSizeDescriptorSetBuilder<'a, R>, PersistentDescriptorSetError> {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.add_empty()?,
- })
- }
-
- /// Binds a buffer as the next descriptor.
- ///
- /// An error is returned if the buffer isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the buffer doesn't have the same device as the descriptor set layout.
- ///
- #[inline]
- pub fn add_buffer<T>(
- self,
- buffer: T,
- ) -> Result<
- FixedSizeDescriptorSetBuilder<'a, (R, PersistentDescriptorSetBuf<T>)>,
- PersistentDescriptorSetError,
- >
- where
- T: BufferAccess,
- {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.add_buffer(buffer)?,
- })
- }
-
- /// Binds a buffer view as the next descriptor.
- ///
- /// An error is returned if the buffer isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the buffer view doesn't have the same device as the descriptor set layout.
- ///
- pub fn add_buffer_view<T>(
- self,
- view: T,
- ) -> Result<
- FixedSizeDescriptorSetBuilder<'a, (R, PersistentDescriptorSetBufView<T>)>,
- PersistentDescriptorSetError,
- >
- where
- T: BufferViewRef,
- {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.add_buffer_view(view)?,
- })
- }
-
- /// Binds an image view as the next descriptor.
- ///
- /// An error is returned if the image view isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the image view doesn't have the same device as the descriptor set layout.
- ///
- #[inline]
- pub fn add_image<T>(
- self,
- image_view: T,
- ) -> Result<
- FixedSizeDescriptorSetBuilder<'a, (R, PersistentDescriptorSetImg<T>)>,
- PersistentDescriptorSetError,
- >
- where
- T: ImageViewAbstract,
- {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.add_image(image_view)?,
- })
- }
-
- /// Binds an image view with a sampler as the next descriptor.
- ///
- /// An error is returned if the image view isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the image view or the sampler doesn't have the same device as the descriptor set layout.
- ///
- #[inline]
- pub fn add_sampled_image<T>(
- self,
- image_view: T,
- sampler: Arc<Sampler>,
- ) -> Result<
- FixedSizeDescriptorSetBuilder<
- 'a,
- (
- (R, PersistentDescriptorSetImg<T>),
- PersistentDescriptorSetSampler,
- ),
- >,
- PersistentDescriptorSetError,
- >
- where
- T: ImageViewAbstract,
- {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.add_sampled_image(image_view, sampler)?,
- })
- }
-
- /// Binds a sampler as the next descriptor.
- ///
- /// An error is returned if the sampler isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the sampler doesn't have the same device as the descriptor set layout.
- ///
- #[inline]
- pub fn add_sampler(
- self,
- sampler: Arc<Sampler>,
- ) -> Result<
- FixedSizeDescriptorSetBuilder<'a, (R, PersistentDescriptorSetSampler)>,
- PersistentDescriptorSetError,
- > {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.add_sampler(sampler)?,
- })
- }
-}
-
-/// Same as `FixedSizeDescriptorSetBuilder`, but we're in an array.
-pub struct FixedSizeDescriptorSetBuilderArray<'a, R> {
- pool: &'a mut FixedSizeDescriptorSetsPool,
- inner: PersistentDescriptorSetBuilderArray<R>,
-}
-
-impl<'a, R> FixedSizeDescriptorSetBuilderArray<'a, R> {
- /// Leaves the array. Call this once you added all the elements of the array.
- pub fn leave_array(
- self,
- ) -> Result<FixedSizeDescriptorSetBuilder<'a, R>, PersistentDescriptorSetError> {
- Ok(FixedSizeDescriptorSetBuilder {
- pool: self.pool,
- inner: self.inner.leave_array()?,
- })
- }
-
- /// Binds a buffer as the next element in the array.
- ///
- /// An error is returned if the buffer isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the buffer doesn't have the same device as the descriptor set layout.
- ///
- pub fn add_buffer<T>(
- self,
- buffer: T,
- ) -> Result<
- FixedSizeDescriptorSetBuilderArray<'a, (R, PersistentDescriptorSetBuf<T>)>,
- PersistentDescriptorSetError,
- >
- where
- T: BufferAccess,
- {
- Ok(FixedSizeDescriptorSetBuilderArray {
- pool: self.pool,
- inner: self.inner.add_buffer(buffer)?,
- })
- }
-
- /// Binds a buffer view as the next element in the array.
- ///
- /// An error is returned if the buffer isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the buffer view doesn't have the same device as the descriptor set layout.
- ///
- pub fn add_buffer_view<T>(
- self,
- view: T,
- ) -> Result<
- FixedSizeDescriptorSetBuilderArray<'a, (R, PersistentDescriptorSetBufView<T>)>,
- PersistentDescriptorSetError,
- >
- where
- T: BufferViewRef,
- {
- Ok(FixedSizeDescriptorSetBuilderArray {
- pool: self.pool,
- inner: self.inner.add_buffer_view(view)?,
- })
- }
-
- /// Binds an image view as the next element in the array.
- ///
- /// An error is returned if the image view isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the image view doesn't have the same device as the descriptor set layout.
- ///
- pub fn add_image<T>(
- self,
- image_view: T,
- ) -> Result<
- FixedSizeDescriptorSetBuilderArray<'a, (R, PersistentDescriptorSetImg<T>)>,
- PersistentDescriptorSetError,
- >
- where
- T: ImageViewAbstract,
- {
- Ok(FixedSizeDescriptorSetBuilderArray {
- pool: self.pool,
- inner: self.inner.add_image(image_view)?,
- })
- }
-
- /// Binds an image view with a sampler as the next element in the array.
- ///
- /// An error is returned if the image view isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the image or the sampler doesn't have the same device as the descriptor set layout.
- ///
- pub fn add_sampled_image<T>(
- self,
- image_view: T,
- sampler: Arc<Sampler>,
- ) -> Result<
- FixedSizeDescriptorSetBuilderArray<
- 'a,
- (
- (R, PersistentDescriptorSetImg<T>),
- PersistentDescriptorSetSampler,
- ),
- >,
- PersistentDescriptorSetError,
- >
- where
- T: ImageViewAbstract,
- {
- Ok(FixedSizeDescriptorSetBuilderArray {
- pool: self.pool,
- inner: self.inner.add_sampled_image(image_view, sampler)?,
- })
- }
-
- /// Binds a sampler as the next element in the array.
- ///
- /// An error is returned if the sampler isn't compatible with the descriptor.
- ///
- /// # Panic
- ///
- /// Panics if the sampler doesn't have the same device as the descriptor set layout.
- ///
- pub fn add_sampler(
- self,
- sampler: Arc<Sampler>,
- ) -> Result<
- FixedSizeDescriptorSetBuilderArray<'a, (R, PersistentDescriptorSetSampler)>,
- PersistentDescriptorSetError,
- > {
- Ok(FixedSizeDescriptorSetBuilderArray {
- pool: self.pool,
- inner: self.inner.add_sampler(sampler)?,
- })
- }
-}