aboutsummaryrefslogtreecommitdiff
path: root/src/descriptor_set/sys.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/descriptor_set/sys.rs')
-rw-r--r--src/descriptor_set/sys.rs588
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,
- }
- }
-}