1use bedrock_vk::{self as brvk, TypedVulkanStructure};
2
3use crate::*;
4#[cfg(feature = "VK_KHR_synchronization2")]
5use ffi_helper::slice_as_ptr_empty_null;
6
7#[cfg(feature = "VK_KHR_synchronization2")]
8#[repr(transparent)]
9#[derive(Clone, Debug)]
10pub struct MemoryBarrier2(brvk::VkMemoryBarrier2KHR);
11#[cfg(feature = "VK_KHR_synchronization2")]
12impl MemoryBarrier2 {
13 pub const fn new() -> Self {
14 Self(brvk::VkMemoryBarrier2KHR {
15 sType: brvk::VkMemoryBarrier2KHR::TYPE,
16 pNext: core::ptr::null(),
17 srcStageMask: brvk::VK_PIPELINE_STAGE_2_NONE_KHR,
18 srcAccessMask: brvk::VK_ACCESS_2_NONE_KHR,
19 dstStageMask: brvk::VK_PIPELINE_STAGE_2_NONE_KHR,
20 dstAccessMask: brvk::VK_ACCESS_2_NONE_KHR,
21 })
22 }
23
24 pub const fn from(mut self, stage: PipelineStageFlags2, access: AccessFlags2) -> Self {
25 self.0.srcStageMask = stage.0;
26 self.0.srcAccessMask = access.0;
27 self
28 }
29
30 pub const fn to(mut self, stage: PipelineStageFlags2, access: AccessFlags2) -> Self {
31 self.0.dstStageMask = stage.0;
32 self.0.dstAccessMask = access.0;
33 self
34 }
35
36 pub const fn of_execution(mut self, src: PipelineStageFlags2, dst: PipelineStageFlags2) -> Self {
37 self.0.srcStageMask = src.0;
38 self.0.dstStageMask = dst.0;
39 self
40 }
41
42 pub const fn of_memory(mut self, src: AccessFlags2, dst: AccessFlags2) -> Self {
43 self.0.srcAccessMask = src.0;
44 self.0.dstAccessMask = dst.0;
45 self
46 }
47}
48
49#[cfg(feature = "VK_KHR_synchronization2")]
50#[repr(transparent)]
51#[derive(Clone, Debug)]
52pub struct BufferMemoryBarrier2<'b>(
53 brvk::VkBufferMemoryBarrier2KHR,
54 core::marker::PhantomData<&'b dyn VkHandle<Handle = brvk::VkBuffer>>,
55);
56#[cfg(feature = "VK_KHR_synchronization2")]
57impl<'b> BufferMemoryBarrier2<'b> {
58 pub fn new(
59 buffer: &'b (impl VkHandle<Handle = brvk::VkBuffer> + ?Sized),
60 range: core::ops::Range<DeviceSize>,
61 ) -> Self {
62 Self(
63 brvk::VkBufferMemoryBarrier2KHR {
64 sType: brvk::VkBufferMemoryBarrier2KHR::TYPE,
65 pNext: core::ptr::null(),
66 srcStageMask: brvk::VK_PIPELINE_STAGE_2_NONE_KHR,
67 srcAccessMask: brvk::VK_ACCESS_2_NONE_KHR,
68 dstStageMask: brvk::VK_PIPELINE_STAGE_2_NONE_KHR,
69 dstAccessMask: brvk::VK_ACCESS_2_NONE_KHR,
70 srcQueueFamilyIndex: brvk::VK_QUEUE_FAMILY_IGNORED,
71 dstQueueFamilyIndex: brvk::VK_QUEUE_FAMILY_IGNORED,
72 buffer: buffer.native_ptr(),
73 offset: range.start,
74 size: range.end - range.start,
75 },
76 core::marker::PhantomData,
77 )
78 }
79
80 pub const fn from(mut self, stage: PipelineStageFlags2, access: AccessFlags2) -> Self {
81 self.0.srcStageMask = stage.0;
82 self.0.srcAccessMask = access.0;
83 self
84 }
85
86 pub const fn to(mut self, stage: PipelineStageFlags2, access: AccessFlags2) -> Self {
87 self.0.dstStageMask = stage.0;
88 self.0.dstAccessMask = access.0;
89 self
90 }
91
92 pub const fn of_execution(mut self, src: PipelineStageFlags2, dst: PipelineStageFlags2) -> Self {
93 self.0.srcStageMask = src.0;
94 self.0.dstStageMask = dst.0;
95 self
96 }
97
98 pub const fn of_memory(mut self, src: AccessFlags2, dst: AccessFlags2) -> Self {
99 self.0.srcAccessMask = src.0;
100 self.0.dstAccessMask = dst.0;
101 self
102 }
103
104 pub const fn transferring_queue_family(mut self, from: u32, to: u32) -> Self {
105 self.0.srcQueueFamilyIndex = from;
106 self.0.dstQueueFamilyIndex = to;
107 self
108 }
109}
110
111#[cfg(feature = "VK_KHR_synchronization2")]
112#[repr(transparent)]
113#[derive(Clone)]
114pub struct ImageMemoryBarrier2<'r>(
115 brvk::VkImageMemoryBarrier2KHR,
116 core::marker::PhantomData<&'r dyn VkHandle<Handle = brvk::VkImage>>,
117);
118#[cfg(feature = "VK_KHR_synchronization2")]
119impl<'r> ImageMemoryBarrier2<'r> {
120 pub fn new(
121 image: &'r (impl VkHandle<Handle = brvk::VkImage> + ?Sized),
122 subresource_range: ImageSubresourceRange,
123 ) -> Self {
124 Self(
125 brvk::VkImageMemoryBarrier2KHR {
126 sType: brvk::VkImageMemoryBarrier2KHR::TYPE,
127 pNext: core::ptr::null(),
128 srcStageMask: brvk::VK_PIPELINE_STAGE_2_NONE_KHR,
129 srcAccessMask: brvk::VK_ACCESS_2_NONE_KHR,
130 dstStageMask: brvk::VK_PIPELINE_STAGE_2_NONE_KHR,
131 dstAccessMask: brvk::VK_ACCESS_2_NONE_KHR,
132 oldLayout: brvk::VK_IMAGE_LAYOUT_UNDEFINED,
133 newLayout: brvk::VK_IMAGE_LAYOUT_UNDEFINED,
134 srcQueueFamilyIndex: brvk::VK_QUEUE_FAMILY_IGNORED,
135 dstQueueFamilyIndex: brvk::VK_QUEUE_FAMILY_IGNORED,
136 image: image.native_ptr(),
137 subresourceRange: subresource_range.0,
138 },
139 core::marker::PhantomData,
140 )
141 }
142
143 pub const fn from(mut self, stage: PipelineStageFlags2, access: AccessFlags2) -> Self {
144 self.0.srcStageMask = stage.0;
145 self.0.srcAccessMask = access.0;
146 self
147 }
148
149 pub const fn to(mut self, stage: PipelineStageFlags2, access: AccessFlags2) -> Self {
150 self.0.dstStageMask = stage.0;
151 self.0.dstAccessMask = access.0;
152 self
153 }
154
155 pub const fn of_execution(mut self, src: PipelineStageFlags2, dst: PipelineStageFlags2) -> Self {
156 self.0.srcStageMask = src.0;
157 self.0.dstStageMask = dst.0;
158 self
159 }
160
161 pub const fn of_memory(mut self, src: AccessFlags2, dst: AccessFlags2) -> Self {
162 self.0.srcAccessMask = src.0;
163 self.0.dstAccessMask = dst.0;
164 self
165 }
166
167 pub const fn transferring_layout(mut self, from: ImageLayout, to: ImageLayout) -> Self {
168 self.0.oldLayout = from as _;
169 self.0.newLayout = to as _;
170 self
171 }
172 pub const fn transit_from(self, trans: LayoutTransition) -> Self {
173 self.transferring_layout(trans.from, trans.to)
174 }
175 pub const fn transit_to(self, trans: LayoutTransition) -> Self {
176 self.transferring_layout(trans.from, trans.to)
177 }
178
179 pub const fn transferring_queue_family(mut self, from: u32, to: u32) -> Self {
180 self.0.srcQueueFamilyIndex = from;
181 self.0.dstQueueFamilyIndex = to;
182 self
183 }
184}
185
186#[cfg(feature = "VK_KHR_synchronization2")]
187#[repr(transparent)]
188#[derive(Debug, Clone)]
189pub struct DependencyInfo<'b, 'r>(
190 brvk::VkDependencyInfoKHR,
191 core::marker::PhantomData<(
192 &'b [MemoryBarrier2],
193 &'b [BufferMemoryBarrier2<'r>],
194 &'b [ImageMemoryBarrier2<'r>],
195 )>,
196);
197#[cfg(feature = "VK_KHR_synchronization2")]
198impl<'b, 'r> DependencyInfo<'b, 'r> {
199 pub const fn new(
200 memory_barriers: &'b [MemoryBarrier2],
201 buffer_memory_barriers: &'b [BufferMemoryBarrier2<'r>],
202 image_memory_barriers: &'b [ImageMemoryBarrier2<'r>],
203 ) -> Self {
204 Self(
205 brvk::VkDependencyInfoKHR {
206 sType: brvk::VkDependencyInfoKHR::TYPE,
207 pNext: core::ptr::null(),
208 dependencyFlags: 0,
209 memoryBarrierCount: memory_barriers.len() as _,
210 pMemoryBarriers: slice_as_ptr_empty_null(memory_barriers).cast(),
211 bufferMemoryBarrierCount: buffer_memory_barriers.len() as _,
212 pBufferMemoryBarriers: slice_as_ptr_empty_null(buffer_memory_barriers).cast(),
213 imageMemoryBarrierCount: image_memory_barriers.len() as _,
214 pImageMemoryBarriers: slice_as_ptr_empty_null(image_memory_barriers).cast(),
215 },
216 core::marker::PhantomData,
217 )
218 }
219
220 pub const fn by_region(mut self) -> Self {
221 self.0.dependencyFlags |= brvk::VK_DEPENDENCY_BY_REGION_BIT;
222 self
223 }
224}