Skip to main content

maia/command_buffer/
barrier.rs

1// Copyright 2022 Google LLC
2
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9#![allow(clippy::too_many_arguments)]
10use crate::buffer::Buffer;
11use crate::enums::*;
12use crate::ffi::Array;
13use crate::image::Image;
14use crate::types::*;
15
16use super::{CommandRecording, RenderPassRecording, SecondaryCommandRecording};
17
18#[doc = crate::man_link!(VkBufferMemoryBarrier)]
19pub struct BufferMemoryBarrier<'a> {
20    pub src_access_mask: AccessFlags,
21    pub dst_access_mask: AccessFlags,
22    pub src_queue_family_index: u32,
23    pub dst_queue_family_index: u32,
24    pub buffer: &'a Arc<Buffer>,
25    pub offset: u64,
26    pub size: u64,
27}
28impl<'a> BufferMemoryBarrier<'a> {
29    fn vk(&self) -> VkBufferMemoryBarrier {
30        VkBufferMemoryBarrier {
31            stype: Default::default(),
32            next: Default::default(),
33            src_access_mask: self.src_access_mask,
34            dst_access_mask: self.dst_access_mask,
35            src_queue_family_index: self.src_queue_family_index,
36            dst_queue_family_index: self.dst_queue_family_index,
37            buffer: self.buffer.handle(),
38            offset: self.offset,
39            size: self.size,
40        }
41    }
42}
43
44#[doc = crate::man_link!(VkImageMemoryBarrier)]
45pub struct ImageMemoryBarrier<'a> {
46    pub src_access_mask: AccessFlags,
47    pub dst_access_mask: AccessFlags,
48    pub old_layout: ImageLayout,
49    pub new_layout: ImageLayout,
50    pub src_queue_family_index: u32,
51    pub dst_queue_family_index: u32,
52    pub image: &'a Arc<Image>,
53    pub subresource_range: ImageSubresourceRange,
54}
55impl<'a> ImageMemoryBarrier<'a> {
56    fn vk(&self) -> VkImageMemoryBarrier {
57        VkImageMemoryBarrier {
58            stype: Default::default(),
59            next: Default::default(),
60            src_access_mask: self.src_access_mask,
61            dst_access_mask: self.dst_access_mask,
62            old_layout: self.old_layout,
63            new_layout: self.new_layout,
64            src_queue_family_index: self.src_queue_family_index,
65            dst_queue_family_index: self.dst_queue_family_index,
66            image: self.image.handle(),
67            subresource_range: self.subresource_range,
68        }
69    }
70}
71
72impl<'a> RenderPassRecording<'a> {
73    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
74    pub fn pipeline_barrier(
75        &mut self, src_stage_mask: PipelineStageFlags,
76        dst_stage_mask: PipelineStageFlags, dependency_flags: DependencyFlags,
77        memory_barriers: &[MemoryBarrier],
78        buffer_memory_barriers: &[BufferMemoryBarrier],
79        image_memory_barriers: &[ImageMemoryBarrier],
80    ) {
81        self.rec.pipeline_barrier(
82            src_stage_mask,
83            dst_stage_mask,
84            dependency_flags,
85            memory_barriers,
86            buffer_memory_barriers,
87            image_memory_barriers,
88        )
89    }
90    /// A shortcut for simple memory barriers
91    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
92    pub fn memory_barrier(
93        &mut self, src_stage_mask: PipelineStageFlags,
94        dst_stage_mask: PipelineStageFlags, src_access_mask: AccessFlags,
95        dst_access_mask: AccessFlags,
96    ) {
97        self.rec.memory_barrier(
98            src_stage_mask,
99            dst_stage_mask,
100            src_access_mask,
101            dst_access_mask,
102        )
103    }
104    /// A shortcut for simple image barriers
105    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
106    pub fn image_barrier(
107        &mut self, image: &Arc<Image>, src_stage_mask: PipelineStageFlags,
108        dst_stage_mask: PipelineStageFlags, src_access_mask: AccessFlags,
109        dst_access_mask: AccessFlags, old_layout: ImageLayout,
110        new_layout: ImageLayout,
111    ) {
112        self.rec.image_barrier(
113            image,
114            src_stage_mask,
115            dst_stage_mask,
116            src_access_mask,
117            dst_access_mask,
118            old_layout,
119            new_layout,
120        )
121    }
122}
123
124impl<'a> SecondaryCommandRecording<'a> {
125    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
126    pub fn pipeline_barrier(
127        &mut self, src_stage_mask: PipelineStageFlags,
128        dst_stage_mask: PipelineStageFlags, dependency_flags: DependencyFlags,
129        memory_barriers: &[MemoryBarrier],
130        buffer_memory_barriers: &[BufferMemoryBarrier],
131        image_memory_barriers: &[ImageMemoryBarrier],
132    ) {
133        self.rec.pipeline_barrier(
134            src_stage_mask,
135            dst_stage_mask,
136            dependency_flags,
137            memory_barriers,
138            buffer_memory_barriers,
139            image_memory_barriers,
140        )
141    }
142    /// A shortcut for simple memory barriers.
143    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
144    pub fn memory_barrier(
145        &mut self, src_stage_mask: PipelineStageFlags,
146        dst_stage_mask: PipelineStageFlags, src_access_mask: AccessFlags,
147        dst_access_mask: AccessFlags,
148    ) {
149        self.rec.memory_barrier(
150            src_stage_mask,
151            dst_stage_mask,
152            src_access_mask,
153            dst_access_mask,
154        )
155    }
156    /// A shortcut for simple image barriers.
157    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
158    pub fn image_barrier(
159        &mut self, image: &Arc<Image>, src_stage_mask: PipelineStageFlags,
160        dst_stage_mask: PipelineStageFlags, src_access_mask: AccessFlags,
161        dst_access_mask: AccessFlags, old_layout: ImageLayout,
162        new_layout: ImageLayout,
163    ) {
164        self.rec.image_barrier(
165            image,
166            src_stage_mask,
167            dst_stage_mask,
168            src_access_mask,
169            dst_access_mask,
170            old_layout,
171            new_layout,
172        )
173    }
174}
175
176impl<'a> CommandRecording<'a> {
177    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
178    pub fn pipeline_barrier(
179        &mut self, src_stage_mask: PipelineStageFlags,
180        dst_stage_mask: PipelineStageFlags, dependency_flags: DependencyFlags,
181        memory_barriers: &[MemoryBarrier],
182        buffer_memory_barriers: &[BufferMemoryBarrier],
183        image_memory_barriers: &[ImageMemoryBarrier],
184    ) {
185        for b in buffer_memory_barriers {
186            self.add_resource(b.buffer.clone());
187        }
188        for b in image_memory_barriers {
189            self.add_resource(b.image.clone());
190        }
191        let vk_buffer_barriers = self.scratch.alloc_slice_fill_iter(
192            buffer_memory_barriers.iter().map(|b| b.vk()),
193        );
194        let vk_image_barriers = self.scratch.alloc_slice_fill_iter(
195            image_memory_barriers.iter().map(|b| b.vk()),
196        );
197
198        unsafe {
199            (self.pool.device.fun.cmd_pipeline_barrier)(
200                self.buffer.handle.borrow_mut(),
201                src_stage_mask,
202                dst_stage_mask,
203                dependency_flags,
204                memory_barriers.len() as u32,
205                Array::from_slice(memory_barriers),
206                vk_buffer_barriers.len() as u32,
207                Array::from_slice(vk_buffer_barriers),
208                vk_image_barriers.len() as u32,
209                Array::from_slice(vk_image_barriers),
210            )
211        }
212    }
213
214    /// A shortcut for simple memory barriers.
215    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
216    pub fn memory_barrier(
217        &mut self, src_stage_mask: PipelineStageFlags,
218        dst_stage_mask: PipelineStageFlags, src_access_mask: AccessFlags,
219        dst_access_mask: AccessFlags,
220    ) {
221        unsafe {
222            (self.pool.device.fun.cmd_pipeline_barrier)(
223                self.buffer.handle.borrow_mut(),
224                src_stage_mask,
225                dst_stage_mask,
226                Default::default(),
227                1,
228                Some(Array::from(&[MemoryBarrier {
229                    src_access_mask,
230                    dst_access_mask,
231                    ..Default::default()
232                }])),
233                0,
234                None,
235                0,
236                None,
237            )
238        }
239    }
240
241    /// A shortcut for simple image barriers.
242    #[doc = crate::man_link!(vkCmdPipelineBarrier)]
243    pub fn image_barrier(
244        &mut self, image: &Arc<Image>, src_stage_mask: PipelineStageFlags,
245        dst_stage_mask: PipelineStageFlags, src_access_mask: AccessFlags,
246        dst_access_mask: AccessFlags, old_layout: ImageLayout,
247        new_layout: ImageLayout,
248    ) {
249        self.add_resource(image.clone());
250        unsafe {
251            let barrier = VkImageMemoryBarrier {
252                stype: Default::default(),
253                next: Default::default(),
254                src_access_mask,
255                dst_access_mask,
256                old_layout,
257                new_layout,
258                src_queue_family_index: Default::default(),
259                dst_queue_family_index: Default::default(),
260                image: image.handle(),
261                subresource_range: Default::default(),
262            };
263            (self.pool.device.fun.cmd_pipeline_barrier)(
264                self.buffer.handle.borrow_mut(),
265                src_stage_mask,
266                dst_stage_mask,
267                Default::default(),
268                0,
269                None,
270                0,
271                None,
272                1,
273                Array::from_slice(&[barrier]),
274            )
275        }
276    }
277}