diff options
Diffstat (limited to 'src/descriptor_set/sys.rs')
-rw-r--r-- | src/descriptor_set/sys.rs | 588 |
1 files changed, 0 insertions, 588 deletions
diff --git a/src/descriptor_set/sys.rs b/src/descriptor_set/sys.rs deleted file mode 100644 index d1c7cc1..0000000 --- a/src/descriptor_set/sys.rs +++ /dev/null @@ -1,588 +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. - -//! Low-level descriptor set. - -use crate::buffer::BufferAccess; -use crate::buffer::BufferInner; -use crate::buffer::BufferView; -use crate::descriptor_set::layout::DescriptorType; -use crate::device::Device; -use crate::device::DeviceOwned; -use crate::image::view::ImageViewAbstract; -use crate::sampler::Sampler; -use crate::DeviceSize; -use crate::VulkanObject; -use smallvec::SmallVec; -use std::fmt; -use std::ptr; -use std::sync::Arc; - -/// Low-level descriptor set. -/// -/// Contrary to most other objects in this library, this one doesn't free itself automatically and -/// doesn't hold the pool or the device it is associated to. -/// Instead it is an object meant to be used with the `UnsafeDescriptorPool`. -pub struct UnsafeDescriptorSet { - pub(super) set: ash::vk::DescriptorSet, -} - -impl UnsafeDescriptorSet { - // TODO: add copying from other descriptor sets - // add a `copy` method that just takes a copy, and an `update` method that takes both - // writes and copies and that actually performs the operation - - /// Modifies a descriptor set. Doesn't check that the writes or copies are correct, and - /// doesn't check whether the descriptor set is in use. - /// - /// **Important**: You must ensure that the `DescriptorSetLayout` object is alive before - /// updating a descriptor set. - /// - /// # Safety - /// - /// - The `Device` must be the device the pool of this set was created with. - /// - The `DescriptorSetLayout` object this set was created with must be alive. - /// - Doesn't verify that the things you write in the descriptor set match its layout. - /// - Doesn't keep the resources alive. You have to do that yourself. - /// - Updating a descriptor set obeys synchronization rules that aren't checked here. Once a - /// command buffer contains a pointer/reference to a descriptor set, it is illegal to write - /// to it. - /// - pub unsafe fn write<I>(&mut self, device: &Device, writes: I) - where - I: Iterator<Item = DescriptorWrite>, - { - let fns = device.fns(); - - // In this function, we build 4 arrays: one array of image descriptors (image_descriptors), - // one for buffer descriptors (buffer_descriptors), one for buffer view descriptors - // (buffer_views_descriptors), and one for the final list of writes (raw_writes). - // Only the final list is passed to Vulkan, but it will contain pointers to the first three - // lists in `pImageInfo`, `pBufferInfo` and `pTexelBufferView`. - // - // In order to handle that, we start by writing null pointers as placeholders in the final - // writes, and we store in `raw_writes_img_infos`, `raw_writes_buf_infos` and - // `raw_writes_buf_view_infos` the offsets of the pointers compared to the start of the - // list. - // Once we have finished iterating all the writes requested by the user, we modify - // `raw_writes` to point to the correct locations. - - let mut buffer_descriptors: SmallVec<[_; 64]> = SmallVec::new(); - let mut image_descriptors: SmallVec<[_; 64]> = SmallVec::new(); - let mut buffer_views_descriptors: SmallVec<[_; 64]> = SmallVec::new(); - - let mut raw_writes: SmallVec<[_; 64]> = SmallVec::new(); - let mut raw_writes_img_infos: SmallVec<[_; 64]> = SmallVec::new(); - let mut raw_writes_buf_infos: SmallVec<[_; 64]> = SmallVec::new(); - let mut raw_writes_buf_view_infos: SmallVec<[_; 64]> = SmallVec::new(); - - for indiv_write in writes { - // Since the `DescriptorWrite` objects are built only through functions, we know for - // sure that it's impossible to have an empty descriptor write. - debug_assert!(!indiv_write.inner.is_empty()); - - // The whole struct thats written here is valid, except for pImageInfo, pBufferInfo - // and pTexelBufferView which are placeholder values. - raw_writes.push(ash::vk::WriteDescriptorSet { - dst_set: self.set, - dst_binding: indiv_write.binding, - dst_array_element: indiv_write.first_array_element, - descriptor_count: indiv_write.inner.len() as u32, - descriptor_type: indiv_write.ty().into(), - p_image_info: ptr::null(), - p_buffer_info: ptr::null(), - p_texel_buffer_view: ptr::null(), - ..Default::default() - }); - - match indiv_write.inner[0] { - DescriptorWriteInner::Sampler(_) - | DescriptorWriteInner::CombinedImageSampler(_, _, _) - | DescriptorWriteInner::SampledImage(_, _) - | DescriptorWriteInner::StorageImage(_, _) - | DescriptorWriteInner::InputAttachment(_, _) => { - raw_writes_img_infos.push(Some(image_descriptors.len())); - raw_writes_buf_infos.push(None); - raw_writes_buf_view_infos.push(None); - } - DescriptorWriteInner::UniformBuffer(_, _, _) - | DescriptorWriteInner::StorageBuffer(_, _, _) - | DescriptorWriteInner::DynamicUniformBuffer(_, _, _) - | DescriptorWriteInner::DynamicStorageBuffer(_, _, _) => { - raw_writes_img_infos.push(None); - raw_writes_buf_infos.push(Some(buffer_descriptors.len())); - raw_writes_buf_view_infos.push(None); - } - DescriptorWriteInner::UniformTexelBuffer(_) - | DescriptorWriteInner::StorageTexelBuffer(_) => { - raw_writes_img_infos.push(None); - raw_writes_buf_infos.push(None); - raw_writes_buf_view_infos.push(Some(buffer_views_descriptors.len())); - } - } - - for elem in indiv_write.inner.iter() { - match *elem { - DescriptorWriteInner::UniformBuffer(buffer, offset, size) - | DescriptorWriteInner::DynamicUniformBuffer(buffer, offset, size) => { - buffer_descriptors.push(ash::vk::DescriptorBufferInfo { - buffer, - offset, - range: size, - }); - } - DescriptorWriteInner::StorageBuffer(buffer, offset, size) - | DescriptorWriteInner::DynamicStorageBuffer(buffer, offset, size) => { - buffer_descriptors.push(ash::vk::DescriptorBufferInfo { - buffer, - offset, - range: size, - }); - } - DescriptorWriteInner::Sampler(sampler) => { - image_descriptors.push(ash::vk::DescriptorImageInfo { - sampler, - image_view: ash::vk::ImageView::null(), - image_layout: ash::vk::ImageLayout::UNDEFINED, - }); - } - DescriptorWriteInner::CombinedImageSampler(sampler, view, layout) => { - image_descriptors.push(ash::vk::DescriptorImageInfo { - sampler, - image_view: view, - image_layout: layout, - }); - } - DescriptorWriteInner::StorageImage(view, layout) => { - image_descriptors.push(ash::vk::DescriptorImageInfo { - sampler: ash::vk::Sampler::null(), - image_view: view, - image_layout: layout, - }); - } - DescriptorWriteInner::SampledImage(view, layout) => { - image_descriptors.push(ash::vk::DescriptorImageInfo { - sampler: ash::vk::Sampler::null(), - image_view: view, - image_layout: layout, - }); - } - DescriptorWriteInner::InputAttachment(view, layout) => { - image_descriptors.push(ash::vk::DescriptorImageInfo { - sampler: ash::vk::Sampler::null(), - image_view: view, - image_layout: layout, - }); - } - DescriptorWriteInner::UniformTexelBuffer(view) - | DescriptorWriteInner::StorageTexelBuffer(view) => { - buffer_views_descriptors.push(view); - } - } - } - } - - // Now that `image_descriptors`, `buffer_descriptors` and `buffer_views_descriptors` are - // entirely filled and will never move again, we can fill the pointers in `raw_writes`. - for (i, write) in raw_writes.iter_mut().enumerate() { - write.p_image_info = match raw_writes_img_infos[i] { - Some(off) => image_descriptors.as_ptr().offset(off as isize), - None => ptr::null(), - }; - - write.p_buffer_info = match raw_writes_buf_infos[i] { - Some(off) => buffer_descriptors.as_ptr().offset(off as isize), - None => ptr::null(), - }; - - write.p_texel_buffer_view = match raw_writes_buf_view_infos[i] { - Some(off) => buffer_views_descriptors.as_ptr().offset(off as isize), - None => ptr::null(), - }; - } - - // It is forbidden to call `vkUpdateDescriptorSets` with 0 writes, so we need to perform - // this emptiness check. - if !raw_writes.is_empty() { - fns.v1_0.update_descriptor_sets( - device.internal_object(), - raw_writes.len() as u32, - raw_writes.as_ptr(), - 0, - ptr::null(), - ); - } - } -} - -unsafe impl VulkanObject for UnsafeDescriptorSet { - type Object = ash::vk::DescriptorSet; - - #[inline] - fn internal_object(&self) -> ash::vk::DescriptorSet { - self.set - } -} - -impl fmt::Debug for UnsafeDescriptorSet { - fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(fmt, "<Vulkan descriptor set {:?}>", self.set) - } -} - -/// Represents a single write entry to a descriptor set. -/// -/// Use the various constructors to build a `DescriptorWrite`. While it is safe to build a -/// `DescriptorWrite`, it is unsafe to actually use it to write to a descriptor set. -// TODO: allow binding whole arrays at once -pub struct DescriptorWrite { - binding: u32, - first_array_element: u32, - inner: SmallVec<[DescriptorWriteInner; 1]>, -} - -#[derive(Debug, Clone)] -enum DescriptorWriteInner { - Sampler(ash::vk::Sampler), - StorageImage(ash::vk::ImageView, ash::vk::ImageLayout), - SampledImage(ash::vk::ImageView, ash::vk::ImageLayout), - CombinedImageSampler(ash::vk::Sampler, ash::vk::ImageView, ash::vk::ImageLayout), - UniformTexelBuffer(ash::vk::BufferView), - StorageTexelBuffer(ash::vk::BufferView), - UniformBuffer(ash::vk::Buffer, DeviceSize, DeviceSize), - StorageBuffer(ash::vk::Buffer, DeviceSize, DeviceSize), - DynamicUniformBuffer(ash::vk::Buffer, DeviceSize, DeviceSize), - DynamicStorageBuffer(ash::vk::Buffer, DeviceSize, DeviceSize), - InputAttachment(ash::vk::ImageView, ash::vk::ImageLayout), -} - -macro_rules! smallvec { - ($elem:expr) => {{ - let mut s = SmallVec::new(); - s.push($elem); - s - }}; -} - -impl DescriptorWrite { - #[inline] - pub fn storage_image<I>(binding: u32, array_element: u32, image_view: &I) -> DescriptorWrite - where - I: ImageViewAbstract, - { - let layouts = image_view - .image() - .descriptor_layouts() - .expect("descriptor_layouts must return Some when used in an image view"); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!({ - DescriptorWriteInner::StorageImage( - image_view.inner().internal_object(), - layouts.storage_image.into(), - ) - }), - } - } - - #[inline] - pub fn sampler(binding: u32, array_element: u32, sampler: &Arc<Sampler>) -> DescriptorWrite { - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!(DescriptorWriteInner::Sampler(sampler.internal_object())), - } - } - - #[inline] - pub fn sampled_image<I>(binding: u32, array_element: u32, image_view: &I) -> DescriptorWrite - where - I: ImageViewAbstract, - { - let layouts = image_view - .image() - .descriptor_layouts() - .expect("descriptor_layouts must return Some when used in an image view"); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!({ - DescriptorWriteInner::SampledImage( - image_view.inner().internal_object(), - layouts.sampled_image.into(), - ) - }), - } - } - - #[inline] - pub fn combined_image_sampler<I>( - binding: u32, - array_element: u32, - sampler: &Arc<Sampler>, - image_view: &I, - ) -> DescriptorWrite - where - I: ImageViewAbstract, - { - let layouts = image_view - .image() - .descriptor_layouts() - .expect("descriptor_layouts must return Some when used in an image view"); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!({ - DescriptorWriteInner::CombinedImageSampler( - sampler.internal_object(), - image_view.inner().internal_object(), - layouts.combined_image_sampler.into(), - ) - }), - } - } - - #[inline] - pub fn uniform_texel_buffer<'a, B>( - binding: u32, - array_element: u32, - view: &BufferView<B>, - ) -> DescriptorWrite - where - B: BufferAccess, - { - assert!(view.uniform_texel_buffer()); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!(DescriptorWriteInner::UniformTexelBuffer( - view.internal_object() - )), - } - } - - #[inline] - pub fn storage_texel_buffer<'a, B>( - binding: u32, - array_element: u32, - view: &BufferView<B>, - ) -> DescriptorWrite - where - B: BufferAccess, - { - assert!(view.storage_texel_buffer()); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!(DescriptorWriteInner::StorageTexelBuffer( - view.internal_object() - )), - } - } - - #[inline] - pub unsafe fn uniform_buffer<B>(binding: u32, array_element: u32, buffer: &B) -> DescriptorWrite - where - B: BufferAccess, - { - let size = buffer.size(); - let BufferInner { buffer, offset } = buffer.inner(); - - debug_assert_eq!( - offset - % buffer - .device() - .physical_device() - .properties() - .min_uniform_buffer_offset_alignment, - 0 - ); - debug_assert!( - size <= buffer - .device() - .physical_device() - .properties() - .max_uniform_buffer_range as DeviceSize - ); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!({ - DescriptorWriteInner::UniformBuffer(buffer.internal_object(), offset, size) - }), - } - } - - #[inline] - pub unsafe fn storage_buffer<B>(binding: u32, array_element: u32, buffer: &B) -> DescriptorWrite - where - B: BufferAccess, - { - let size = buffer.size(); - let BufferInner { buffer, offset } = buffer.inner(); - - debug_assert_eq!( - offset - % buffer - .device() - .physical_device() - .properties() - .min_storage_buffer_offset_alignment, - 0 - ); - debug_assert!( - size <= buffer - .device() - .physical_device() - .properties() - .max_storage_buffer_range as DeviceSize - ); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!({ - DescriptorWriteInner::StorageBuffer(buffer.internal_object(), offset, size) - }), - } - } - - #[inline] - pub unsafe fn dynamic_uniform_buffer<B>( - binding: u32, - array_element: u32, - buffer: &B, - ) -> DescriptorWrite - where - B: BufferAccess, - { - let size = buffer.size(); - let BufferInner { buffer, offset } = buffer.inner(); - - debug_assert_eq!( - offset - % buffer - .device() - .physical_device() - .properties() - .min_uniform_buffer_offset_alignment, - 0 - ); - debug_assert!( - size <= buffer - .device() - .physical_device() - .properties() - .max_uniform_buffer_range as DeviceSize - ); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!(DescriptorWriteInner::DynamicUniformBuffer( - buffer.internal_object(), - offset, - size - )), - } - } - - #[inline] - pub unsafe fn dynamic_storage_buffer<B>( - binding: u32, - array_element: u32, - buffer: &B, - ) -> DescriptorWrite - where - B: BufferAccess, - { - let size = buffer.size(); - let BufferInner { buffer, offset } = buffer.inner(); - - debug_assert_eq!( - offset - % buffer - .device() - .physical_device() - .properties() - .min_storage_buffer_offset_alignment, - 0 - ); - debug_assert!( - size <= buffer - .device() - .physical_device() - .properties() - .max_storage_buffer_range as DeviceSize - ); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!(DescriptorWriteInner::DynamicStorageBuffer( - buffer.internal_object(), - offset, - size - )), - } - } - - #[inline] - pub fn input_attachment<I>(binding: u32, array_element: u32, image_view: &I) -> DescriptorWrite - where - I: ImageViewAbstract, - { - let layouts = image_view - .image() - .descriptor_layouts() - .expect("descriptor_layouts must return Some when used in an image view"); - - DescriptorWrite { - binding, - first_array_element: array_element, - inner: smallvec!({ - DescriptorWriteInner::InputAttachment( - image_view.inner().internal_object(), - layouts.input_attachment.into(), - ) - }), - } - } - - /// Returns the type corresponding to this write. - #[inline] - pub fn ty(&self) -> DescriptorType { - match self.inner[0] { - DescriptorWriteInner::Sampler(_) => DescriptorType::Sampler, - DescriptorWriteInner::CombinedImageSampler(_, _, _) => { - DescriptorType::CombinedImageSampler - } - DescriptorWriteInner::SampledImage(_, _) => DescriptorType::SampledImage, - DescriptorWriteInner::StorageImage(_, _) => DescriptorType::StorageImage, - DescriptorWriteInner::UniformTexelBuffer(_) => DescriptorType::UniformTexelBuffer, - DescriptorWriteInner::StorageTexelBuffer(_) => DescriptorType::StorageTexelBuffer, - DescriptorWriteInner::UniformBuffer(_, _, _) => DescriptorType::UniformBuffer, - DescriptorWriteInner::StorageBuffer(_, _, _) => DescriptorType::StorageBuffer, - DescriptorWriteInner::DynamicUniformBuffer(_, _, _) => { - DescriptorType::UniformBufferDynamic - } - DescriptorWriteInner::DynamicStorageBuffer(_, _, _) => { - DescriptorType::StorageBufferDynamic - } - DescriptorWriteInner::InputAttachment(_, _) => DescriptorType::InputAttachment, - } - } -} |