screen_13/driver/
mod.rs

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