• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2017 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9 
10 //! A simple, immutable descriptor set that is expected to be long-lived.
11 //!
12 //! Creating a persistent descriptor set allocates from a pool, and can't be modified once created.
13 //! You are therefore encouraged to create them at initialization and not the during
14 //! performance-critical paths.
15 //!
16 //! > **Note**: You can control of the pool that is used to create the descriptor set, if you wish
17 //! > so. By creating a implementation of the `DescriptorPool` trait that doesn't perform any
18 //! > actual allocation, you can skip this allocation and make it acceptable to use a persistent
19 //! > descriptor set in performance-critical paths..
20 //!
21 //! # Examples
22 //! TODO:
23 
24 use crate::{
25     descriptor_set::{
26         allocator::{DescriptorSetAlloc, DescriptorSetAllocator, StandardDescriptorSetAlloc},
27         update::WriteDescriptorSet,
28         DescriptorSet, DescriptorSetCreationError, DescriptorSetInner, DescriptorSetLayout,
29         DescriptorSetResources, UnsafeDescriptorSet,
30     },
31     device::{Device, DeviceOwned},
32     VulkanObject,
33 };
34 use std::{
35     hash::{Hash, Hasher},
36     sync::Arc,
37 };
38 
39 /// A simple, immutable descriptor set that is expected to be long-lived.
40 pub struct PersistentDescriptorSet<P = StandardDescriptorSetAlloc> {
41     alloc: P,
42     inner: DescriptorSetInner,
43 }
44 
45 impl PersistentDescriptorSet {
46     /// Creates and returns a new descriptor set with a variable descriptor count of 0.
47     ///
48     /// See `new_with_pool` for more.
49     #[inline]
new<A>( allocator: &A, layout: Arc<DescriptorSetLayout>, descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>, ) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, DescriptorSetCreationError> where A: DescriptorSetAllocator + ?Sized,50     pub fn new<A>(
51         allocator: &A,
52         layout: Arc<DescriptorSetLayout>,
53         descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
54     ) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, DescriptorSetCreationError>
55     where
56         A: DescriptorSetAllocator + ?Sized,
57     {
58         Self::new_variable(allocator, layout, 0, descriptor_writes)
59     }
60 
61     /// Creates and returns a new descriptor set with the requested variable descriptor count,
62     /// allocating it from the provided pool.
63     ///
64     /// # Panics
65     ///
66     /// - Panics if `layout` was created for push descriptors rather than descriptor sets.
67     /// - Panics if `variable_descriptor_count` is too large for the given `layout`.
new_variable<A>( allocator: &A, layout: Arc<DescriptorSetLayout>, variable_descriptor_count: u32, descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>, ) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, DescriptorSetCreationError> where A: DescriptorSetAllocator + ?Sized,68     pub fn new_variable<A>(
69         allocator: &A,
70         layout: Arc<DescriptorSetLayout>,
71         variable_descriptor_count: u32,
72         descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
73     ) -> Result<Arc<PersistentDescriptorSet<A::Alloc>>, DescriptorSetCreationError>
74     where
75         A: DescriptorSetAllocator + ?Sized,
76     {
77         assert!(
78             !layout.push_descriptor(),
79             "the provided descriptor set layout is for push descriptors, and cannot be used to \
80             build a descriptor set object",
81         );
82 
83         let max_count = layout.variable_descriptor_count();
84 
85         assert!(
86             variable_descriptor_count <= max_count,
87             "the provided variable_descriptor_count ({}) is greater than the maximum number of \
88             variable count descriptors in the set ({})",
89             variable_descriptor_count,
90             max_count,
91         );
92 
93         let alloc = allocator.allocate(&layout, variable_descriptor_count)?;
94         let inner = DescriptorSetInner::new(
95             alloc.inner().handle(),
96             layout,
97             variable_descriptor_count,
98             descriptor_writes,
99         )?;
100 
101         Ok(Arc::new(PersistentDescriptorSet { alloc, inner }))
102     }
103 }
104 
105 unsafe impl<P> DescriptorSet for PersistentDescriptorSet<P>
106 where
107     P: DescriptorSetAlloc,
108 {
inner(&self) -> &UnsafeDescriptorSet109     fn inner(&self) -> &UnsafeDescriptorSet {
110         self.alloc.inner()
111     }
112 
layout(&self) -> &Arc<DescriptorSetLayout>113     fn layout(&self) -> &Arc<DescriptorSetLayout> {
114         self.inner.layout()
115     }
116 
variable_descriptor_count(&self) -> u32117     fn variable_descriptor_count(&self) -> u32 {
118         self.inner.variable_descriptor_count
119     }
120 
resources(&self) -> &DescriptorSetResources121     fn resources(&self) -> &DescriptorSetResources {
122         self.inner.resources()
123     }
124 }
125 
126 unsafe impl<P> DeviceOwned for PersistentDescriptorSet<P>
127 where
128     P: DescriptorSetAlloc,
129 {
device(&self) -> &Arc<Device>130     fn device(&self) -> &Arc<Device> {
131         self.inner.layout().device()
132     }
133 }
134 
135 impl<P> PartialEq for PersistentDescriptorSet<P>
136 where
137     P: DescriptorSetAlloc,
138 {
eq(&self, other: &Self) -> bool139     fn eq(&self, other: &Self) -> bool {
140         self.inner() == other.inner()
141     }
142 }
143 
144 impl<P> Eq for PersistentDescriptorSet<P> where P: DescriptorSetAlloc {}
145 
146 impl<P> Hash for PersistentDescriptorSet<P>
147 where
148     P: DescriptorSetAlloc,
149 {
hash<H: Hasher>(&self, state: &mut H)150     fn hash<H: Hasher>(&self, state: &mut H) {
151         self.inner().hash(state);
152     }
153 }
154