1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::sync::{
	atomic::{self, AtomicBool},
	Arc, Barrier,
};
use vulkano::image::{
	sys::UnsafeImageView,
	traits::{ImageAccess, ImageViewAccess},
	Dimensions, ImageLayout,
};

/// An abstraction on ImageViewAccess to provide a lease like function. This
/// simply wraps ImageViewAccess and provides a barrier that will be used when the
/// wrapper drops. The provided barrier should have wait() called before dropping.
pub struct TmpImageViewAccess {
	inner: Arc<dyn ImageViewAccess + Send + Sync>,
	barrier: Option<Arc<Barrier>>,
	abool: Option<Arc<AtomicBool>>,
}

impl TmpImageViewAccess {
	pub fn new(from: Arc<dyn ImageViewAccess + Send + Sync>) -> (Self, Arc<Barrier>) {
		let barrier = Arc::new(Barrier::new(2));

		(
			TmpImageViewAccess {
				inner: from,
				barrier: Some(barrier.clone()),
				abool: None,
			},
			barrier,
		)
	}

	pub fn new_abool(from: Arc<dyn ImageViewAccess + Send + Sync>) -> (Self, Arc<AtomicBool>) {
		let abool = Arc::new(AtomicBool::new(true));

		(
			TmpImageViewAccess {
				inner: from,
				barrier: None,
				abool: Some(abool.clone()),
			},
			abool,
		)
	}
}

impl Drop for TmpImageViewAccess {
	fn drop(&mut self) {
		if let Some(abool) = self.abool.take() {
			abool.store(false, atomic::Ordering::Relaxed);
		}

		if let Some(barrier) = self.barrier.take() {
			barrier.wait();
		}
	}
}

unsafe impl ImageViewAccess for TmpImageViewAccess {
	fn parent(&self) -> &dyn ImageAccess {
		self.inner.parent()
	}

	fn dimensions(&self) -> Dimensions {
		self.inner.dimensions()
	}

	fn inner(&self) -> &UnsafeImageView {
		self.inner.inner()
	}

	fn descriptor_set_storage_image_layout(&self) -> ImageLayout {
		self.inner.descriptor_set_storage_image_layout()
	}

	fn descriptor_set_combined_image_sampler_layout(&self) -> ImageLayout {
		self.inner.descriptor_set_combined_image_sampler_layout()
	}

	fn descriptor_set_sampled_image_layout(&self) -> ImageLayout {
		self.inner.descriptor_set_sampled_image_layout()
	}

	fn descriptor_set_input_attachment_layout(&self) -> ImageLayout {
		self.inner.descriptor_set_input_attachment_layout()
	}

	fn identity_swizzle(&self) -> bool {
		self.inner.identity_swizzle()
	}
}