diff options
Diffstat (limited to 'src/descriptor_set/mod.rs')
-rw-r--r-- | src/descriptor_set/mod.rs | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/src/descriptor_set/mod.rs b/src/descriptor_set/mod.rs deleted file mode 100644 index b69deee..0000000 --- a/src/descriptor_set/mod.rs +++ /dev/null @@ -1,287 +0,0 @@ -// Copyright (c) 2016 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. - -//! Bindings between shaders and the resources they access. -//! -//! # Overview -//! -//! In order to access a buffer or an image from a shader, that buffer or image must be put in a -//! *descriptor*. Each descriptor contains one buffer or one image alongside with the way that it -//! can be accessed. A descriptor can also be an array, in which case it contains multiple buffers -//! or images that all have the same layout. -//! -//! Descriptors are grouped in what is called *descriptor sets*. In Vulkan you don't bind -//! individual descriptors one by one, but you create then bind descriptor sets one by one. As -//! binding a descriptor set has (small but non-null) a cost, you are encouraged to put descriptors -//! that are often used together in the same set so that you can keep the same set binding through -//! multiple draws. -//! -//! # Example -//! -//! > **Note**: This section describes the simple way to bind resources. There are more optimized -//! > ways. -//! -//! There are two steps to give access to a resource in a shader: creating the descriptor set, and -//! passing the descriptor sets when drawing. -//! -//! ## Creating a descriptor set -//! -//! TODO: write example for: PersistentDescriptorSet::start(layout.clone()).add_buffer(data_buffer.clone()) -//! -//! ## Passing the descriptor set when drawing -//! -//! TODO: write -//! -//! # When drawing -//! -//! When you call a function that adds a draw command to a command buffer, one of the parameters -//! corresponds to the list of descriptor sets to use. Vulkano will check that what you passed is -//! compatible with the layout of the pipeline. -//! -//! TODO: talk about perfs of changing sets -//! -//! # Descriptor sets creation and management -//! -//! There are three concepts in Vulkan related to descriptor sets: -//! -//! - A `DescriptorSetLayout` is a Vulkan object that describes to the Vulkan implementation the -//! layout of a future descriptor set. When you allocate a descriptor set, you have to pass an -//! instance of this object. This is represented with the `DescriptorSetLayout` type in -//! vulkano. -//! - A `DescriptorPool` is a Vulkan object that holds the memory of descriptor sets and that can -//! be used to allocate and free individual descriptor sets. This is represented with the -//! `UnsafeDescriptorPool` type in vulkano. -//! - A `DescriptorSet` contains the bindings to resources and is allocated from a pool. This is -//! represented with the `UnsafeDescriptorSet` type in vulkano. -//! -//! In addition to this, vulkano defines the following: -//! -//! - The `DescriptorPool` trait can be implemented on types from which you can allocate and free -//! descriptor sets. However it is different from Vulkan descriptor pools in the sense that an -//! implementation of the `DescriptorPool` trait can manage multiple Vulkan descriptor pools. -//! - The `StdDescriptorPool` type is a default implementation of the `DescriptorPool` trait. -//! - The `DescriptorSet` trait is implemented on types that wrap around Vulkan descriptor sets in -//! a safe way. A Vulkan descriptor set is inherently unsafe, so we need safe wrappers around -//! them. -//! - The `SimpleDescriptorSet` type is a default implementation of the `DescriptorSet` trait. -//! - The `DescriptorSetsCollection` trait is implemented on collections of types that implement -//! `DescriptorSet`. It is what you pass to the draw functions. - -pub use self::collection::DescriptorSetsCollection; -pub use self::fixed_size_pool::FixedSizeDescriptorSetsPool; -use self::layout::DescriptorSetLayout; -pub use self::persistent::PersistentDescriptorSet; -pub use self::persistent::PersistentDescriptorSetBuildError; -pub use self::persistent::PersistentDescriptorSetError; -use self::sys::UnsafeDescriptorSet; -use crate::buffer::BufferAccess; -use crate::descriptor_set::layout::{DescriptorBufferDesc, DescriptorDescTy}; -use crate::device::DeviceOwned; -use crate::image::view::ImageViewAbstract; -use crate::SafeDeref; -use crate::VulkanObject; -use smallvec::SmallVec; -use std::hash::Hash; -use std::hash::Hasher; -use std::sync::Arc; - -mod collection; -pub mod fixed_size_pool; -pub mod layout; -pub mod persistent; -pub mod pool; -pub mod sys; - -/// Trait for objects that contain a collection of resources that will be accessible by shaders. -/// -/// Objects of this type can be passed when submitting a draw command. -pub unsafe trait DescriptorSet: DeviceOwned { - /// Returns the inner `UnsafeDescriptorSet`. - fn inner(&self) -> &UnsafeDescriptorSet; - - /// Returns the layout of this descriptor set. - fn layout(&self) -> &Arc<DescriptorSetLayout>; - - /// Creates a [`DescriptorSetWithOffsets`] with the given dynamic offsets. - fn offsets<I>(self, dynamic_offsets: I) -> DescriptorSetWithOffsets - where - Self: Sized + Send + Sync + 'static, - I: IntoIterator<Item = u32>, - { - DescriptorSetWithOffsets::new(self, dynamic_offsets) - } - - /// 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<(&dyn BufferAccess, u32)>; - - /// 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<(&dyn ImageViewAbstract, u32)>; -} - -unsafe impl<T> DescriptorSet for T -where - T: SafeDeref, - T::Target: DescriptorSet, -{ - #[inline] - fn inner(&self) -> &UnsafeDescriptorSet { - (**self).inner() - } - - #[inline] - fn layout(&self) -> &Arc<DescriptorSetLayout> { - (**self).layout() - } - - #[inline] - fn num_buffers(&self) -> usize { - (**self).num_buffers() - } - - #[inline] - fn buffer(&self, index: usize) -> Option<(&dyn BufferAccess, u32)> { - (**self).buffer(index) - } - - #[inline] - fn num_images(&self) -> usize { - (**self).num_images() - } - - #[inline] - fn image(&self, index: usize) -> Option<(&dyn ImageViewAbstract, u32)> { - (**self).image(index) - } -} - -impl PartialEq for dyn DescriptorSet + Send + Sync { - #[inline] - fn eq(&self, other: &Self) -> bool { - self.inner().internal_object() == other.inner().internal_object() - && self.device() == other.device() - } -} - -impl Eq for dyn DescriptorSet + Send + Sync {} - -impl Hash for dyn DescriptorSet + Send + Sync { - #[inline] - fn hash<H: Hasher>(&self, state: &mut H) { - self.inner().internal_object().hash(state); - self.device().hash(state); - } -} - -pub struct DescriptorSetWithOffsets { - descriptor_set: Box<dyn DescriptorSet + Send + Sync>, - dynamic_offsets: SmallVec<[u32; 4]>, -} - -impl DescriptorSetWithOffsets { - #[inline] - pub fn new<S, O>(descriptor_set: S, dynamic_offsets: O) -> Self - where - S: DescriptorSet + Send + Sync + 'static, - O: IntoIterator<Item = u32>, - { - let dynamic_offsets: SmallVec<_> = dynamic_offsets.into_iter().collect(); - let layout = descriptor_set.layout(); - let properties = layout.device().physical_device().properties(); - let min_uniform_off_align = properties.min_uniform_buffer_offset_alignment as u32; - let min_storage_off_align = properties.min_storage_buffer_offset_alignment as u32; - let mut dynamic_offset_index = 0; - - // Ensure that the number of dynamic_offsets is correct and that each - // dynamic offset is a multiple of the minimum offset alignment specified - // by the physical device. - for desc in layout.desc().bindings() { - let desc = desc.as_ref().unwrap(); - if let DescriptorDescTy::Buffer(DescriptorBufferDesc { - dynamic: Some(true), - storage, - }) = desc.ty - { - // Don't check alignment if there are not enough offsets anyway - if dynamic_offsets.len() > dynamic_offset_index { - if storage { - assert!( - dynamic_offsets[dynamic_offset_index] % min_storage_off_align == 0, - "Dynamic storage buffer offset must be a multiple of min_storage_buffer_offset_alignment: got {}, expected a multiple of {}", - dynamic_offsets[dynamic_offset_index], - min_storage_off_align - ); - } else { - assert!( - dynamic_offsets[dynamic_offset_index] % min_uniform_off_align == 0, - "Dynamic uniform buffer offset must be a multiple of min_uniform_buffer_offset_alignment: got {}, expected a multiple of {}", - dynamic_offsets[dynamic_offset_index], - min_uniform_off_align - ); - } - } - dynamic_offset_index += 1; - } - } - - assert!( - !(dynamic_offsets.len() < dynamic_offset_index), - "Too few dynamic offsets: got {}, expected {}", - dynamic_offsets.len(), - dynamic_offset_index - ); - assert!( - !(dynamic_offsets.len() > dynamic_offset_index), - "Too many dynamic offsets: got {}, expected {}", - dynamic_offsets.len(), - dynamic_offset_index - ); - - DescriptorSetWithOffsets { - descriptor_set: Box::new(descriptor_set), - dynamic_offsets, - } - } - - #[inline] - pub fn as_ref(&self) -> (&dyn DescriptorSet, &[u32]) { - (&self.descriptor_set, &self.dynamic_offsets) - } - - #[inline] - pub fn into_tuple( - self, - ) -> ( - Box<dyn DescriptorSet + Send + Sync>, - impl ExactSizeIterator<Item = u32>, - ) { - (self.descriptor_set, self.dynamic_offsets.into_iter()) - } -} - -impl<S> From<S> for DescriptorSetWithOffsets -where - S: DescriptorSet + Send + Sync + 'static, -{ - #[inline] - fn from(descriptor_set: S) -> Self { - Self::new(descriptor_set, std::iter::empty()) - } -} |