Skip to main content

vk_graph/driver/
mod.rs

1//! Vulkan interface based on smart pointers.
2//!
3//! # Resources
4//!
5//! Resources are created and destroyed using RAII-style wrapper structures.
6//!
7//! The following resources are available:
8//!
9//! - [`AccelerationStructure`](accel_struct::AccelerationStructure)
10//! - [`Buffer`]
11//! - [`Image`](image::Image)
12//!
13//! Resources are logically mutable. All resource types contain useful read-only public fields, for
14//! example:
15//!
16//! [`Buffer`] Field|`->`
17//! -|-
18//! [`device`](Buffer::device)|[`Device`](device::Device)
19//! [`handle`](Buffer::handle)|[`vk::Buffer`]
20//! [`info`](Buffer::info)|[`BufferInfo`]
21//!
22//! Resources use atomic [`AccessType`](sync::AccessType) values to maintain consistency and track
23//! changes.
24//!
25//! # Pipelines
26//!
27//! Pipelines enable reading and writing resources using shader code running on physical graphics
28//! hardware.
29//!
30//! The following pipelines are available:
31//!
32//! - [`ComputePipeline`](compute::ComputePipeline)
33//! - [`GraphicPipeline`](graphic::GraphicPipeline)
34//! - [`RayTracePipeline`](ray_trace::RayTracePipeline)
35//!
36//! Pipelines are immutable. All pipeline types contain useful public methods, for
37//! example:
38//!
39//! [`ComputePipeline`](compute::ComputePipeline) Method | `->`
40//! -|-
41//! [`device(&self)`](compute::ComputePipeline::device)|[`Device`](device::Device)
42//! [`handle(&self)`](compute::ComputePipeline::handle)|[`vk::Pipeline`]
43//! [`info(&self)`](compute::ComputePipeline::info)
44//! | [`ComputePipelineInfo`](compute::ComputePipelineInfo)
45
46pub mod accel_struct;
47pub mod buffer;
48pub mod cmd_buf;
49pub mod compute;
50pub mod device;
51pub mod graphic;
52pub mod image;
53pub mod instance;
54pub mod physical_device;
55pub mod ray_trace;
56pub mod render_pass;
57pub mod shader;
58pub mod surface;
59pub mod swapchain;
60
61#[doc(hidden)]
62pub mod descriptor_set;
63
64mod descriptor_set_layout;
65
66pub use {
67    ash::{self},
68    vk_sync::{self as sync},
69};
70
71#[deprecated = "Use driver::render_pass::ResolveMode instead"]
72#[doc(hidden)]
73pub type ResolveMode = self::render_pass::ResolveMode;
74
75pub(crate) use self::{
76    descriptor_set::DescriptorSet,
77    descriptor_set_layout::DescriptorSetLayout,
78    render_pass::{
79        AttachmentInfo, AttachmentRef, FramebufferAttachmentImageInfo, FramebufferInfo,
80        SubpassDependency, SubpassInfo,
81    },
82    shader::{Descriptor, DescriptorBindingMap, DescriptorInfo},
83    surface::Surface,
84};
85
86use {
87    self::{
88        buffer::{Buffer, BufferInfo},
89        graphic::VertexInputState,
90    },
91    ash::vk,
92    gpu_allocator::AllocationError,
93    std::{
94        cmp::Ordering,
95        error::Error,
96        fmt::{Display, Formatter},
97    },
98};
99
100// When removing, fix all the extra-overly-qualiified references in this file
101#[deprecated = "use from sync module"]
102#[doc(hidden)]
103pub type AccessType = self::sync::AccessType;
104
105pub(super) const fn format_aspect_mask(fmt: vk::Format) -> vk::ImageAspectFlags {
106    match fmt {
107        vk::Format::D16_UNORM | vk::Format::D32_SFLOAT | vk::Format::X8_D24_UNORM_PACK32 => {
108            vk::ImageAspectFlags::DEPTH
109        }
110        vk::Format::S8_UINT => vk::ImageAspectFlags::STENCIL,
111        vk::Format::D16_UNORM_S8_UINT
112        | vk::Format::D24_UNORM_S8_UINT
113        | vk::Format::D32_SFLOAT_S8_UINT => vk::ImageAspectFlags::from_raw(
114            vk::ImageAspectFlags::DEPTH.as_raw() | vk::ImageAspectFlags::STENCIL.as_raw(),
115        ),
116        _ => vk::ImageAspectFlags::COLOR,
117    }
118}
119
120/// Returns number of bytes used to store one texel block (a single addressable element of an
121/// uncompressed image, or a single compressed block of a compressed image).
122///
123/// See the [Texel Block Size](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#texel-block-size)
124/// section of the Vulkan specification.
125pub const fn format_texel_block_size(fmt: vk::Format) -> u32 {
126    match fmt {
127        vk::Format::UNDEFINED => 0,
128        vk::Format::R4G4_UNORM_PACK8
129        | vk::Format::R8_UNORM
130        | vk::Format::R8_SNORM
131        | vk::Format::R8_USCALED
132        | vk::Format::R8_SSCALED
133        | vk::Format::R8_UINT
134        | vk::Format::R8_SINT
135        | vk::Format::R8_SRGB => 1,
136        vk::Format::A1B5G5R5_UNORM_PACK16_KHR
137        | vk::Format::R10X6_UNORM_PACK16
138        | vk::Format::R12X4_UNORM_PACK16
139        | vk::Format::A4R4G4B4_UNORM_PACK16
140        | vk::Format::A4B4G4R4_UNORM_PACK16
141        | vk::Format::R4G4B4A4_UNORM_PACK16
142        | vk::Format::B4G4R4A4_UNORM_PACK16
143        | vk::Format::R5G6B5_UNORM_PACK16
144        | vk::Format::B5G6R5_UNORM_PACK16
145        | vk::Format::R5G5B5A1_UNORM_PACK16
146        | vk::Format::B5G5R5A1_UNORM_PACK16
147        | vk::Format::A1R5G5B5_UNORM_PACK16
148        | vk::Format::R8G8_UNORM
149        | vk::Format::R8G8_SNORM
150        | vk::Format::R8G8_USCALED
151        | vk::Format::R8G8_SSCALED
152        | vk::Format::R8G8_UINT
153        | vk::Format::R8G8_SINT
154        | vk::Format::R8G8_SRGB
155        | vk::Format::R16_UNORM
156        | vk::Format::R16_SNORM
157        | vk::Format::R16_USCALED
158        | vk::Format::R16_SSCALED
159        | vk::Format::R16_UINT
160        | vk::Format::R16_SINT
161        | vk::Format::R16_SFLOAT => 2,
162        vk::Format::A8_UNORM_KHR => 1,
163        vk::Format::R8G8B8_UNORM
164        | vk::Format::R8G8B8_SNORM
165        | vk::Format::R8G8B8_USCALED
166        | vk::Format::R8G8B8_SSCALED
167        | vk::Format::R8G8B8_UINT
168        | vk::Format::R8G8B8_SINT
169        | vk::Format::R8G8B8_SRGB
170        | vk::Format::B8G8R8_UNORM
171        | vk::Format::B8G8R8_SNORM
172        | vk::Format::B8G8R8_USCALED
173        | vk::Format::B8G8R8_SSCALED
174        | vk::Format::B8G8R8_UINT
175        | vk::Format::B8G8R8_SINT
176        | vk::Format::B8G8R8_SRGB => 3,
177        vk::Format::R10X6G10X6_UNORM_2PACK16
178        | vk::Format::R12X4G12X4_UNORM_2PACK16
179        | vk::Format::R16G16_S10_5_NV
180        | vk::Format::R8G8B8A8_UNORM
181        | vk::Format::R8G8B8A8_SNORM
182        | vk::Format::R8G8B8A8_USCALED
183        | vk::Format::R8G8B8A8_SSCALED
184        | vk::Format::R8G8B8A8_UINT
185        | vk::Format::R8G8B8A8_SINT
186        | vk::Format::R8G8B8A8_SRGB
187        | vk::Format::B8G8R8A8_UNORM
188        | vk::Format::B8G8R8A8_SNORM
189        | vk::Format::B8G8R8A8_USCALED
190        | vk::Format::B8G8R8A8_SSCALED
191        | vk::Format::B8G8R8A8_UINT
192        | vk::Format::B8G8R8A8_SINT
193        | vk::Format::B8G8R8A8_SRGB
194        | vk::Format::A8B8G8R8_UNORM_PACK32
195        | vk::Format::A8B8G8R8_SNORM_PACK32
196        | vk::Format::A8B8G8R8_USCALED_PACK32
197        | vk::Format::A8B8G8R8_SSCALED_PACK32
198        | vk::Format::A8B8G8R8_UINT_PACK32
199        | vk::Format::A8B8G8R8_SINT_PACK32
200        | vk::Format::A8B8G8R8_SRGB_PACK32
201        | vk::Format::A2R10G10B10_UNORM_PACK32
202        | vk::Format::A2R10G10B10_SNORM_PACK32
203        | vk::Format::A2R10G10B10_USCALED_PACK32
204        | vk::Format::A2R10G10B10_SSCALED_PACK32
205        | vk::Format::A2R10G10B10_UINT_PACK32
206        | vk::Format::A2R10G10B10_SINT_PACK32
207        | vk::Format::A2B10G10R10_UNORM_PACK32
208        | vk::Format::A2B10G10R10_SNORM_PACK32
209        | vk::Format::A2B10G10R10_USCALED_PACK32
210        | vk::Format::A2B10G10R10_SSCALED_PACK32
211        | vk::Format::A2B10G10R10_UINT_PACK32
212        | vk::Format::A2B10G10R10_SINT_PACK32
213        | vk::Format::R16G16_UNORM
214        | vk::Format::R16G16_SNORM
215        | vk::Format::R16G16_USCALED
216        | vk::Format::R16G16_SSCALED
217        | vk::Format::R16G16_UINT
218        | vk::Format::R16G16_SINT
219        | vk::Format::R16G16_SFLOAT
220        | vk::Format::R32_UINT
221        | vk::Format::R32_SINT
222        | vk::Format::R32_SFLOAT
223        | vk::Format::B10G11R11_UFLOAT_PACK32
224        | vk::Format::E5B9G9R9_UFLOAT_PACK32 => 4,
225        vk::Format::R16G16B16_UNORM
226        | vk::Format::R16G16B16_SNORM
227        | vk::Format::R16G16B16_USCALED
228        | vk::Format::R16G16B16_SSCALED
229        | vk::Format::R16G16B16_UINT
230        | vk::Format::R16G16B16_SINT
231        | vk::Format::R16G16B16_SFLOAT => 6,
232        vk::Format::R16G16B16A16_UNORM
233        | vk::Format::R16G16B16A16_SNORM
234        | vk::Format::R16G16B16A16_USCALED
235        | vk::Format::R16G16B16A16_SSCALED
236        | vk::Format::R16G16B16A16_UINT
237        | vk::Format::R16G16B16A16_SINT
238        | vk::Format::R16G16B16A16_SFLOAT
239        | vk::Format::R32G32_UINT
240        | vk::Format::R32G32_SINT
241        | vk::Format::R32G32_SFLOAT
242        | vk::Format::R64_UINT
243        | vk::Format::R64_SINT
244        | vk::Format::R64_SFLOAT => 8,
245        vk::Format::R32G32B32_UINT | vk::Format::R32G32B32_SINT | vk::Format::R32G32B32_SFLOAT => {
246            12
247        }
248        vk::Format::R32G32B32A32_UINT
249        | vk::Format::R32G32B32A32_SINT
250        | vk::Format::R32G32B32A32_SFLOAT
251        | vk::Format::R64G64_UINT
252        | vk::Format::R64G64_SINT
253        | vk::Format::R64G64_SFLOAT => 16,
254        vk::Format::R64G64B64_UINT | vk::Format::R64G64B64_SINT | vk::Format::R64G64B64_SFLOAT => {
255            24
256        }
257        vk::Format::R64G64B64A64_UINT
258        | vk::Format::R64G64B64A64_SINT
259        | vk::Format::R64G64B64A64_SFLOAT => 32,
260        vk::Format::D16_UNORM => 2,
261        vk::Format::X8_D24_UNORM_PACK32 => 4,
262        vk::Format::D32_SFLOAT => 4,
263        vk::Format::S8_UINT => 1,
264        vk::Format::D16_UNORM_S8_UINT => 3,
265        vk::Format::D24_UNORM_S8_UINT => 4,
266        vk::Format::D32_SFLOAT_S8_UINT => 5,
267        vk::Format::BC1_RGB_UNORM_BLOCK
268        | vk::Format::BC1_RGB_SRGB_BLOCK
269        | vk::Format::BC1_RGBA_UNORM_BLOCK
270        | vk::Format::BC1_RGBA_SRGB_BLOCK
271        | vk::Format::BC4_UNORM_BLOCK
272        | vk::Format::BC4_SNORM_BLOCK
273        | vk::Format::ETC2_R8G8B8_UNORM_BLOCK
274        | vk::Format::ETC2_R8G8B8_SRGB_BLOCK
275        | vk::Format::ETC2_R8G8B8A1_UNORM_BLOCK
276        | vk::Format::ETC2_R8G8B8A1_SRGB_BLOCK
277        | vk::Format::EAC_R11_UNORM_BLOCK
278        | vk::Format::EAC_R11_SNORM_BLOCK => 8,
279        vk::Format::BC2_UNORM_BLOCK
280        | vk::Format::BC2_SRGB_BLOCK
281        | vk::Format::BC3_UNORM_BLOCK
282        | vk::Format::BC3_SRGB_BLOCK
283        | vk::Format::BC5_UNORM_BLOCK
284        | vk::Format::BC5_SNORM_BLOCK
285        | vk::Format::BC6H_UFLOAT_BLOCK
286        | vk::Format::BC6H_SFLOAT_BLOCK
287        | vk::Format::BC7_UNORM_BLOCK
288        | vk::Format::BC7_SRGB_BLOCK
289        | vk::Format::ETC2_R8G8B8A8_UNORM_BLOCK
290        | vk::Format::ETC2_R8G8B8A8_SRGB_BLOCK
291        | vk::Format::EAC_R11G11_UNORM_BLOCK
292        | vk::Format::EAC_R11G11_SNORM_BLOCK => 16,
293        vk::Format::ASTC_4X4_SFLOAT_BLOCK
294        | vk::Format::ASTC_4X4_UNORM_BLOCK
295        | vk::Format::ASTC_4X4_SRGB_BLOCK
296        | vk::Format::ASTC_5X4_SFLOAT_BLOCK
297        | vk::Format::ASTC_5X4_UNORM_BLOCK
298        | vk::Format::ASTC_5X4_SRGB_BLOCK
299        | vk::Format::ASTC_5X5_SFLOAT_BLOCK
300        | vk::Format::ASTC_5X5_UNORM_BLOCK
301        | vk::Format::ASTC_5X5_SRGB_BLOCK
302        | vk::Format::ASTC_6X5_SFLOAT_BLOCK
303        | vk::Format::ASTC_6X5_UNORM_BLOCK
304        | vk::Format::ASTC_6X5_SRGB_BLOCK
305        | vk::Format::ASTC_6X6_SFLOAT_BLOCK
306        | vk::Format::ASTC_6X6_UNORM_BLOCK
307        | vk::Format::ASTC_6X6_SRGB_BLOCK
308        | vk::Format::ASTC_8X5_SFLOAT_BLOCK
309        | vk::Format::ASTC_8X5_UNORM_BLOCK
310        | vk::Format::ASTC_8X5_SRGB_BLOCK
311        | vk::Format::ASTC_8X6_SFLOAT_BLOCK
312        | vk::Format::ASTC_8X6_UNORM_BLOCK
313        | vk::Format::ASTC_8X6_SRGB_BLOCK
314        | vk::Format::ASTC_8X8_SFLOAT_BLOCK
315        | vk::Format::ASTC_8X8_UNORM_BLOCK
316        | vk::Format::ASTC_8X8_SRGB_BLOCK
317        | vk::Format::ASTC_10X5_SFLOAT_BLOCK
318        | vk::Format::ASTC_10X5_UNORM_BLOCK
319        | vk::Format::ASTC_10X5_SRGB_BLOCK
320        | vk::Format::ASTC_10X6_SFLOAT_BLOCK
321        | vk::Format::ASTC_10X6_UNORM_BLOCK
322        | vk::Format::ASTC_10X6_SRGB_BLOCK
323        | vk::Format::ASTC_10X8_SFLOAT_BLOCK
324        | vk::Format::ASTC_10X8_UNORM_BLOCK
325        | vk::Format::ASTC_10X8_SRGB_BLOCK
326        | vk::Format::ASTC_10X10_SFLOAT_BLOCK
327        | vk::Format::ASTC_10X10_UNORM_BLOCK
328        | vk::Format::ASTC_10X10_SRGB_BLOCK
329        | vk::Format::ASTC_12X10_SFLOAT_BLOCK
330        | vk::Format::ASTC_12X10_UNORM_BLOCK
331        | vk::Format::ASTC_12X10_SRGB_BLOCK
332        | vk::Format::ASTC_12X12_SFLOAT_BLOCK
333        | vk::Format::ASTC_12X12_UNORM_BLOCK
334        | vk::Format::ASTC_12X12_SRGB_BLOCK => 16,
335        vk::Format::G8B8G8R8_422_UNORM | vk::Format::B8G8R8G8_422_UNORM => 4,
336        vk::Format::G8_B8_R8_3PLANE_420_UNORM
337        | vk::Format::G8_B8R8_2PLANE_420_UNORM
338        | vk::Format::G8_B8_R8_3PLANE_422_UNORM
339        | vk::Format::G8_B8R8_2PLANE_422_UNORM
340        | vk::Format::G8_B8_R8_3PLANE_444_UNORM => 3,
341        vk::Format::R10X6G10X6B10X6A10X6_UNORM_4PACK16
342        | vk::Format::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
343        | vk::Format::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
344        | vk::Format::R12X4G12X4B12X4A12X4_UNORM_4PACK16
345        | vk::Format::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
346        | vk::Format::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
347        | vk::Format::G16B16G16R16_422_UNORM
348        | vk::Format::B16G16R16G16_422_UNORM => 8,
349        vk::Format::G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
350        | vk::Format::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
351        | vk::Format::G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
352        | vk::Format::G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
353        | vk::Format::G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
354        | vk::Format::G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
355        | vk::Format::G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
356        | vk::Format::G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
357        | vk::Format::G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
358        | vk::Format::G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
359        | vk::Format::G16_B16_R16_3PLANE_420_UNORM
360        | vk::Format::G16_B16R16_2PLANE_420_UNORM
361        | vk::Format::G16_B16_R16_3PLANE_422_UNORM
362        | vk::Format::G16_B16R16_2PLANE_422_UNORM
363        | vk::Format::G16_B16_R16_3PLANE_444_UNORM => 6,
364        vk::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG
365        | vk::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG
366        | vk::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG
367        | vk::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG
368        | vk::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG
369        | vk::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG
370        | vk::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG
371        | vk::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG => 8,
372        vk::Format::G8_B8R8_2PLANE_444_UNORM => 3,
373        vk::Format::G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16
374        | vk::Format::G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16
375        | vk::Format::G16_B16R16_2PLANE_444_UNORM => 6,
376        _ => panic!("unsupported texel block size format"),
377    }
378}
379
380/// Returns the extent of a block of texels for the given Vulkan format.
381/// Uncompressed formats typically have a block extent of `(1, 1)`.
382///
383/// See the [Texel Block Size](https://registry.khronos.org/vulkan/specs/latest/html/vkspec.html#texel-block-size)
384/// section of the Vulkan specification.
385pub const fn format_texel_block_extent(vk_format: vk::Format) -> (u32, u32) {
386    match vk_format {
387        vk::Format::UNDEFINED => (1, 1),
388        vk::Format::R4G4_UNORM_PACK8
389        | vk::Format::R8_UNORM
390        | vk::Format::R8_SNORM
391        | vk::Format::R8_USCALED
392        | vk::Format::R8_SSCALED
393        | vk::Format::R8_UINT
394        | vk::Format::R8_SINT
395        | vk::Format::R8_SRGB
396        | vk::Format::A1B5G5R5_UNORM_PACK16_KHR
397        | vk::Format::R10X6_UNORM_PACK16
398        | vk::Format::R12X4_UNORM_PACK16
399        | vk::Format::A4R4G4B4_UNORM_PACK16
400        | vk::Format::A4B4G4R4_UNORM_PACK16
401        | vk::Format::R4G4B4A4_UNORM_PACK16
402        | vk::Format::B4G4R4A4_UNORM_PACK16
403        | vk::Format::R5G6B5_UNORM_PACK16
404        | vk::Format::B5G6R5_UNORM_PACK16
405        | vk::Format::R5G5B5A1_UNORM_PACK16
406        | vk::Format::B5G5R5A1_UNORM_PACK16
407        | vk::Format::A1R5G5B5_UNORM_PACK16
408        | vk::Format::R8G8_UNORM
409        | vk::Format::R8G8_SNORM
410        | vk::Format::R8G8_USCALED
411        | vk::Format::R8G8_SSCALED
412        | vk::Format::R8G8_UINT
413        | vk::Format::R8G8_SINT
414        | vk::Format::R8G8_SRGB
415        | vk::Format::R16_UNORM
416        | vk::Format::R16_SNORM
417        | vk::Format::R16_USCALED
418        | vk::Format::R16_SSCALED
419        | vk::Format::R16_UINT
420        | vk::Format::R16_SINT
421        | vk::Format::R16_SFLOAT
422        | vk::Format::A8_UNORM_KHR
423        | vk::Format::R8G8B8_UNORM
424        | vk::Format::R8G8B8_SNORM
425        | vk::Format::R8G8B8_USCALED
426        | vk::Format::R8G8B8_SSCALED
427        | vk::Format::R8G8B8_UINT
428        | vk::Format::R8G8B8_SINT
429        | vk::Format::R8G8B8_SRGB
430        | vk::Format::B8G8R8_UNORM
431        | vk::Format::B8G8R8_SNORM
432        | vk::Format::B8G8R8_USCALED
433        | vk::Format::B8G8R8_SSCALED
434        | vk::Format::B8G8R8_UINT
435        | vk::Format::B8G8R8_SINT
436        | vk::Format::B8G8R8_SRGB
437        | vk::Format::R10X6G10X6_UNORM_2PACK16
438        | vk::Format::R12X4G12X4_UNORM_2PACK16
439        | vk::Format::R16G16_S10_5_NV
440        | vk::Format::R8G8B8A8_UNORM
441        | vk::Format::R8G8B8A8_SNORM
442        | vk::Format::R8G8B8A8_USCALED
443        | vk::Format::R8G8B8A8_SSCALED
444        | vk::Format::R8G8B8A8_UINT
445        | vk::Format::R8G8B8A8_SINT
446        | vk::Format::R8G8B8A8_SRGB
447        | vk::Format::B8G8R8A8_UNORM
448        | vk::Format::B8G8R8A8_SNORM
449        | vk::Format::B8G8R8A8_USCALED
450        | vk::Format::B8G8R8A8_SSCALED
451        | vk::Format::B8G8R8A8_UINT
452        | vk::Format::B8G8R8A8_SINT
453        | vk::Format::B8G8R8A8_SRGB
454        | vk::Format::A8B8G8R8_UNORM_PACK32
455        | vk::Format::A8B8G8R8_SNORM_PACK32
456        | vk::Format::A8B8G8R8_USCALED_PACK32
457        | vk::Format::A8B8G8R8_SSCALED_PACK32
458        | vk::Format::A8B8G8R8_UINT_PACK32
459        | vk::Format::A8B8G8R8_SINT_PACK32
460        | vk::Format::A8B8G8R8_SRGB_PACK32
461        | vk::Format::A2R10G10B10_UNORM_PACK32
462        | vk::Format::A2R10G10B10_SNORM_PACK32
463        | vk::Format::A2R10G10B10_USCALED_PACK32
464        | vk::Format::A2R10G10B10_SSCALED_PACK32
465        | vk::Format::A2R10G10B10_UINT_PACK32
466        | vk::Format::A2R10G10B10_SINT_PACK32
467        | vk::Format::A2B10G10R10_UNORM_PACK32
468        | vk::Format::A2B10G10R10_SNORM_PACK32
469        | vk::Format::A2B10G10R10_USCALED_PACK32
470        | vk::Format::A2B10G10R10_SSCALED_PACK32
471        | vk::Format::A2B10G10R10_UINT_PACK32
472        | vk::Format::A2B10G10R10_SINT_PACK32
473        | vk::Format::R16G16_UNORM
474        | vk::Format::R16G16_SNORM
475        | vk::Format::R16G16_USCALED
476        | vk::Format::R16G16_SSCALED
477        | vk::Format::R16G16_UINT
478        | vk::Format::R16G16_SINT
479        | vk::Format::R16G16_SFLOAT
480        | vk::Format::R32_UINT
481        | vk::Format::R32_SINT
482        | vk::Format::R32_SFLOAT
483        | vk::Format::B10G11R11_UFLOAT_PACK32
484        | vk::Format::E5B9G9R9_UFLOAT_PACK32
485        | vk::Format::R16G16B16_UNORM
486        | vk::Format::R16G16B16_SNORM
487        | vk::Format::R16G16B16_USCALED
488        | vk::Format::R16G16B16_SSCALED
489        | vk::Format::R16G16B16_UINT
490        | vk::Format::R16G16B16_SINT
491        | vk::Format::R16G16B16_SFLOAT
492        | vk::Format::R16G16B16A16_UNORM
493        | vk::Format::R16G16B16A16_SNORM
494        | vk::Format::R16G16B16A16_USCALED
495        | vk::Format::R16G16B16A16_SSCALED
496        | vk::Format::R16G16B16A16_UINT
497        | vk::Format::R16G16B16A16_SINT
498        | vk::Format::R16G16B16A16_SFLOAT
499        | vk::Format::R32G32_UINT
500        | vk::Format::R32G32_SINT
501        | vk::Format::R32G32_SFLOAT
502        | vk::Format::R64_UINT
503        | vk::Format::R64_SINT
504        | vk::Format::R64_SFLOAT
505        | vk::Format::R32G32B32_UINT
506        | vk::Format::R32G32B32_SINT
507        | vk::Format::R32G32B32_SFLOAT
508        | vk::Format::R32G32B32A32_UINT
509        | vk::Format::R32G32B32A32_SINT
510        | vk::Format::R32G32B32A32_SFLOAT
511        | vk::Format::R64G64_UINT
512        | vk::Format::R64G64_SINT
513        | vk::Format::R64G64_SFLOAT
514        | vk::Format::R64G64B64_UINT
515        | vk::Format::R64G64B64_SINT
516        | vk::Format::R64G64B64_SFLOAT
517        | vk::Format::R64G64B64A64_UINT
518        | vk::Format::R64G64B64A64_SINT
519        | vk::Format::R64G64B64A64_SFLOAT
520        | vk::Format::D16_UNORM
521        | vk::Format::X8_D24_UNORM_PACK32
522        | vk::Format::D32_SFLOAT
523        | vk::Format::S8_UINT
524        | vk::Format::D16_UNORM_S8_UINT
525        | vk::Format::D24_UNORM_S8_UINT
526        | vk::Format::D32_SFLOAT_S8_UINT => (1, 1),
527        vk::Format::BC1_RGB_UNORM_BLOCK
528        | vk::Format::BC1_RGB_SRGB_BLOCK
529        | vk::Format::BC1_RGBA_UNORM_BLOCK
530        | vk::Format::BC1_RGBA_SRGB_BLOCK
531        | vk::Format::BC2_UNORM_BLOCK
532        | vk::Format::BC2_SRGB_BLOCK
533        | vk::Format::BC3_UNORM_BLOCK
534        | vk::Format::BC3_SRGB_BLOCK
535        | vk::Format::BC4_UNORM_BLOCK
536        | vk::Format::BC4_SNORM_BLOCK
537        | vk::Format::BC5_UNORM_BLOCK
538        | vk::Format::BC5_SNORM_BLOCK
539        | vk::Format::BC6H_UFLOAT_BLOCK
540        | vk::Format::BC6H_SFLOAT_BLOCK
541        | vk::Format::BC7_UNORM_BLOCK
542        | vk::Format::BC7_SRGB_BLOCK
543        | vk::Format::ETC2_R8G8B8_UNORM_BLOCK
544        | vk::Format::ETC2_R8G8B8_SRGB_BLOCK
545        | vk::Format::ETC2_R8G8B8A1_UNORM_BLOCK
546        | vk::Format::ETC2_R8G8B8A1_SRGB_BLOCK
547        | vk::Format::ETC2_R8G8B8A8_UNORM_BLOCK
548        | vk::Format::ETC2_R8G8B8A8_SRGB_BLOCK
549        | vk::Format::EAC_R11_UNORM_BLOCK
550        | vk::Format::EAC_R11_SNORM_BLOCK
551        | vk::Format::EAC_R11G11_UNORM_BLOCK
552        | vk::Format::EAC_R11G11_SNORM_BLOCK => (4, 4),
553        vk::Format::ASTC_4X4_SFLOAT_BLOCK
554        | vk::Format::ASTC_4X4_UNORM_BLOCK
555        | vk::Format::ASTC_4X4_SRGB_BLOCK => (4, 4),
556        vk::Format::ASTC_5X4_SFLOAT_BLOCK
557        | vk::Format::ASTC_5X4_UNORM_BLOCK
558        | vk::Format::ASTC_5X4_SRGB_BLOCK => (5, 4),
559        vk::Format::ASTC_5X5_SFLOAT_BLOCK
560        | vk::Format::ASTC_5X5_UNORM_BLOCK
561        | vk::Format::ASTC_5X5_SRGB_BLOCK => (5, 5),
562        vk::Format::ASTC_6X5_SFLOAT_BLOCK
563        | vk::Format::ASTC_6X5_UNORM_BLOCK
564        | vk::Format::ASTC_6X5_SRGB_BLOCK => (6, 5),
565        vk::Format::ASTC_6X6_SFLOAT_BLOCK
566        | vk::Format::ASTC_6X6_UNORM_BLOCK
567        | vk::Format::ASTC_6X6_SRGB_BLOCK => (6, 6),
568        vk::Format::ASTC_8X5_SFLOAT_BLOCK
569        | vk::Format::ASTC_8X5_UNORM_BLOCK
570        | vk::Format::ASTC_8X5_SRGB_BLOCK => (8, 5),
571        vk::Format::ASTC_8X6_SFLOAT_BLOCK
572        | vk::Format::ASTC_8X6_UNORM_BLOCK
573        | vk::Format::ASTC_8X6_SRGB_BLOCK => (8, 6),
574        vk::Format::ASTC_8X8_SFLOAT_BLOCK
575        | vk::Format::ASTC_8X8_UNORM_BLOCK
576        | vk::Format::ASTC_8X8_SRGB_BLOCK => (8, 8),
577        vk::Format::ASTC_10X5_SFLOAT_BLOCK
578        | vk::Format::ASTC_10X5_UNORM_BLOCK
579        | vk::Format::ASTC_10X5_SRGB_BLOCK => (10, 5),
580        vk::Format::ASTC_10X6_SFLOAT_BLOCK
581        | vk::Format::ASTC_10X6_UNORM_BLOCK
582        | vk::Format::ASTC_10X6_SRGB_BLOCK => (10, 6),
583        vk::Format::ASTC_10X8_SFLOAT_BLOCK
584        | vk::Format::ASTC_10X8_UNORM_BLOCK
585        | vk::Format::ASTC_10X8_SRGB_BLOCK => (10, 8),
586        vk::Format::ASTC_10X10_SFLOAT_BLOCK
587        | vk::Format::ASTC_10X10_UNORM_BLOCK
588        | vk::Format::ASTC_10X10_SRGB_BLOCK => (10, 10),
589        vk::Format::ASTC_12X10_SFLOAT_BLOCK
590        | vk::Format::ASTC_12X10_UNORM_BLOCK
591        | vk::Format::ASTC_12X10_SRGB_BLOCK => (12, 10),
592        vk::Format::ASTC_12X12_SFLOAT_BLOCK
593        | vk::Format::ASTC_12X12_UNORM_BLOCK
594        | vk::Format::ASTC_12X12_SRGB_BLOCK => (12, 12),
595        vk::Format::G8B8G8R8_422_UNORM | vk::Format::B8G8R8G8_422_UNORM => (2, 1),
596        vk::Format::G8_B8_R8_3PLANE_420_UNORM
597        | vk::Format::G8_B8R8_2PLANE_420_UNORM
598        | vk::Format::G8_B8_R8_3PLANE_422_UNORM
599        | vk::Format::G8_B8R8_2PLANE_422_UNORM
600        | vk::Format::G8_B8_R8_3PLANE_444_UNORM
601        | vk::Format::R10X6G10X6B10X6A10X6_UNORM_4PACK16
602        | vk::Format::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
603        | vk::Format::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
604        | vk::Format::G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
605        | vk::Format::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
606        | vk::Format::G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
607        | vk::Format::G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
608        | vk::Format::G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
609        | vk::Format::R12X4G12X4B12X4A12X4_UNORM_4PACK16
610        | vk::Format::G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
611        | vk::Format::G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
612        | vk::Format::G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
613        | vk::Format::G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
614        | vk::Format::G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
615        | vk::Format::G16_B16_R16_3PLANE_420_UNORM
616        | vk::Format::G16_B16R16_2PLANE_420_UNORM
617        | vk::Format::G16_B16_R16_3PLANE_422_UNORM
618        | vk::Format::G16_B16R16_2PLANE_422_UNORM
619        | vk::Format::G16_B16_R16_3PLANE_444_UNORM
620        | vk::Format::G8_B8R8_2PLANE_444_UNORM
621        | vk::Format::G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16
622        | vk::Format::G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16
623        | vk::Format::G16_B16R16_2PLANE_444_UNORM => (1, 1),
624        vk::Format::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
625        | vk::Format::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
626        | vk::Format::G16B16G16R16_422_UNORM
627        | vk::Format::B16G16R16G16_422_UNORM => (2, 1),
628        vk::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG
629        | vk::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG
630        | vk::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG
631        | vk::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG => (8, 4),
632        vk::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG
633        | vk::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG
634        | vk::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG
635        | vk::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG => (4, 4),
636        _ => panic!("unsupported texel block extent format"),
637    }
638}
639
640pub(super) const fn image_subresource_range_from_layers(
641    vk::ImageSubresourceLayers {
642        aspect_mask,
643        mip_level,
644        base_array_layer,
645        layer_count,
646    }: vk::ImageSubresourceLayers,
647) -> vk::ImageSubresourceRange {
648    vk::ImageSubresourceRange {
649        aspect_mask,
650        base_mip_level: mip_level,
651        level_count: 1,
652        base_array_layer,
653        layer_count,
654    }
655}
656
657pub(super) const fn initial_image_layout_access(
658    ty: self::sync::AccessType,
659) -> self::sync::AccessType {
660    use self::sync::AccessType::*;
661    match ty {
662        DepthStencilAttachmentReadWrite => DepthStencilAttachmentRead,
663        _ => ty,
664    }
665}
666
667pub(super) const fn is_read_access(ty: self::sync::AccessType) -> bool {
668    use self::sync::AccessType::*;
669    match ty {
670        Nothing
671        | CommandBufferWriteNVX
672        | VertexShaderWrite
673        | TessellationControlShaderWrite
674        | TessellationEvaluationShaderWrite
675        | GeometryShaderWrite
676        | FragmentShaderWrite
677        | ColorAttachmentWrite
678        | DepthStencilAttachmentWrite
679        | ComputeShaderWrite
680        | AnyShaderWrite
681        | TransferWrite
682        | HostWrite
683        | AccelerationStructureBuildWrite
684        | AccelerationStructureBufferWrite
685        | MeshShaderWrite
686        | TaskShaderWrite => false,
687        CommandBufferReadNVX
688        | IndirectBuffer
689        | IndexBuffer
690        | VertexBuffer
691        | VertexShaderReadUniformBuffer
692        | VertexShaderReadSampledImageOrUniformTexelBuffer
693        | VertexShaderReadOther
694        | TessellationControlShaderReadUniformBuffer
695        | TessellationControlShaderReadSampledImageOrUniformTexelBuffer
696        | TessellationControlShaderReadOther
697        | TessellationEvaluationShaderReadUniformBuffer
698        | TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer
699        | TessellationEvaluationShaderReadOther
700        | GeometryShaderReadUniformBuffer
701        | GeometryShaderReadSampledImageOrUniformTexelBuffer
702        | GeometryShaderReadOther
703        | FragmentShaderReadUniformBuffer
704        | FragmentShaderReadSampledImageOrUniformTexelBuffer
705        | FragmentShaderReadColorInputAttachment
706        | FragmentShaderReadDepthStencilInputAttachment
707        | FragmentShaderReadOther
708        | ColorAttachmentRead
709        | DepthStencilAttachmentRead
710        | ComputeShaderReadUniformBuffer
711        | ComputeShaderReadSampledImageOrUniformTexelBuffer
712        | ComputeShaderReadOther
713        | AnyShaderReadUniformBuffer
714        | AnyShaderReadUniformBufferOrVertexBuffer
715        | AnyShaderReadSampledImageOrUniformTexelBuffer
716        | AnyShaderReadOther
717        | TransferRead
718        | HostRead
719        | Present
720        | RayTracingShaderReadSampledImageOrUniformTexelBuffer
721        | RayTracingShaderReadColorInputAttachment
722        | RayTracingShaderReadDepthStencilInputAttachment
723        | RayTracingShaderReadAccelerationStructure
724        | RayTracingShaderReadOther
725        | AccelerationStructureBuildRead
726        | MeshShaderReadUniformBuffer
727        | MeshShaderReadSampledImageOrUniformTexelBuffer
728        | MeshShaderReadOther
729        | TaskShaderReadUniformBuffer
730        | TaskShaderReadSampledImageOrUniformTexelBuffer
731        | TaskShaderReadOther
732        | DepthStencilAttachmentReadWrite
733        | DepthAttachmentWriteStencilReadOnly
734        | StencilAttachmentWriteDepthReadOnly
735        | ColorAttachmentReadWrite
736        | General
737        | ComputeShaderReadWrite => true,
738    }
739}
740
741pub(super) const fn is_write_access(ty: self::sync::AccessType) -> bool {
742    use self::sync::AccessType::*;
743    match ty {
744        Nothing
745        | CommandBufferReadNVX
746        | IndirectBuffer
747        | IndexBuffer
748        | VertexBuffer
749        | VertexShaderReadUniformBuffer
750        | VertexShaderReadSampledImageOrUniformTexelBuffer
751        | VertexShaderReadOther
752        | TessellationControlShaderReadUniformBuffer
753        | TessellationControlShaderReadSampledImageOrUniformTexelBuffer
754        | TessellationControlShaderReadOther
755        | TessellationEvaluationShaderReadUniformBuffer
756        | TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer
757        | TessellationEvaluationShaderReadOther
758        | GeometryShaderReadUniformBuffer
759        | GeometryShaderReadSampledImageOrUniformTexelBuffer
760        | GeometryShaderReadOther
761        | FragmentShaderReadUniformBuffer
762        | FragmentShaderReadSampledImageOrUniformTexelBuffer
763        | FragmentShaderReadColorInputAttachment
764        | FragmentShaderReadDepthStencilInputAttachment
765        | FragmentShaderReadOther
766        | ColorAttachmentRead
767        | DepthStencilAttachmentRead
768        | ComputeShaderReadUniformBuffer
769        | ComputeShaderReadSampledImageOrUniformTexelBuffer
770        | ComputeShaderReadOther
771        | AnyShaderReadUniformBuffer
772        | AnyShaderReadUniformBufferOrVertexBuffer
773        | AnyShaderReadSampledImageOrUniformTexelBuffer
774        | AnyShaderReadOther
775        | TransferRead
776        | HostRead
777        | Present
778        | RayTracingShaderReadSampledImageOrUniformTexelBuffer
779        | RayTracingShaderReadColorInputAttachment
780        | RayTracingShaderReadDepthStencilInputAttachment
781        | RayTracingShaderReadAccelerationStructure
782        | RayTracingShaderReadOther
783        | AccelerationStructureBuildRead
784        | MeshShaderReadUniformBuffer
785        | MeshShaderReadSampledImageOrUniformTexelBuffer
786        | MeshShaderReadOther
787        | TaskShaderReadUniformBuffer
788        | TaskShaderReadSampledImageOrUniformTexelBuffer
789        | TaskShaderReadOther => false,
790        CommandBufferWriteNVX
791        | VertexShaderWrite
792        | TessellationControlShaderWrite
793        | TessellationEvaluationShaderWrite
794        | GeometryShaderWrite
795        | FragmentShaderWrite
796        | ColorAttachmentWrite
797        | DepthStencilAttachmentWrite
798        | DepthStencilAttachmentReadWrite
799        | DepthAttachmentWriteStencilReadOnly
800        | StencilAttachmentWriteDepthReadOnly
801        | ComputeShaderWrite
802        | AnyShaderWrite
803        | TransferWrite
804        | HostWrite
805        | ColorAttachmentReadWrite
806        | General
807        | AccelerationStructureBuildWrite
808        | AccelerationStructureBufferWrite
809        | ComputeShaderReadWrite
810        | MeshShaderWrite
811        | TaskShaderWrite => true,
812    }
813}
814
815// Convert overlapping push constant regions such as this:
816// VERTEX 0..64
817// FRAGMENT 0..80
818//
819// To this:
820// VERTEX | FRAGMENT 0..64
821// FRAGMENT 64..80
822//
823// We do this so that submission doesn't need to check for overlaps
824// See https://github.com/KhronosGroup/Vulkan-Docs/issues/609
825#[profiling::function]
826fn merge_push_constant_ranges(pcr: &[vk::PushConstantRange]) -> Vec<vk::PushConstantRange> {
827    // Each specified range must be for a single stage and each stage must be specified once
828    #[cfg(debug_assertions)]
829    {
830        let mut stage_flags = vk::ShaderStageFlags::empty();
831        for item in pcr.iter() {
832            assert_eq!(item.stage_flags.as_raw().count_ones(), 1);
833            assert!(!stage_flags.contains(item.stage_flags));
834            assert!(item.size > 0);
835
836            stage_flags |= item.stage_flags;
837        }
838    }
839
840    match pcr.len() {
841        0 => vec![],
842        1 => vec![pcr[0]],
843        _ => {
844            let mut res = pcr.to_vec();
845            let sort_fn = |lhs: &vk::PushConstantRange, rhs: &vk::PushConstantRange| match lhs
846                .offset
847                .cmp(&rhs.offset)
848            {
849                Ordering::Equal => lhs.size.cmp(&rhs.size),
850                res => res,
851            };
852
853            res.sort_unstable_by(sort_fn);
854
855            let mut i = 0;
856            let mut j = 1;
857
858            while j < res.len() {
859                let lhs = res[i];
860                let rhs = res[j];
861
862                if lhs.offset == rhs.offset && lhs.size == rhs.size {
863                    res[i].stage_flags |= rhs.stage_flags;
864                    let _ = res.remove(j);
865                } else if lhs.offset == rhs.offset {
866                    res[i].stage_flags |= rhs.stage_flags;
867                    res[j].offset += lhs.size;
868                    res[j].size -= lhs.size;
869                    res[j..].sort_unstable_by(sort_fn);
870                } else if lhs.offset + lhs.size > rhs.offset + rhs.size {
871                    res[i].size = rhs.offset - lhs.offset;
872                    res[j].stage_flags = lhs.stage_flags;
873                    res[j].offset += rhs.size;
874                    res[j].size = (lhs.offset + lhs.size) - (rhs.offset + rhs.size);
875                    res.insert(
876                        j,
877                        vk::PushConstantRange {
878                            stage_flags: lhs.stage_flags | rhs.stage_flags,
879                            offset: rhs.offset,
880                            size: rhs.size,
881                        },
882                    );
883                    i += 1;
884                    j += 1;
885                } else if lhs.offset + lhs.size == rhs.offset + rhs.size {
886                    res[i].size -= rhs.size;
887                    res[j].stage_flags |= lhs.stage_flags;
888                    i += 1;
889                    j += 1;
890                } else if lhs.offset + lhs.size > rhs.offset
891                    && lhs.offset + lhs.size < rhs.offset + rhs.size
892                {
893                    res[i].size = rhs.offset - lhs.offset;
894                    res[j].offset = lhs.offset + lhs.size;
895                    res[j].size = (rhs.offset + rhs.size) - (lhs.offset + lhs.size);
896                    res.insert(
897                        j,
898                        vk::PushConstantRange {
899                            stage_flags: lhs.stage_flags | rhs.stage_flags,
900                            offset: rhs.offset,
901                            size: (lhs.offset + lhs.size) - rhs.offset,
902                        },
903                    );
904                    res[j..].sort_unstable_by(sort_fn);
905                } else {
906                    i += 1;
907                    j += 1;
908                }
909            }
910
911            res
912        }
913    }
914}
915
916pub(super) const fn pipeline_stage_access_flags(
917    access_type: vk_sync::AccessType,
918) -> (vk::PipelineStageFlags, vk::AccessFlags) {
919    use {
920        vk::{AccessFlags as access, PipelineStageFlags as stage},
921        vk_sync::AccessType as ty,
922    };
923
924    match access_type {
925        ty::Nothing => (stage::empty(), access::empty()),
926        ty::CommandBufferReadNVX => (
927            stage::COMMAND_PREPROCESS_NV,
928            access::COMMAND_PREPROCESS_READ_NV,
929        ),
930        ty::IndirectBuffer => (stage::DRAW_INDIRECT, access::INDIRECT_COMMAND_READ),
931        ty::IndexBuffer => (stage::VERTEX_INPUT, access::INDEX_READ),
932        ty::VertexBuffer => (stage::VERTEX_INPUT, access::VERTEX_ATTRIBUTE_READ),
933        ty::VertexShaderReadUniformBuffer => (stage::VERTEX_SHADER, access::SHADER_READ),
934        ty::VertexShaderReadSampledImageOrUniformTexelBuffer => {
935            (stage::VERTEX_SHADER, access::SHADER_READ)
936        }
937        ty::VertexShaderReadOther => (stage::VERTEX_SHADER, access::SHADER_READ),
938        ty::TessellationControlShaderReadUniformBuffer => {
939            (stage::TESSELLATION_CONTROL_SHADER, access::UNIFORM_READ)
940        }
941        ty::TessellationControlShaderReadSampledImageOrUniformTexelBuffer => {
942            (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_READ)
943        }
944        ty::TessellationControlShaderReadOther => {
945            (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_READ)
946        }
947        ty::TessellationEvaluationShaderReadUniformBuffer => {
948            (stage::TESSELLATION_EVALUATION_SHADER, access::UNIFORM_READ)
949        }
950        ty::TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer => {
951            (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_READ)
952        }
953        ty::TessellationEvaluationShaderReadOther => {
954            (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_READ)
955        }
956        ty::GeometryShaderReadUniformBuffer => (stage::GEOMETRY_SHADER, access::UNIFORM_READ),
957        ty::GeometryShaderReadSampledImageOrUniformTexelBuffer => {
958            (stage::GEOMETRY_SHADER, access::SHADER_READ)
959        }
960        ty::GeometryShaderReadOther => (stage::GEOMETRY_SHADER, access::SHADER_READ),
961        ty::FragmentShaderReadUniformBuffer => (stage::FRAGMENT_SHADER, access::UNIFORM_READ),
962        ty::FragmentShaderReadSampledImageOrUniformTexelBuffer => {
963            (stage::FRAGMENT_SHADER, access::SHADER_READ)
964        }
965        ty::FragmentShaderReadColorInputAttachment => {
966            (stage::FRAGMENT_SHADER, access::INPUT_ATTACHMENT_READ)
967        }
968        ty::FragmentShaderReadDepthStencilInputAttachment => {
969            (stage::FRAGMENT_SHADER, access::INPUT_ATTACHMENT_READ)
970        }
971        ty::FragmentShaderReadOther => (stage::FRAGMENT_SHADER, access::SHADER_READ),
972        ty::ColorAttachmentRead => (
973            stage::COLOR_ATTACHMENT_OUTPUT,
974            access::COLOR_ATTACHMENT_READ,
975        ),
976        ty::DepthStencilAttachmentRead => (
977            stage::from_raw(
978                stage::EARLY_FRAGMENT_TESTS.as_raw()
979                    | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
980            ),
981            access::DEPTH_STENCIL_ATTACHMENT_READ,
982        ),
983        ty::ComputeShaderReadUniformBuffer => (stage::COMPUTE_SHADER, access::UNIFORM_READ),
984        ty::ComputeShaderReadSampledImageOrUniformTexelBuffer => {
985            (stage::COMPUTE_SHADER, access::SHADER_READ)
986        }
987        ty::ComputeShaderReadOther => (stage::COMPUTE_SHADER, access::SHADER_READ),
988        ty::AnyShaderReadUniformBuffer => (stage::ALL_COMMANDS, access::UNIFORM_READ),
989        ty::AnyShaderReadUniformBufferOrVertexBuffer => (
990            stage::ALL_COMMANDS,
991            access::from_raw(
992                access::UNIFORM_READ.as_raw() | vk::AccessFlags::VERTEX_ATTRIBUTE_READ.as_raw(),
993            ),
994        ),
995        ty::AnyShaderReadSampledImageOrUniformTexelBuffer => {
996            (stage::ALL_COMMANDS, access::SHADER_READ)
997        }
998        ty::AnyShaderReadOther => (stage::ALL_COMMANDS, access::SHADER_READ),
999        ty::TransferRead => (stage::TRANSFER, access::TRANSFER_READ),
1000        ty::HostRead => (stage::HOST, access::HOST_READ),
1001        ty::Present => (stage::empty(), access::empty()),
1002        ty::CommandBufferWriteNVX => (
1003            stage::COMMAND_PREPROCESS_NV,
1004            access::COMMAND_PREPROCESS_WRITE_NV,
1005        ),
1006        ty::VertexShaderWrite => (stage::VERTEX_SHADER, access::SHADER_WRITE),
1007        ty::TessellationControlShaderWrite => {
1008            (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_WRITE)
1009        }
1010        ty::TessellationEvaluationShaderWrite => {
1011            (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_WRITE)
1012        }
1013        ty::GeometryShaderWrite => (stage::GEOMETRY_SHADER, access::SHADER_WRITE),
1014        ty::FragmentShaderWrite => (stage::FRAGMENT_SHADER, access::SHADER_WRITE),
1015        ty::ColorAttachmentWrite => (
1016            stage::COLOR_ATTACHMENT_OUTPUT,
1017            access::COLOR_ATTACHMENT_WRITE,
1018        ),
1019        ty::DepthStencilAttachmentWrite => (
1020            stage::from_raw(
1021                stage::EARLY_FRAGMENT_TESTS.as_raw()
1022                    | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1023            ),
1024            access::DEPTH_STENCIL_ATTACHMENT_WRITE,
1025        ),
1026        ty::DepthStencilAttachmentReadWrite => (
1027            stage::from_raw(
1028                stage::EARLY_FRAGMENT_TESTS.as_raw()
1029                    | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1030            ),
1031            access::from_raw(
1032                access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
1033                    | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
1034            ),
1035        ),
1036        ty::DepthAttachmentWriteStencilReadOnly => (
1037            stage::from_raw(
1038                stage::EARLY_FRAGMENT_TESTS.as_raw()
1039                    | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1040            ),
1041            access::from_raw(
1042                access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
1043                    | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
1044            ),
1045        ),
1046        ty::StencilAttachmentWriteDepthReadOnly => (
1047            stage::from_raw(
1048                stage::EARLY_FRAGMENT_TESTS.as_raw()
1049                    | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1050            ),
1051            access::from_raw(
1052                access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
1053                    | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
1054            ),
1055        ),
1056        ty::ComputeShaderWrite => (stage::COMPUTE_SHADER, access::SHADER_WRITE),
1057        ty::ComputeShaderReadWrite => (
1058            stage::COMPUTE_SHADER,
1059            access::from_raw(access::SHADER_WRITE.as_raw() | access::SHADER_READ.as_raw()),
1060        ),
1061        ty::AnyShaderWrite => (stage::ALL_COMMANDS, access::SHADER_WRITE),
1062        ty::TransferWrite => (stage::TRANSFER, access::TRANSFER_WRITE),
1063        ty::HostWrite => (stage::HOST, access::HOST_WRITE),
1064        ty::ColorAttachmentReadWrite => (
1065            stage::COLOR_ATTACHMENT_OUTPUT,
1066            access::from_raw(
1067                access::COLOR_ATTACHMENT_READ.as_raw()
1068                    | vk::AccessFlags::COLOR_ATTACHMENT_WRITE.as_raw(),
1069            ),
1070        ),
1071        ty::General => (
1072            stage::ALL_COMMANDS,
1073            access::from_raw(access::MEMORY_READ.as_raw() | vk::AccessFlags::MEMORY_WRITE.as_raw()),
1074        ),
1075        ty::RayTracingShaderReadSampledImageOrUniformTexelBuffer => {
1076            (stage::RAY_TRACING_SHADER_KHR, access::SHADER_READ)
1077        }
1078        ty::RayTracingShaderReadColorInputAttachment => {
1079            (stage::RAY_TRACING_SHADER_KHR, access::INPUT_ATTACHMENT_READ)
1080        }
1081        ty::RayTracingShaderReadDepthStencilInputAttachment => {
1082            (stage::RAY_TRACING_SHADER_KHR, access::INPUT_ATTACHMENT_READ)
1083        }
1084        ty::RayTracingShaderReadAccelerationStructure => (
1085            stage::RAY_TRACING_SHADER_KHR,
1086            access::ACCELERATION_STRUCTURE_READ_KHR,
1087        ),
1088        ty::RayTracingShaderReadOther => (stage::RAY_TRACING_SHADER_KHR, access::SHADER_READ),
1089        ty::AccelerationStructureBuildWrite => (
1090            stage::ACCELERATION_STRUCTURE_BUILD_KHR,
1091            access::ACCELERATION_STRUCTURE_WRITE_KHR,
1092        ),
1093        ty::AccelerationStructureBuildRead => (
1094            stage::ACCELERATION_STRUCTURE_BUILD_KHR,
1095            access::ACCELERATION_STRUCTURE_READ_KHR,
1096        ),
1097        ty::AccelerationStructureBufferWrite => (
1098            stage::ACCELERATION_STRUCTURE_BUILD_KHR,
1099            access::TRANSFER_WRITE,
1100        ),
1101        ty::MeshShaderReadUniformBuffer => (stage::MESH_SHADER_EXT, access::SHADER_READ),
1102        ty::MeshShaderReadSampledImageOrUniformTexelBuffer => {
1103            (stage::MESH_SHADER_EXT, access::SHADER_READ)
1104        }
1105        ty::MeshShaderReadOther => (stage::MESH_SHADER_EXT, access::SHADER_READ),
1106        ty::TaskShaderReadUniformBuffer => (stage::TASK_SHADER_EXT, access::SHADER_READ),
1107        ty::TaskShaderReadSampledImageOrUniformTexelBuffer => {
1108            (stage::TASK_SHADER_EXT, access::SHADER_READ)
1109        }
1110        ty::TaskShaderReadOther => (stage::TASK_SHADER_EXT, access::SHADER_READ),
1111        ty::MeshShaderWrite => (stage::MESH_SHADER_EXT, access::SHADER_WRITE),
1112        ty::TaskShaderWrite => (stage::TASK_SHADER_EXT, access::SHADER_WRITE),
1113    }
1114}
1115
1116/// Describes the general category of all graphics driver failure cases.
1117///
1118/// In the event of a failure you should follow the _vk-graph_ code to the responsible Vulkan API
1119/// and then to the `Ash` stub call; it will generally contain a link to the appropriate
1120/// specification. The specifications provide a table of possible error conditions which can be a
1121/// good starting point to debug the issue.
1122///
1123/// Feel free to open an issue on GitHub, [here](https://github.com/attackgoat/vk-graph/issues) for
1124/// help debugging the issue.
1125#[derive(Clone, Copy, Debug)]
1126pub enum DriverError {
1127    /// The input data, or referenced data, is not valid for the current state.
1128    InvalidData,
1129
1130    /// The requested feature, or input configuration, is not supported for the current state.
1131    Unsupported,
1132
1133    /// The device has run out of physical memory.
1134    ///
1135    /// Many drivers return this value for generic or unhandled error conditions.
1136    OutOfMemory,
1137}
1138
1139impl DriverError {
1140    fn from_alloc_err(err: AllocationError) -> Self {
1141        match err {
1142            AllocationError::OutOfMemory => Self::OutOfMemory,
1143            AllocationError::InvalidAllocationCreateDesc
1144            | AllocationError::InvalidAllocatorCreateDesc(_) => Self::InvalidData,
1145            AllocationError::FailedToMap(_)
1146            | AllocationError::NoCompatibleMemoryTypeFound
1147            | AllocationError::Internal(_)
1148            | AllocationError::BarrierLayoutNeedsDevice10
1149            | AllocationError::CastableFormatsRequiresEnhancedBarriers
1150            | AllocationError::CastableFormatsRequiresAtLeastDevice12 => Self::Unsupported,
1151        }
1152    }
1153}
1154
1155impl Display for DriverError {
1156    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1157        write!(f, "{:?}", self)
1158    }
1159}
1160
1161impl Error for DriverError {}
1162
1163#[cfg(test)]
1164mod test {
1165    use {super::merge_push_constant_ranges, ash::vk};
1166
1167    macro_rules! assert_pcr_eq {
1168        ($lhs: expr, $rhs: expr,) => {
1169            assert_eq!($lhs.stage_flags, $rhs.stage_flags, "Stages flags not equal");
1170            assert_eq!($lhs.offset, $rhs.offset, "Offset not equal");
1171            assert_eq!($lhs.size, $rhs.size, "Size not equal");
1172        };
1173    }
1174
1175    #[test]
1176    pub fn push_constant_ranges_complex() {
1177        let res = merge_push_constant_ranges(&[
1178            vk::PushConstantRange {
1179                stage_flags: vk::ShaderStageFlags::VERTEX,
1180                offset: 8,
1181                size: 16,
1182            },
1183            vk::PushConstantRange {
1184                stage_flags: vk::ShaderStageFlags::GEOMETRY,
1185                offset: 20,
1186                size: 48,
1187            },
1188            vk::PushConstantRange {
1189                stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL,
1190                offset: 24,
1191                size: 8,
1192            },
1193            vk::PushConstantRange {
1194                stage_flags: vk::ShaderStageFlags::TESSELLATION_EVALUATION,
1195                offset: 28,
1196                size: 32,
1197            },
1198            vk::PushConstantRange {
1199                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1200                offset: 40,
1201                size: 128,
1202            },
1203        ]);
1204
1205        assert_eq!(res.len(), 8);
1206        assert_pcr_eq!(
1207            res[0],
1208            vk::PushConstantRange {
1209                stage_flags: vk::ShaderStageFlags::VERTEX,
1210                offset: 8,
1211                size: 12,
1212            },
1213        );
1214        assert_pcr_eq!(
1215            res[1],
1216            vk::PushConstantRange {
1217                stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
1218                offset: 20,
1219                size: 4,
1220            },
1221        );
1222        assert_pcr_eq!(
1223            res[2],
1224            vk::PushConstantRange {
1225                stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL
1226                    | vk::ShaderStageFlags::GEOMETRY,
1227                offset: 24,
1228                size: 4,
1229            },
1230        );
1231        assert_pcr_eq!(
1232            res[3],
1233            vk::PushConstantRange {
1234                stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL
1235                    | vk::ShaderStageFlags::TESSELLATION_EVALUATION
1236                    | vk::ShaderStageFlags::GEOMETRY,
1237                offset: 28,
1238                size: 4,
1239            },
1240        );
1241        assert_pcr_eq!(
1242            res[4],
1243            vk::PushConstantRange {
1244                stage_flags: vk::ShaderStageFlags::GEOMETRY
1245                    | vk::ShaderStageFlags::TESSELLATION_EVALUATION,
1246                offset: 32,
1247                size: 8,
1248            },
1249        );
1250        assert_pcr_eq!(
1251            res[5],
1252            vk::PushConstantRange {
1253                stage_flags: vk::ShaderStageFlags::GEOMETRY
1254                    | vk::ShaderStageFlags::TESSELLATION_EVALUATION
1255                    | vk::ShaderStageFlags::FRAGMENT,
1256                offset: 40,
1257                size: 20,
1258            },
1259        );
1260        assert_pcr_eq!(
1261            res[6],
1262            vk::PushConstantRange {
1263                stage_flags: vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::GEOMETRY,
1264                offset: 60,
1265                size: 8,
1266            },
1267        );
1268        assert_pcr_eq!(
1269            res[7],
1270            vk::PushConstantRange {
1271                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1272                offset: 68,
1273                size: 100,
1274            },
1275        );
1276    }
1277
1278    #[test]
1279    pub fn push_constant_ranges_disjoint() {
1280        let res = merge_push_constant_ranges(&[
1281            vk::PushConstantRange {
1282                stage_flags: vk::ShaderStageFlags::VERTEX,
1283                offset: 0,
1284                size: 32,
1285            },
1286            vk::PushConstantRange {
1287                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1288                offset: 32,
1289                size: 64,
1290            },
1291        ]);
1292
1293        assert_eq!(res.len(), 2);
1294        assert_pcr_eq!(
1295            res[0],
1296            vk::PushConstantRange {
1297                stage_flags: vk::ShaderStageFlags::VERTEX,
1298                offset: 0,
1299                size: 32,
1300            },
1301        );
1302        assert_pcr_eq!(
1303            res[1],
1304            vk::PushConstantRange {
1305                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1306                offset: 32,
1307                size: 64,
1308            },
1309        );
1310    }
1311
1312    #[test]
1313    pub fn push_constant_ranges_equal() {
1314        let res = merge_push_constant_ranges(&[
1315            vk::PushConstantRange {
1316                stage_flags: vk::ShaderStageFlags::VERTEX,
1317                offset: 0,
1318                size: 32,
1319            },
1320            vk::PushConstantRange {
1321                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1322                offset: 0,
1323                size: 32,
1324            },
1325        ]);
1326
1327        assert_eq!(res.len(), 1);
1328        assert_pcr_eq!(
1329            res[0],
1330            vk::PushConstantRange {
1331                stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1332                offset: 0,
1333                size: 32,
1334            },
1335        );
1336    }
1337
1338    #[test]
1339    pub fn push_constant_ranges_overlap() {
1340        let res = merge_push_constant_ranges(&[
1341            vk::PushConstantRange {
1342                stage_flags: vk::ShaderStageFlags::VERTEX,
1343                offset: 0,
1344                size: 24,
1345            },
1346            vk::PushConstantRange {
1347                stage_flags: vk::ShaderStageFlags::GEOMETRY,
1348                offset: 8,
1349                size: 24,
1350            },
1351            vk::PushConstantRange {
1352                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1353                offset: 20,
1354                size: 28,
1355            },
1356        ]);
1357
1358        assert_eq!(res.len(), 5);
1359        assert_pcr_eq!(
1360            res[0],
1361            vk::PushConstantRange {
1362                stage_flags: vk::ShaderStageFlags::VERTEX,
1363                offset: 0,
1364                size: 8,
1365            },
1366        );
1367        assert_pcr_eq!(
1368            res[1],
1369            vk::PushConstantRange {
1370                stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
1371                offset: 8,
1372                size: 12,
1373            },
1374        );
1375        assert_pcr_eq!(
1376            res[2],
1377            vk::PushConstantRange {
1378                stage_flags: vk::ShaderStageFlags::VERTEX
1379                    | vk::ShaderStageFlags::GEOMETRY
1380                    | vk::ShaderStageFlags::FRAGMENT,
1381                offset: 20,
1382                size: 4,
1383            },
1384        );
1385        assert_pcr_eq!(
1386            res[3],
1387            vk::PushConstantRange {
1388                stage_flags: vk::ShaderStageFlags::GEOMETRY | vk::ShaderStageFlags::FRAGMENT,
1389                offset: 24,
1390                size: 8,
1391            },
1392        );
1393        assert_pcr_eq!(
1394            res[4],
1395            vk::PushConstantRange {
1396                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1397                offset: 32,
1398                size: 16,
1399            },
1400        );
1401    }
1402
1403    #[test]
1404    pub fn push_constant_ranges_subset() {
1405        let res = merge_push_constant_ranges(&[
1406            vk::PushConstantRange {
1407                stage_flags: vk::ShaderStageFlags::VERTEX,
1408                offset: 0,
1409                size: 64,
1410            },
1411            vk::PushConstantRange {
1412                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1413                offset: 16,
1414                size: 8,
1415            },
1416        ]);
1417
1418        assert_eq!(res.len(), 3);
1419        assert_pcr_eq!(
1420            res[0],
1421            vk::PushConstantRange {
1422                stage_flags: vk::ShaderStageFlags::VERTEX,
1423                offset: 0,
1424                size: 16,
1425            },
1426        );
1427        assert_pcr_eq!(
1428            res[1],
1429            vk::PushConstantRange {
1430                stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1431                offset: 16,
1432                size: 8,
1433            },
1434        );
1435        assert_pcr_eq!(
1436            res[2],
1437            vk::PushConstantRange {
1438                stage_flags: vk::ShaderStageFlags::VERTEX,
1439                offset: 24,
1440                size: 40,
1441            },
1442        );
1443    }
1444
1445    #[test]
1446    pub fn push_constant_ranges_superset() {
1447        let res = merge_push_constant_ranges(&[
1448            vk::PushConstantRange {
1449                stage_flags: vk::ShaderStageFlags::VERTEX,
1450                offset: 0,
1451                size: 64,
1452            },
1453            vk::PushConstantRange {
1454                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1455                offset: 0,
1456                size: 80,
1457            },
1458        ]);
1459
1460        assert_eq!(res.len(), 2);
1461        assert_pcr_eq!(
1462            res[0],
1463            vk::PushConstantRange {
1464                stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1465                offset: 0,
1466                size: 64,
1467            },
1468        );
1469        assert_pcr_eq!(
1470            res[1],
1471            vk::PushConstantRange {
1472                stage_flags: vk::ShaderStageFlags::FRAGMENT,
1473                offset: 64,
1474                size: 16,
1475            },
1476        );
1477    }
1478}