1use {
15 super::{
16 DescriptorSetLayout, DriverError,
17 accel_struct::AccelerationStructure,
18 buffer::{Buffer, BufferSubresourceRange},
19 compute::ComputePipeline,
20 device::Device,
21 format_aspect_mask,
22 graphics::GraphicsPipeline,
23 image::{Image, ImageViewInfo},
24 ray_tracing::RayTracingPipeline,
25 shader::PipelineDescriptorInfo,
26 },
27 ash::vk,
28 log::warn,
29 std::{
30 fmt::{Debug, Formatter},
31 iter,
32 ops::Deref,
33 slice,
34 sync::Arc,
35 thread::panicking,
36 },
37};
38
39#[derive(Debug)]
43#[read_only::cast]
44pub(crate) struct DescriptorPool {
45 #[readonly]
49 pub device: Device,
50
51 #[readonly]
55 pub handle: vk::DescriptorPool,
56
57 #[readonly]
61 pub(crate) info: DescriptorPoolInfo,
62}
63
64impl DescriptorPool {
65 #[profiling::function]
66 pub(crate) fn create(
67 device: &Device,
68 info: impl Into<DescriptorPoolInfo>,
69 ) -> Result<Self, DriverError> {
70 let device = device.clone();
71 let info = info.into();
72
73 let mut pool_sizes = [vk::DescriptorPoolSize {
74 ty: Default::default(),
75 descriptor_count: 0,
76 }; 12];
77 let mut pool_size_count = 0;
78
79 if info.acceleration_structure_count > 0 {
80 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
81 ty: vk::DescriptorType::ACCELERATION_STRUCTURE_KHR,
82 descriptor_count: info.acceleration_structure_count,
83 };
84 pool_size_count += 1;
85 }
86
87 if info.combined_image_sampler_count > 0 {
88 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
89 ty: vk::DescriptorType::COMBINED_IMAGE_SAMPLER,
90 descriptor_count: info.combined_image_sampler_count,
91 };
92 pool_size_count += 1;
93 }
94
95 if info.input_attachment_count > 0 {
96 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
97 ty: vk::DescriptorType::INPUT_ATTACHMENT,
98 descriptor_count: info.input_attachment_count,
99 };
100 pool_size_count += 1;
101 }
102
103 if info.sampled_image_count > 0 {
104 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
105 ty: vk::DescriptorType::SAMPLED_IMAGE,
106 descriptor_count: info.sampled_image_count,
107 };
108 pool_size_count += 1;
109 }
110
111 if info.sampler_count > 0 {
112 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
113 ty: vk::DescriptorType::SAMPLER,
114 descriptor_count: info.sampler_count,
115 };
116 pool_size_count += 1;
117 }
118
119 if info.storage_buffer_count > 0 {
120 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
121 ty: vk::DescriptorType::STORAGE_BUFFER,
122 descriptor_count: info.storage_buffer_count,
123 };
124 pool_size_count += 1;
125 }
126
127 if info.storage_buffer_dynamic_count > 0 {
128 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
129 ty: vk::DescriptorType::STORAGE_BUFFER_DYNAMIC,
130 descriptor_count: info.storage_buffer_dynamic_count,
131 };
132 pool_size_count += 1;
133 }
134
135 if info.storage_image_count > 0 {
136 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
137 ty: vk::DescriptorType::STORAGE_IMAGE,
138 descriptor_count: info.storage_image_count,
139 };
140 pool_size_count += 1;
141 }
142
143 if info.storage_texel_buffer_count > 0 {
144 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
145 ty: vk::DescriptorType::STORAGE_TEXEL_BUFFER,
146 descriptor_count: info.storage_texel_buffer_count,
147 };
148 pool_size_count += 1;
149 }
150
151 if info.uniform_buffer_count > 0 {
152 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
153 ty: vk::DescriptorType::UNIFORM_BUFFER,
154 descriptor_count: info.uniform_buffer_count,
155 };
156 pool_size_count += 1;
157 }
158
159 if info.uniform_buffer_dynamic_count > 0 {
160 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
161 ty: vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC,
162 descriptor_count: info.uniform_buffer_dynamic_count,
163 };
164 pool_size_count += 1;
165 }
166
167 if info.uniform_texel_buffer_count > 0 {
168 pool_sizes[pool_size_count] = vk::DescriptorPoolSize {
169 ty: vk::DescriptorType::UNIFORM_TEXEL_BUFFER,
170 descriptor_count: info.uniform_texel_buffer_count,
171 };
172 pool_size_count += 1;
173 }
174
175 let handle = unsafe {
176 device.create_descriptor_pool(
177 &vk::DescriptorPoolCreateInfo::default()
178 .flags(vk::DescriptorPoolCreateFlags::FREE_DESCRIPTOR_SET)
179 .max_sets(info.max_sets)
180 .pool_sizes(&pool_sizes[0..pool_size_count]),
181 None,
182 )
183 }
184 .map_err(|err| {
185 warn!("unable to create descriptor pool: {err}");
186
187 match err {
188 vk::Result::ERROR_OUT_OF_DEVICE_MEMORY | vk::Result::ERROR_OUT_OF_HOST_MEMORY => {
189 DriverError::OutOfMemory
190 }
191 _ => DriverError::Unsupported,
192 }
193 })?;
194
195 Ok(Self {
196 device,
197 handle,
198 info,
199 })
200 }
201
202 pub(crate) fn allocate_descriptor_set(
203 this: &Self,
204 layout: &DescriptorSetLayout,
205 ) -> Result<RawDescriptorSet, DriverError> {
206 Ok(Self::allocate_descriptor_sets(this, layout, 1)?
207 .next()
208 .expect("missing descriptor set"))
209 }
210
211 #[profiling::function]
212 pub(crate) fn allocate_descriptor_sets<'a>(
213 &'a self,
214 layout: &DescriptorSetLayout,
215 count: u32,
216 ) -> Result<impl Iterator<Item = RawDescriptorSet> + 'a, DriverError> {
217 let layout_handles = vec![layout.handle(); count as usize];
218 let create_info = vk::DescriptorSetAllocateInfo::default()
219 .descriptor_pool(self.handle)
220 .set_layouts(&layout_handles);
221
222 Ok(unsafe {
223 self.device
224 .allocate_descriptor_sets(&create_info)
225 .map_err(|err| {
226 use {DriverError::*, vk::Result as vk};
227
228 warn!("unable to allocate descriptor sets: {err}");
229
230 match err {
231 e if e == vk::ERROR_FRAGMENTED_POOL => InvalidData,
232 e if e == vk::ERROR_OUT_OF_DEVICE_MEMORY => OutOfMemory,
233 e if e == vk::ERROR_OUT_OF_HOST_MEMORY => OutOfMemory,
234 e if e == vk::ERROR_OUT_OF_POOL_MEMORY => OutOfMemory,
235 _ => Unsupported,
236 }
237 })?
238 .into_iter()
239 .map(move |descriptor_set| RawDescriptorSet {
240 descriptor_pool: self.handle,
241 descriptor_set,
242 device: self.device.clone(),
243 })
244 })
245 }
246}
247
248impl Drop for DescriptorPool {
249 #[profiling::function]
250 fn drop(&mut self) {
251 if panicking() {
252 return;
253 }
254
255 unsafe {
256 self.device.destroy_descriptor_pool(self.handle, None);
257 }
258 }
259}
260
261#[derive(Clone, Debug, Default, Eq, Hash, PartialEq)]
266pub(crate) struct DescriptorPoolInfo {
267 pub(crate) acceleration_structure_count: u32,
268 pub(crate) combined_image_sampler_count: u32,
269 pub(crate) input_attachment_count: u32,
270 pub(crate) max_sets: u32,
271 pub(crate) sampled_image_count: u32,
272 pub(crate) sampler_count: u32,
273 pub(crate) storage_buffer_count: u32,
274 pub(crate) storage_buffer_dynamic_count: u32,
275 pub(crate) storage_image_count: u32,
276 pub(crate) storage_texel_buffer_count: u32,
277 pub(crate) uniform_buffer_count: u32,
278 pub(crate) uniform_buffer_dynamic_count: u32,
279 pub(crate) uniform_texel_buffer_count: u32,
280}
281
282impl DescriptorPoolInfo {
283 fn for_layout(layout: &DescriptorSetLayout) -> Result<Self, DriverError> {
284 let mut info = Self {
285 max_sets: 1,
286 ..Default::default()
287 };
288
289 for binding in &layout.info().bindings {
290 let count = binding.descriptor_count;
291 let destination = match binding.descriptor_type {
292 vk::DescriptorType::ACCELERATION_STRUCTURE_KHR => {
293 &mut info.acceleration_structure_count
294 }
295 vk::DescriptorType::COMBINED_IMAGE_SAMPLER => {
296 &mut info.combined_image_sampler_count
297 }
298 vk::DescriptorType::INPUT_ATTACHMENT => &mut info.input_attachment_count,
299 vk::DescriptorType::SAMPLED_IMAGE => &mut info.sampled_image_count,
300 vk::DescriptorType::SAMPLER => &mut info.sampler_count,
301 vk::DescriptorType::STORAGE_BUFFER => &mut info.storage_buffer_count,
302 vk::DescriptorType::STORAGE_BUFFER_DYNAMIC => {
303 &mut info.storage_buffer_dynamic_count
304 }
305 vk::DescriptorType::STORAGE_IMAGE => &mut info.storage_image_count,
306 vk::DescriptorType::STORAGE_TEXEL_BUFFER => &mut info.storage_texel_buffer_count,
307 vk::DescriptorType::UNIFORM_BUFFER => &mut info.uniform_buffer_count,
308 vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC => {
309 &mut info.uniform_buffer_dynamic_count
310 }
311 vk::DescriptorType::UNIFORM_TEXEL_BUFFER => &mut info.uniform_texel_buffer_count,
312 _ => {
313 warn!(
314 "unsupported descriptor type {:?} in descriptor set layout",
315 binding.descriptor_type
316 );
317 return Err(DriverError::Unsupported);
318 }
319 };
320 *destination = destination
321 .checked_add(count)
322 .ok_or(DriverError::InvalidData)?;
323 }
324
325 Ok(info)
326 }
327}
328
329#[derive(Clone)]
335pub struct DescriptorSet {
336 inner: Arc<DescriptorSetInner>,
337}
338
339impl DescriptorSet {
340 #[profiling::function]
349 pub fn alloc_and_update<P, I>(
350 pipeline: &P,
351 info: impl Into<DescriptorSetInfo>,
352 updates: I,
353 ) -> Result<Self, DriverError>
354 where
355 P: DescriptorSetPipeline + ?Sized,
356 I: IntoIterator<Item = DescriptorSetUpdateInfo>,
357 {
358 let info = info.into();
359 let pipeline_info = descriptor_set_private::Sealed::descriptor_info(pipeline);
360 let device = descriptor_set_private::Sealed::device(pipeline);
361 let layout = pipeline_info
362 .layouts
363 .get(&info.set)
364 .ok_or_else(|| {
365 warn!("pipeline descriptor set {} does not exist", info.set);
366 DriverError::InvalidData
367 })?
368 .clone();
369 Self::validate_layout(&layout)?;
370 let updates = updates.into_iter().collect::<Vec<_>>();
371 let mut writes = Vec::with_capacity(updates.len());
372 let mut copies = Vec::with_capacity(updates.len());
373
374 for update in updates {
375 let destination_info = Self::validate_binding(&layout, update.destination, 1)?;
376 let descriptor_type = destination_info.descriptor_type;
377
378 match update.update {
379 DescriptorSetUpdate::AccelerationStructure(resource) => {
380 if descriptor_type != vk::DescriptorType::ACCELERATION_STRUCTURE_KHR
381 || !Device::is_same(device, &resource.buffer.device)
382 || !matches!(
383 resource.info.acceleration_structure_type,
384 vk::AccelerationStructureTypeKHR::GENERIC
385 | vk::AccelerationStructureTypeKHR::TOP_LEVEL
386 )
387 {
388 warn!("invalid acceleration structure descriptor write");
389 return Err(DriverError::InvalidData);
390 }
391
392 writes.push(PreparedWrite::AccelerationStructure {
393 destination: update.destination,
394 descriptor_type,
395 resource,
396 });
397 }
398 DescriptorSetUpdate::Buffer { buffer, range } => {
399 let (required_usage, required_alignment, max_range) = match descriptor_type {
400 vk::DescriptorType::STORAGE_BUFFER => (
401 vk::BufferUsageFlags::STORAGE_BUFFER,
402 device
403 .physical
404 .properties_v1_0
405 .limits
406 .min_storage_buffer_offset_alignment,
407 vk::DeviceSize::from(
408 device
409 .physical
410 .properties_v1_0
411 .limits
412 .max_storage_buffer_range,
413 ),
414 ),
415 vk::DescriptorType::UNIFORM_BUFFER => (
416 vk::BufferUsageFlags::UNIFORM_BUFFER,
417 device
418 .physical
419 .properties_v1_0
420 .limits
421 .min_uniform_buffer_offset_alignment,
422 vk::DeviceSize::from(
423 device
424 .physical
425 .properties_v1_0
426 .limits
427 .max_uniform_buffer_range,
428 ),
429 ),
430 _ => {
431 warn!("invalid buffer descriptor type {descriptor_type:?}");
432 return Err(DriverError::InvalidData);
433 }
434 };
435 let range_size = if range.end == vk::WHOLE_SIZE {
436 buffer.info.size.saturating_sub(range.start)
437 } else {
438 range.end.saturating_sub(range.start)
439 };
440
441 if !Device::is_same(device, &buffer.device)
442 || !buffer.info.usage.contains(required_usage)
443 || range.start >= buffer.info.size
444 || range.end != vk::WHOLE_SIZE
445 && (range.end <= range.start || range.end > buffer.info.size)
446 || required_alignment > 1 && range.start % required_alignment != 0
447 || range_size == 0
448 || range_size > max_range
449 {
450 warn!("invalid buffer descriptor write");
451 return Err(DriverError::InvalidData);
452 }
453
454 writes.push(PreparedWrite::Buffer {
455 destination: update.destination,
456 descriptor_type,
457 resource: buffer,
458 range,
459 });
460 }
461 DescriptorSetUpdate::Copy {
462 descriptor_count,
463 source,
464 source_binding,
465 } => {
466 let destination_info =
467 Self::validate_binding(&layout, update.destination, descriptor_count)?;
468 let source_info = Self::validate_binding(
469 &source.inner.layout,
470 source_binding,
471 descriptor_count,
472 )?;
473
474 if !Device::is_same(device, source.device())
475 || source_info.descriptor_type != destination_info.descriptor_type
476 || destination_info.descriptor_type == vk::DescriptorType::SAMPLER
477 && destination_info.immutable_sampler.is_some()
478 {
479 warn!("invalid descriptor copy");
480 return Err(DriverError::InvalidData);
481 }
482
483 copies.push(PreparedCopy {
484 descriptor_count,
485 destination: update.destination,
486 source,
487 source_binding,
488 });
489 }
490 DescriptorSetUpdate::Image { image, view } => {
491 let image_layout = Self::image_layout(descriptor_type).ok_or_else(|| {
492 warn!("invalid image descriptor write");
493 DriverError::InvalidData
494 })?;
495 let required_usage = match descriptor_type {
496 vk::DescriptorType::COMBINED_IMAGE_SAMPLER
497 | vk::DescriptorType::SAMPLED_IMAGE => vk::ImageUsageFlags::SAMPLED,
498 vk::DescriptorType::STORAGE_IMAGE => vk::ImageUsageFlags::STORAGE,
499 _ => {
500 warn!("invalid image descriptor type {descriptor_type:?}");
501 return Err(DriverError::InvalidData);
502 }
503 };
504 let image_aspects = format_aspect_mask(image.info.format);
505 let mip_level_count = if view.mip_level_count == vk::REMAINING_MIP_LEVELS {
506 image
507 .info
508 .mip_level_count
509 .saturating_sub(view.base_mip_level)
510 } else {
511 view.mip_level_count
512 };
513 let array_layer_count = if view.array_layer_count == vk::REMAINING_ARRAY_LAYERS
514 {
515 image
516 .info
517 .array_layer_count
518 .saturating_sub(view.base_array_layer)
519 } else {
520 view.array_layer_count
521 };
522
523 if !Device::is_same(device, &image.device)
524 || !image.info.usage.contains(required_usage)
525 || view.format == vk::Format::UNDEFINED
526 || view.aspect_mask.as_raw().count_ones() != 1
527 || !image_aspects.contains(view.aspect_mask)
528 || view.base_mip_level >= image.info.mip_level_count
529 || mip_level_count == 0
530 || mip_level_count > image.info.mip_level_count - view.base_mip_level
531 || view.base_array_layer >= image.info.array_layer_count
532 || array_layer_count == 0
533 || array_layer_count > image.info.array_layer_count - view.base_array_layer
534 || view.format != image.info.format
535 && !image
536 .info
537 .flags
538 .contains(vk::ImageCreateFlags::MUTABLE_FORMAT)
539 {
540 warn!("invalid image descriptor write");
541 return Err(DriverError::InvalidData);
542 }
543
544 let image_view = image.view(view)?;
545 writes.push(PreparedWrite::Image {
546 destination: update.destination,
547 descriptor_type,
548 image_layout,
549 image_view,
550 resource: image,
551 });
552 }
553 }
554 }
555
556 let descriptor_pool =
557 DescriptorPool::create(device, DescriptorPoolInfo::for_layout(&layout)?)?;
558 let descriptor_set = DescriptorPool::allocate_descriptor_set(&descriptor_pool, &layout)?;
559 let handle = *descriptor_set;
560
561 for write in &writes {
562 unsafe {
563 match write {
564 PreparedWrite::AccelerationStructure {
565 destination,
566 descriptor_type,
567 resource,
568 } => {
569 let acceleration_structures = [resource.handle];
570 let mut acceleration_structure_info =
571 vk::WriteDescriptorSetAccelerationStructureKHR::default()
572 .acceleration_structures(&acceleration_structures);
573 let write = vk::WriteDescriptorSet::default()
574 .dst_set(handle)
575 .dst_binding(destination.binding)
576 .dst_array_element(destination.array_element)
577 .descriptor_type(*descriptor_type)
578 .descriptor_count(1)
579 .push_next(&mut acceleration_structure_info);
580 device.update_descriptor_sets(slice::from_ref(&write), &[]);
581 }
582 PreparedWrite::Buffer {
583 destination,
584 descriptor_type,
585 resource,
586 range,
587 } => {
588 let range_size = if range.end == vk::WHOLE_SIZE {
589 vk::WHOLE_SIZE
590 } else {
591 range.end - range.start
592 };
593 let buffer_info = vk::DescriptorBufferInfo::default()
594 .buffer(resource.handle)
595 .offset(range.start)
596 .range(range_size);
597 let write = vk::WriteDescriptorSet::default()
598 .dst_set(handle)
599 .dst_binding(destination.binding)
600 .dst_array_element(destination.array_element)
601 .descriptor_type(*descriptor_type)
602 .buffer_info(slice::from_ref(&buffer_info));
603 device.update_descriptor_sets(slice::from_ref(&write), &[]);
604 }
605 PreparedWrite::Image {
606 destination,
607 descriptor_type,
608 image_layout,
609 image_view,
610 ..
611 } => {
612 let image_info = vk::DescriptorImageInfo::default()
613 .image_layout(*image_layout)
614 .image_view(*image_view);
615 let write = vk::WriteDescriptorSet::default()
616 .dst_set(handle)
617 .dst_binding(destination.binding)
618 .dst_array_element(destination.array_element)
619 .descriptor_type(*descriptor_type)
620 .image_info(slice::from_ref(&image_info));
621 device.update_descriptor_sets(slice::from_ref(&write), &[]);
622 }
623 }
624 }
625 }
626
627 if !copies.is_empty() {
628 let copy_infos = copies
629 .iter()
630 .map(|copy| {
631 vk::CopyDescriptorSet::default()
632 .src_set(copy.source.handle())
633 .src_binding(copy.source_binding.binding)
634 .src_array_element(copy.source_binding.array_element)
635 .dst_set(handle)
636 .dst_binding(copy.destination.binding)
637 .dst_array_element(copy.destination.array_element)
638 .descriptor_count(copy.descriptor_count)
639 })
640 .collect::<Vec<_>>();
641
642 unsafe {
643 device.update_descriptor_sets(&[], ©_infos);
644 }
645 }
646
647 let resources = writes
648 .into_iter()
649 .map(|write| match write {
650 PreparedWrite::AccelerationStructure { resource, .. } => {
651 DescriptorSetResource::AccelerationStructure(resource)
652 }
653 PreparedWrite::Buffer { resource, .. } => DescriptorSetResource::Buffer(resource),
654 PreparedWrite::Image { resource, .. } => DescriptorSetResource::Image(resource),
655 })
656 .chain(
657 copies
658 .into_iter()
659 .map(|copy| DescriptorSetResource::DescriptorSet(copy.source)),
660 )
661 .collect();
662
663 Ok(Self {
664 inner: Arc::new(DescriptorSetInner {
665 descriptor_set,
666 _descriptor_pool: descriptor_pool,
667 info,
668 layout,
669 _resources: resources,
670 }),
671 })
672 }
673
674 pub fn device(&self) -> &Device {
676 self.inner.layout.device()
677 }
678
679 pub fn handle(&self) -> vk::DescriptorSet {
681 *self.inner.descriptor_set
682 }
683
684 pub fn info(&self) -> DescriptorSetInfo {
686 self.inner.info
687 }
688
689 pub fn set_debug_name(&self, name: impl AsRef<str>) {
691 Device::try_set_debug_utils_object_name(self.device(), self.handle(), &name);
692 Device::try_set_private_data_object_name(
693 self.device(),
694 vk::ObjectType::DESCRIPTOR_SET,
695 self.handle(),
696 &name,
697 );
698 }
699
700 pub fn with_debug_name(self, name: impl AsRef<str>) -> Self {
702 self.set_debug_name(name);
703
704 self
705 }
706
707 pub(crate) fn is_compatible(&self, set: u32, layout: &DescriptorSetLayout) -> bool {
708 self.inner.info.set == set && self.inner.layout.is_same(layout)
709 }
710
711 fn validate_layout(layout: &DescriptorSetLayout) -> Result<(), DriverError> {
712 for binding in &layout.info().bindings {
713 if matches!(
714 binding.descriptor_type,
715 vk::DescriptorType::INPUT_ATTACHMENT
716 | vk::DescriptorType::STORAGE_BUFFER_DYNAMIC
717 | vk::DescriptorType::STORAGE_TEXEL_BUFFER
718 | vk::DescriptorType::UNIFORM_BUFFER_DYNAMIC
719 | vk::DescriptorType::UNIFORM_TEXEL_BUFFER
720 ) {
721 warn!(
722 "descriptor set layout contains unsupported descriptor type {:?}",
723 binding.descriptor_type
724 );
725 return Err(DriverError::Unsupported);
726 }
727 }
728
729 Ok(())
730 }
731
732 fn image_layout(descriptor_type: vk::DescriptorType) -> Option<vk::ImageLayout> {
733 match descriptor_type {
734 vk::DescriptorType::COMBINED_IMAGE_SAMPLER | vk::DescriptorType::SAMPLED_IMAGE => {
735 Some(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL)
736 }
737 vk::DescriptorType::STORAGE_IMAGE => Some(vk::ImageLayout::GENERAL),
738 _ => None,
739 }
740 }
741
742 fn validate_binding(
743 layout: &DescriptorSetLayout,
744 binding: DescriptorSetBinding,
745 descriptor_count: u32,
746 ) -> Result<&super::descriptor_set_layout::DescriptorSetLayoutBindingInfo, DriverError> {
747 let binding_info = layout.info().binding(binding.binding).ok_or_else(|| {
748 warn!("descriptor binding {} does not exist", binding.binding);
749 DriverError::InvalidData
750 })?;
751 let end = binding
752 .array_element
753 .checked_add(descriptor_count)
754 .ok_or(DriverError::InvalidData)?;
755
756 if descriptor_count == 0 || end > binding_info.descriptor_count {
757 warn!(
758 "descriptor binding {} array range {}..{} is out of bounds",
759 binding.binding, binding.array_element, end
760 );
761 return Err(DriverError::InvalidData);
762 }
763
764 Ok(binding_info)
765 }
766}
767
768impl Debug for DescriptorSet {
769 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
770 let mut result = f.debug_struct(stringify!(DescriptorSet));
771
772 if let Some(debug_name) = &Device::private_data_object_name(
773 self.device(),
774 vk::ObjectType::DESCRIPTOR_SET,
775 self.handle(),
776 ) {
777 result.field("debug_name", debug_name);
778 }
779
780 result
781 .field("handle", &self.handle())
782 .field("info", &self.info())
783 .finish()
784 }
785}
786
787#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
789pub struct DescriptorSetBinding {
790 pub binding: u32,
792
793 pub array_element: u32,
795}
796
797impl From<u32> for DescriptorSetBinding {
798 fn from(binding: u32) -> Self {
799 Self {
800 binding,
801 array_element: 0,
802 }
803 }
804}
805
806impl From<(u32, u32)> for DescriptorSetBinding {
807 fn from((binding, array_element): (u32, u32)) -> Self {
808 Self {
809 binding,
810 array_element,
811 }
812 }
813}
814
815impl From<(u32, [u32; 1])> for DescriptorSetBinding {
816 fn from((binding, [array_element]): (u32, [u32; 1])) -> Self {
817 Self {
818 binding,
819 array_element,
820 }
821 }
822}
823
824#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
828pub struct DescriptorSetInfo {
829 pub set: u32,
831}
832
833impl DescriptorSetInfo {
834 pub const fn builder() -> DescriptorSetInfoBuilder {
836 DescriptorSetInfoBuilder { set: 0 }
837 }
838
839 pub const fn into_builder(self) -> DescriptorSetInfoBuilder {
841 DescriptorSetInfoBuilder { set: self.set }
842 }
843}
844
845impl From<DescriptorSetInfoBuilder> for DescriptorSetInfo {
846 fn from(info: DescriptorSetInfoBuilder) -> Self {
847 info.build()
848 }
849}
850
851#[derive(Clone, Copy, Debug, Default)]
853pub struct DescriptorSetInfoBuilder {
854 set: u32,
855}
856
857impl DescriptorSetInfoBuilder {
858 pub const fn set(mut self, set: u32) -> Self {
860 self.set = set;
861 self
862 }
863
864 pub const fn build(self) -> DescriptorSetInfo {
866 DescriptorSetInfo { set: self.set }
867 }
868}
869
870struct DescriptorSetInner {
871 descriptor_set: RawDescriptorSet,
872 _descriptor_pool: DescriptorPool,
873 info: DescriptorSetInfo,
874 layout: DescriptorSetLayout,
875 _resources: Box<[DescriptorSetResource]>,
876}
877
878impl Drop for DescriptorSetInner {
879 fn drop(&mut self) {
880 if panicking() {
881 return;
882 }
883
884 Device::try_clear_private_data_object_name(
885 self.layout.device(),
886 vk::ObjectType::DESCRIPTOR_SET,
887 *self.descriptor_set,
888 );
889 }
890}
891
892#[allow(dead_code)]
893enum DescriptorSetResource {
894 AccelerationStructure(Arc<AccelerationStructure>),
895 Buffer(Arc<Buffer>),
896 DescriptorSet(DescriptorSet),
897 Image(Arc<Image>),
898}
899
900#[derive(Clone, Debug)]
901enum DescriptorSetUpdate {
902 AccelerationStructure(Arc<AccelerationStructure>),
903 Buffer {
904 buffer: Arc<Buffer>,
905 range: BufferSubresourceRange,
906 },
907 Copy {
908 descriptor_count: u32,
909 source: DescriptorSet,
910 source_binding: DescriptorSetBinding,
911 },
912 Image {
913 image: Arc<Image>,
914 view: ImageViewInfo,
915 },
916}
917
918#[derive(Clone, Debug)]
920pub struct DescriptorSetUpdateInfo {
921 destination: DescriptorSetBinding,
922 update: DescriptorSetUpdate,
923}
924
925impl DescriptorSetUpdateInfo {
926 pub fn acceleration_structure(
928 destination: impl Into<DescriptorSetBinding>,
929 acceleration_structure: &Arc<AccelerationStructure>,
930 ) -> Self {
931 Self {
932 destination: destination.into(),
933 update: DescriptorSetUpdate::AccelerationStructure(acceleration_structure.clone()),
934 }
935 }
936
937 pub fn buffer(destination: impl Into<DescriptorSetBinding>, buffer: &Arc<Buffer>) -> Self {
939 Self::buffer_range(destination, buffer, buffer.info)
940 }
941
942 pub fn buffer_range(
944 destination: impl Into<DescriptorSetBinding>,
945 buffer: &Arc<Buffer>,
946 range: impl Into<BufferSubresourceRange>,
947 ) -> Self {
948 Self {
949 destination: destination.into(),
950 update: DescriptorSetUpdate::Buffer {
951 buffer: buffer.clone(),
952 range: range.into(),
953 },
954 }
955 }
956
957 pub fn copy(
959 source: &DescriptorSet,
960 source_binding: impl Into<DescriptorSetBinding>,
961 destination: impl Into<DescriptorSetBinding>,
962 ) -> Self {
963 Self::copy_many(source, source_binding, destination, 1)
964 }
965
966 pub fn copy_many(
970 source: &DescriptorSet,
971 source_binding: impl Into<DescriptorSetBinding>,
972 destination: impl Into<DescriptorSetBinding>,
973 descriptor_count: u32,
974 ) -> Self {
975 Self {
976 destination: destination.into(),
977 update: DescriptorSetUpdate::Copy {
978 descriptor_count,
979 source: source.clone(),
980 source_binding: source_binding.into(),
981 },
982 }
983 }
984
985 pub fn image(destination: impl Into<DescriptorSetBinding>, image: &Arc<Image>) -> Self {
989 Self::image_view(destination, image, image.info)
990 }
991
992 pub fn image_view(
994 destination: impl Into<DescriptorSetBinding>,
995 image: &Arc<Image>,
996 view: impl Into<ImageViewInfo>,
997 ) -> Self {
998 Self {
999 destination: destination.into(),
1000 update: DescriptorSetUpdate::Image {
1001 image: image.clone(),
1002 view: view.into(),
1003 },
1004 }
1005 }
1006}
1007
1008impl IntoIterator for DescriptorSetUpdateInfo {
1009 type Item = Self;
1010 type IntoIter = iter::Once<Self>;
1011
1012 fn into_iter(self) -> Self::IntoIter {
1013 iter::once(self)
1014 }
1015}
1016
1017impl IntoIterator for &DescriptorSetUpdateInfo {
1018 type Item = DescriptorSetUpdateInfo;
1019 type IntoIter = iter::Once<Self::Item>;
1020
1021 fn into_iter(self) -> Self::IntoIter {
1022 iter::once(self.clone())
1023 }
1024}
1025
1026#[doc(hidden)]
1028pub trait DescriptorSetPipeline: descriptor_set_private::Sealed {}
1029
1030macro_rules! descriptor_set_pipeline {
1031 ($pipeline:ty) => {
1032 #[allow(private_interfaces)]
1033 impl descriptor_set_private::Sealed for $pipeline {
1034 fn descriptor_info(&self) -> &PipelineDescriptorInfo {
1035 &self.inner.descriptor_info
1036 }
1037
1038 fn device(&self) -> &Device {
1039 self.device()
1040 }
1041 }
1042
1043 impl DescriptorSetPipeline for $pipeline {}
1044 };
1045}
1046
1047descriptor_set_pipeline!(ComputePipeline);
1048descriptor_set_pipeline!(GraphicsPipeline);
1049descriptor_set_pipeline!(RayTracingPipeline);
1050
1051#[allow(private_interfaces)]
1052mod descriptor_set_private {
1053 use super::{Device, PipelineDescriptorInfo};
1054
1055 pub trait Sealed {
1056 fn descriptor_info(&self) -> &PipelineDescriptorInfo;
1057
1058 fn device(&self) -> &Device;
1059 }
1060}
1061
1062enum PreparedWrite {
1063 AccelerationStructure {
1064 destination: DescriptorSetBinding,
1065 descriptor_type: vk::DescriptorType,
1066 resource: Arc<AccelerationStructure>,
1067 },
1068 Buffer {
1069 destination: DescriptorSetBinding,
1070 descriptor_type: vk::DescriptorType,
1071 resource: Arc<Buffer>,
1072 range: BufferSubresourceRange,
1073 },
1074 Image {
1075 destination: DescriptorSetBinding,
1076 descriptor_type: vk::DescriptorType,
1077 image_layout: vk::ImageLayout,
1078 image_view: vk::ImageView,
1079 resource: Arc<Image>,
1080 },
1081}
1082
1083struct PreparedCopy {
1084 descriptor_count: u32,
1085 destination: DescriptorSetBinding,
1086 source: DescriptorSet,
1087 source_binding: DescriptorSetBinding,
1088}
1089
1090#[derive(Debug)]
1091pub(crate) struct RawDescriptorSet {
1092 descriptor_pool: vk::DescriptorPool,
1093 descriptor_set: vk::DescriptorSet,
1094 device: Device,
1095}
1096
1097impl Deref for RawDescriptorSet {
1098 type Target = vk::DescriptorSet;
1099
1100 fn deref(&self) -> &Self::Target {
1101 &self.descriptor_set
1102 }
1103}
1104
1105impl Drop for RawDescriptorSet {
1106 #[profiling::function]
1107 fn drop(&mut self) {
1108 if panicking() {
1109 return;
1110 }
1111
1112 if let Err(err) = unsafe {
1113 self.device
1114 .free_descriptor_sets(self.descriptor_pool, slice::from_ref(&self.descriptor_set))
1115 } {
1116 warn!("unable to free descriptor set: {err}");
1117 }
1118 }
1119}
1120
1121#[cfg(test)]
1122mod test {
1123 use super::*;
1124
1125 #[test]
1126 fn descriptor_set_binding_conversions() {
1127 assert_eq!(
1128 DescriptorSetBinding::from(3),
1129 DescriptorSetBinding {
1130 binding: 3,
1131 array_element: 0,
1132 }
1133 );
1134 assert_eq!(
1135 DescriptorSetBinding::from((3, [7])),
1136 DescriptorSetBinding {
1137 binding: 3,
1138 array_element: 7,
1139 }
1140 );
1141 }
1142
1143 #[test]
1144 fn descriptor_set_info_builder() {
1145 let info = DescriptorSetInfo::builder().set(2).build();
1146
1147 assert_eq!(info.set, 2);
1148 assert_eq!(info, info.into_builder().build());
1149 assert_eq!(
1150 std::mem::size_of::<DescriptorSetInfo>(),
1151 std::mem::size_of::<u32>()
1152 );
1153 }
1154
1155 #[test]
1156 fn empty_descriptor_set_updates_are_inferred() {
1157 fn update_count(updates: impl IntoIterator<Item = DescriptorSetUpdateInfo>) -> usize {
1158 updates.into_iter().count()
1159 }
1160
1161 assert_eq!(update_count([]), 0);
1162 assert_eq!(update_count(None), 0);
1163 }
1164}