vk_sync/
cmd.rs

1use super::*;
2use ash;
3
4/// Simplified wrapper around `vkCmdPipelineBarrier`.
5/// The mapping functions defined above are used to translate the passed in
6/// barrier definitions into a set of pipeline stages and native Vulkan memory
7/// barriers to be passed to `vkCmdPipelineBarrier`.
8/// `command_buffer` is passed unmodified to `vkCmdPipelineBarrier`.
9pub fn pipeline_barrier(
10	device: &ash::vk::DeviceFnV1_0,
11	command_buffer: ash::vk::CommandBuffer,
12	global_barrier: Option<GlobalBarrier>,
13	buffer_barriers: &[BufferBarrier],
14	image_barriers: &[ImageBarrier],
15) {
16	let mut src_stage_mask = ash::vk::PipelineStageFlags::TOP_OF_PIPE;
17	let mut dst_stage_mask = ash::vk::PipelineStageFlags::BOTTOM_OF_PIPE;
18
19	// TODO: Optimize out the Vec heap allocations
20	let mut vk_memory_barriers: Vec<ash::vk::MemoryBarrier> = Vec::with_capacity(1);
21	let mut vk_buffer_barriers: Vec<ash::vk::BufferMemoryBarrier> =
22		Vec::with_capacity(buffer_barriers.len());
23	let mut vk_image_barriers: Vec<ash::vk::ImageMemoryBarrier> =
24		Vec::with_capacity(image_barriers.len());
25
26	// Global memory barrier
27	if let Some(ref barrier) = global_barrier {
28		let (src_mask, dst_mask, barrier) = get_memory_barrier(barrier);
29		src_stage_mask |= src_mask;
30		dst_stage_mask |= dst_mask;
31		vk_memory_barriers.push(barrier);
32	}
33
34	// Buffer memory barriers
35	for buffer_barrier in buffer_barriers {
36		let (src_mask, dst_mask, barrier) = get_buffer_memory_barrier(buffer_barrier);
37		src_stage_mask |= src_mask;
38		dst_stage_mask |= dst_mask;
39		vk_buffer_barriers.push(barrier);
40	}
41
42	// Image memory barriers
43	for image_barrier in image_barriers {
44		let (src_mask, dst_mask, barrier) = get_image_memory_barrier(image_barrier);
45		src_stage_mask |= src_mask;
46		dst_stage_mask |= dst_mask;
47		vk_image_barriers.push(barrier);
48	}
49
50	unsafe {
51		device.cmd_pipeline_barrier(
52			command_buffer,
53			src_stage_mask,
54			dst_stage_mask,
55			ash::vk::DependencyFlags::empty(),
56			vk_memory_barriers.len() as u32,
57			vk_memory_barriers.as_ptr(),
58			vk_buffer_barriers.len() as u32,
59			vk_buffer_barriers.as_ptr(),
60			vk_image_barriers.len() as u32,
61			vk_image_barriers.as_ptr(),
62		);
63	}
64}
65
66/// Wrapper around `vkCmdSetEvent`.
67/// Sets an event when the accesses defined by `previous_accesses` are completed.
68/// `command_buffer` and `event` are passed unmodified to `vkCmdSetEvent`.
69pub fn set_event(
70	device: &ash::vk::DeviceFnV1_0,
71	command_buffer: ash::vk::CommandBuffer,
72	event: ash::vk::Event,
73	previous_accesses: &[AccessType],
74) {
75	let mut stage_mask = ash::vk::PipelineStageFlags::TOP_OF_PIPE;
76	for previous_access in previous_accesses {
77		let previous_info = get_access_info(*previous_access);
78		stage_mask |= previous_info.stage_mask;
79	}
80
81	unsafe {
82		device.cmd_set_event(command_buffer, event, stage_mask);
83	}
84}
85
86/// Wrapper around `vkCmdResetEvent`.
87/// Resets an event when the accesses defined by `previous_accesses` are completed.
88/// `command_buffer` and `event` are passed unmodified to `vkCmdResetEvent`.
89pub fn reset_event(
90	device: &ash::vk::DeviceFnV1_0,
91	command_buffer: ash::vk::CommandBuffer,
92	event: ash::vk::Event,
93	previous_accesses: &[AccessType],
94) {
95	let mut stage_mask = ash::vk::PipelineStageFlags::TOP_OF_PIPE;
96	for previous_access in previous_accesses {
97		let previous_info = get_access_info(*previous_access);
98		stage_mask |= previous_info.stage_mask;
99	}
100
101	unsafe {
102		device.cmd_reset_event(command_buffer, event, stage_mask);
103	}
104}
105
106/// Simplified wrapper around `vkCmdWaitEvents`.
107/// The mapping functions defined above are used to translate the passed in
108/// barrier definitions into a set of pipeline stages and native Vulkan memory
109/// barriers to be passed to `vkCmdPipelineBarrier`.
110///
111/// `commandBuffer` and `events` are passed unmodified to `vkCmdWaitEvents`.
112pub fn wait_events(
113	device: &ash::vk::DeviceFnV1_0,
114	command_buffer: ash::vk::CommandBuffer,
115	events: &[ash::vk::Event],
116	global_barrier: Option<GlobalBarrier>,
117	buffer_barriers: &[BufferBarrier],
118	image_barriers: &[ImageBarrier],
119) {
120	let mut src_stage_mask = ash::vk::PipelineStageFlags::TOP_OF_PIPE;
121	let mut dst_stage_mask = ash::vk::PipelineStageFlags::BOTTOM_OF_PIPE;
122
123	// TODO: Optimize out the Vec heap allocations
124	let mut vk_memory_barriers: Vec<ash::vk::MemoryBarrier> = Vec::with_capacity(1);
125	let mut vk_buffer_barriers: Vec<ash::vk::BufferMemoryBarrier> =
126		Vec::with_capacity(buffer_barriers.len());
127	let mut vk_image_barriers: Vec<ash::vk::ImageMemoryBarrier> =
128		Vec::with_capacity(image_barriers.len());
129
130	// Global memory barrier
131	if let Some(ref barrier) = global_barrier {
132		let (src_mask, dst_mask, barrier) = get_memory_barrier(barrier);
133		src_stage_mask |= src_mask;
134		dst_stage_mask |= dst_mask;
135		vk_memory_barriers.push(barrier);
136	}
137
138	// Buffer memory barriers
139	for buffer_barrier in buffer_barriers {
140		let (src_mask, dst_mask, barrier) = get_buffer_memory_barrier(buffer_barrier);
141		src_stage_mask |= src_mask;
142		dst_stage_mask |= dst_mask;
143		vk_buffer_barriers.push(barrier);
144	}
145
146	// Image memory barriers
147	for image_barrier in image_barriers {
148		let (src_mask, dst_mask, barrier) = get_image_memory_barrier(image_barrier);
149		src_stage_mask |= src_mask;
150		dst_stage_mask |= dst_mask;
151		vk_image_barriers.push(barrier);
152	}
153
154	unsafe {
155		device.cmd_wait_events(
156			command_buffer,
157			events.len() as u32,
158			events.as_ptr(),
159			src_stage_mask,
160			dst_stage_mask,
161			vk_memory_barriers.len() as u32,
162			vk_memory_barriers.as_ptr(),
163			vk_buffer_barriers.len() as u32,
164			vk_buffer_barriers.as_ptr(),
165			vk_image_barriers.len() as u32,
166			vk_image_barriers.as_ptr(),
167		);
168	}
169}