1pub mod accel_struct;
51pub mod buffer;
52pub mod cmd_buf;
53pub mod compute;
54pub mod descriptor_set;
55pub mod device;
56pub mod fence;
57pub mod graphics;
58pub mod image;
59pub mod instance;
60pub mod physical_device;
61pub mod ray_tracing;
62pub mod render_pass;
63pub mod shader;
64pub mod surface;
65pub mod swapchain;
66
67pub(crate) mod query_pool;
68
69mod descriptor_set_layout;
70
71#[doc(hidden)]
82pub use ash::{self};
83
84#[doc(hidden)]
94pub use vk_sync::{self as sync};
95
96pub(crate) use self::{
97 descriptor_set::RawDescriptorSet,
98 descriptor_set_layout::DescriptorSetLayout,
99 render_pass::{
100 AttachmentInfo, AttachmentRef, FramebufferAttachmentImageInfo, FramebufferInfo,
101 SubpassDependency, SubpassInfo,
102 },
103 shader::{Descriptor, DescriptorBindingMap, DescriptorInfo},
104 surface::Surface,
105};
106
107use {
108 self::{
109 buffer::{Buffer, BufferInfo},
110 graphics::VertexInputState,
111 },
112 ash::vk,
113 gpu_allocator::AllocationError,
114 std::{
115 cmp::Ordering,
116 convert::Infallible,
117 error::Error,
118 fmt::{Display, Formatter},
119 },
120};
121
122macro_rules! access_type_u8_map {
123 ($($idx:literal => $name:ident),* $(,)?) => {
124 pub(super) const fn access_type_into_u8(ty: self::sync::AccessType) -> u8 {
125 use self::sync::AccessType::*;
126
127 match ty {
128 $($name => $idx,)*
129 }
130 }
131
132 pub(super) const fn access_type_from_u8(value: u8) -> self::sync::AccessType {
133 use self::sync::AccessType::*;
134
135 match value {
136 $($idx => $name,)*
137 _ => panic!("invalid packed access type"),
138 }
139 }
140 };
141}
142
143access_type_u8_map! {
144 0 => Nothing,
145 1 => CommandBufferReadNVX,
146 2 => IndirectBuffer,
147 3 => IndexBuffer,
148 4 => VertexBuffer,
149 5 => VertexShaderReadUniformBuffer,
150 6 => VertexShaderReadSampledImageOrUniformTexelBuffer,
151 7 => VertexShaderReadOther,
152 8 => TessellationControlShaderReadUniformBuffer,
153 9 => TessellationControlShaderReadSampledImageOrUniformTexelBuffer,
154 10 => TessellationControlShaderReadOther,
155 11 => TessellationEvaluationShaderReadUniformBuffer,
156 12 => TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer,
157 13 => TessellationEvaluationShaderReadOther,
158 14 => GeometryShaderReadUniformBuffer,
159 15 => GeometryShaderReadSampledImageOrUniformTexelBuffer,
160 16 => GeometryShaderReadOther,
161 17 => FragmentShaderReadUniformBuffer,
162 18 => FragmentShaderReadSampledImageOrUniformTexelBuffer,
163 19 => FragmentShaderReadColorInputAttachment,
164 20 => FragmentShaderReadDepthStencilInputAttachment,
165 21 => FragmentShaderReadOther,
166 22 => ColorAttachmentRead,
167 23 => DepthStencilAttachmentRead,
168 24 => ComputeShaderReadUniformBuffer,
169 25 => ComputeShaderReadSampledImageOrUniformTexelBuffer,
170 26 => ComputeShaderReadOther,
171 27 => AnyShaderReadUniformBuffer,
172 28 => AnyShaderReadUniformBufferOrVertexBuffer,
173 29 => AnyShaderReadSampledImageOrUniformTexelBuffer,
174 30 => AnyShaderReadOther,
175 31 => TransferRead,
176 32 => HostRead,
177 33 => Present,
178 34 => CommandBufferWriteNVX,
179 35 => VertexShaderWrite,
180 36 => TessellationControlShaderWrite,
181 37 => TessellationEvaluationShaderWrite,
182 38 => GeometryShaderWrite,
183 39 => FragmentShaderWrite,
184 40 => ColorAttachmentWrite,
185 41 => DepthStencilAttachmentWrite,
186 42 => DepthStencilAttachmentReadWrite,
187 43 => DepthAttachmentWriteStencilReadOnly,
188 44 => StencilAttachmentWriteDepthReadOnly,
189 45 => ComputeShaderWrite,
190 46 => ComputeShaderReadWrite,
191 47 => AnyShaderWrite,
192 48 => TransferWrite,
193 49 => HostWrite,
194 50 => ColorAttachmentReadWrite,
195 51 => General,
196 52 => RayTracingShaderReadSampledImageOrUniformTexelBuffer,
197 53 => RayTracingShaderReadColorInputAttachment,
198 54 => RayTracingShaderReadDepthStencilInputAttachment,
199 55 => RayTracingShaderReadAccelerationStructure,
200 56 => RayTracingShaderReadOther,
201 57 => AccelerationStructureBuildWrite,
202 58 => AccelerationStructureBuildRead,
203 59 => AccelerationStructureBufferWrite,
204 60 => MeshShaderReadUniformBuffer,
205 61 => MeshShaderReadSampledImageOrUniformTexelBuffer,
206 62 => MeshShaderReadOther,
207 63 => TaskShaderReadUniformBuffer,
208 64 => TaskShaderReadSampledImageOrUniformTexelBuffer,
209 65 => TaskShaderReadOther,
210 66 => MeshShaderWrite,
211 67 => TaskShaderWrite,
212}
213
214pub(super) const fn format_aspect_mask(fmt: vk::Format) -> vk::ImageAspectFlags {
215 match fmt {
216 vk::Format::D16_UNORM | vk::Format::D32_SFLOAT | vk::Format::X8_D24_UNORM_PACK32 => {
217 vk::ImageAspectFlags::DEPTH
218 }
219 vk::Format::S8_UINT => vk::ImageAspectFlags::STENCIL,
220 vk::Format::D16_UNORM_S8_UINT
221 | vk::Format::D24_UNORM_S8_UINT
222 | vk::Format::D32_SFLOAT_S8_UINT => vk::ImageAspectFlags::from_raw(
223 vk::ImageAspectFlags::DEPTH.as_raw() | vk::ImageAspectFlags::STENCIL.as_raw(),
224 ),
225 _ => vk::ImageAspectFlags::COLOR,
226 }
227}
228
229pub const fn format_texel_block_size(fmt: vk::Format) -> u32 {
235 match fmt {
236 vk::Format::UNDEFINED => 0,
237 vk::Format::R4G4_UNORM_PACK8
238 | vk::Format::R8_UNORM
239 | vk::Format::R8_SNORM
240 | vk::Format::R8_USCALED
241 | vk::Format::R8_SSCALED
242 | vk::Format::R8_UINT
243 | vk::Format::R8_SINT
244 | vk::Format::R8_SRGB => 1,
245 vk::Format::A1B5G5R5_UNORM_PACK16_KHR
246 | vk::Format::R10X6_UNORM_PACK16
247 | vk::Format::R12X4_UNORM_PACK16
248 | vk::Format::A4R4G4B4_UNORM_PACK16
249 | vk::Format::A4B4G4R4_UNORM_PACK16
250 | vk::Format::R4G4B4A4_UNORM_PACK16
251 | vk::Format::B4G4R4A4_UNORM_PACK16
252 | vk::Format::R5G6B5_UNORM_PACK16
253 | vk::Format::B5G6R5_UNORM_PACK16
254 | vk::Format::R5G5B5A1_UNORM_PACK16
255 | vk::Format::B5G5R5A1_UNORM_PACK16
256 | vk::Format::A1R5G5B5_UNORM_PACK16
257 | vk::Format::R8G8_UNORM
258 | vk::Format::R8G8_SNORM
259 | vk::Format::R8G8_USCALED
260 | vk::Format::R8G8_SSCALED
261 | vk::Format::R8G8_UINT
262 | vk::Format::R8G8_SINT
263 | vk::Format::R8G8_SRGB
264 | vk::Format::R16_UNORM
265 | vk::Format::R16_SNORM
266 | vk::Format::R16_USCALED
267 | vk::Format::R16_SSCALED
268 | vk::Format::R16_UINT
269 | vk::Format::R16_SINT
270 | vk::Format::R16_SFLOAT => 2,
271 vk::Format::A8_UNORM_KHR => 1,
272 vk::Format::R8G8B8_UNORM
273 | vk::Format::R8G8B8_SNORM
274 | vk::Format::R8G8B8_USCALED
275 | vk::Format::R8G8B8_SSCALED
276 | vk::Format::R8G8B8_UINT
277 | vk::Format::R8G8B8_SINT
278 | vk::Format::R8G8B8_SRGB
279 | vk::Format::B8G8R8_UNORM
280 | vk::Format::B8G8R8_SNORM
281 | vk::Format::B8G8R8_USCALED
282 | vk::Format::B8G8R8_SSCALED
283 | vk::Format::B8G8R8_UINT
284 | vk::Format::B8G8R8_SINT
285 | vk::Format::B8G8R8_SRGB => 3,
286 vk::Format::R10X6G10X6_UNORM_2PACK16
287 | vk::Format::R12X4G12X4_UNORM_2PACK16
288 | vk::Format::R16G16_S10_5_NV
289 | vk::Format::R8G8B8A8_UNORM
290 | vk::Format::R8G8B8A8_SNORM
291 | vk::Format::R8G8B8A8_USCALED
292 | vk::Format::R8G8B8A8_SSCALED
293 | vk::Format::R8G8B8A8_UINT
294 | vk::Format::R8G8B8A8_SINT
295 | vk::Format::R8G8B8A8_SRGB
296 | vk::Format::B8G8R8A8_UNORM
297 | vk::Format::B8G8R8A8_SNORM
298 | vk::Format::B8G8R8A8_USCALED
299 | vk::Format::B8G8R8A8_SSCALED
300 | vk::Format::B8G8R8A8_UINT
301 | vk::Format::B8G8R8A8_SINT
302 | vk::Format::B8G8R8A8_SRGB
303 | vk::Format::A8B8G8R8_UNORM_PACK32
304 | vk::Format::A8B8G8R8_SNORM_PACK32
305 | vk::Format::A8B8G8R8_USCALED_PACK32
306 | vk::Format::A8B8G8R8_SSCALED_PACK32
307 | vk::Format::A8B8G8R8_UINT_PACK32
308 | vk::Format::A8B8G8R8_SINT_PACK32
309 | vk::Format::A8B8G8R8_SRGB_PACK32
310 | vk::Format::A2R10G10B10_UNORM_PACK32
311 | vk::Format::A2R10G10B10_SNORM_PACK32
312 | vk::Format::A2R10G10B10_USCALED_PACK32
313 | vk::Format::A2R10G10B10_SSCALED_PACK32
314 | vk::Format::A2R10G10B10_UINT_PACK32
315 | vk::Format::A2R10G10B10_SINT_PACK32
316 | vk::Format::A2B10G10R10_UNORM_PACK32
317 | vk::Format::A2B10G10R10_SNORM_PACK32
318 | vk::Format::A2B10G10R10_USCALED_PACK32
319 | vk::Format::A2B10G10R10_SSCALED_PACK32
320 | vk::Format::A2B10G10R10_UINT_PACK32
321 | vk::Format::A2B10G10R10_SINT_PACK32
322 | vk::Format::R16G16_UNORM
323 | vk::Format::R16G16_SNORM
324 | vk::Format::R16G16_USCALED
325 | vk::Format::R16G16_SSCALED
326 | vk::Format::R16G16_UINT
327 | vk::Format::R16G16_SINT
328 | vk::Format::R16G16_SFLOAT
329 | vk::Format::R32_UINT
330 | vk::Format::R32_SINT
331 | vk::Format::R32_SFLOAT
332 | vk::Format::B10G11R11_UFLOAT_PACK32
333 | vk::Format::E5B9G9R9_UFLOAT_PACK32 => 4,
334 vk::Format::R16G16B16_UNORM
335 | vk::Format::R16G16B16_SNORM
336 | vk::Format::R16G16B16_USCALED
337 | vk::Format::R16G16B16_SSCALED
338 | vk::Format::R16G16B16_UINT
339 | vk::Format::R16G16B16_SINT
340 | vk::Format::R16G16B16_SFLOAT => 6,
341 vk::Format::R16G16B16A16_UNORM
342 | vk::Format::R16G16B16A16_SNORM
343 | vk::Format::R16G16B16A16_USCALED
344 | vk::Format::R16G16B16A16_SSCALED
345 | vk::Format::R16G16B16A16_UINT
346 | vk::Format::R16G16B16A16_SINT
347 | vk::Format::R16G16B16A16_SFLOAT
348 | vk::Format::R32G32_UINT
349 | vk::Format::R32G32_SINT
350 | vk::Format::R32G32_SFLOAT
351 | vk::Format::R64_UINT
352 | vk::Format::R64_SINT
353 | vk::Format::R64_SFLOAT => 8,
354 vk::Format::R32G32B32_UINT | vk::Format::R32G32B32_SINT | vk::Format::R32G32B32_SFLOAT => {
355 12
356 }
357 vk::Format::R32G32B32A32_UINT
358 | vk::Format::R32G32B32A32_SINT
359 | vk::Format::R32G32B32A32_SFLOAT
360 | vk::Format::R64G64_UINT
361 | vk::Format::R64G64_SINT
362 | vk::Format::R64G64_SFLOAT => 16,
363 vk::Format::R64G64B64_UINT | vk::Format::R64G64B64_SINT | vk::Format::R64G64B64_SFLOAT => {
364 24
365 }
366 vk::Format::R64G64B64A64_UINT
367 | vk::Format::R64G64B64A64_SINT
368 | vk::Format::R64G64B64A64_SFLOAT => 32,
369 vk::Format::D16_UNORM => 2,
370 vk::Format::X8_D24_UNORM_PACK32 => 4,
371 vk::Format::D32_SFLOAT => 4,
372 vk::Format::S8_UINT => 1,
373 vk::Format::D16_UNORM_S8_UINT => 3,
374 vk::Format::D24_UNORM_S8_UINT => 4,
375 vk::Format::D32_SFLOAT_S8_UINT => 5,
376 vk::Format::BC1_RGB_UNORM_BLOCK
377 | vk::Format::BC1_RGB_SRGB_BLOCK
378 | vk::Format::BC1_RGBA_UNORM_BLOCK
379 | vk::Format::BC1_RGBA_SRGB_BLOCK
380 | vk::Format::BC4_UNORM_BLOCK
381 | vk::Format::BC4_SNORM_BLOCK
382 | vk::Format::ETC2_R8G8B8_UNORM_BLOCK
383 | vk::Format::ETC2_R8G8B8_SRGB_BLOCK
384 | vk::Format::ETC2_R8G8B8A1_UNORM_BLOCK
385 | vk::Format::ETC2_R8G8B8A1_SRGB_BLOCK
386 | vk::Format::EAC_R11_UNORM_BLOCK
387 | vk::Format::EAC_R11_SNORM_BLOCK => 8,
388 vk::Format::BC2_UNORM_BLOCK
389 | vk::Format::BC2_SRGB_BLOCK
390 | vk::Format::BC3_UNORM_BLOCK
391 | vk::Format::BC3_SRGB_BLOCK
392 | vk::Format::BC5_UNORM_BLOCK
393 | vk::Format::BC5_SNORM_BLOCK
394 | vk::Format::BC6H_UFLOAT_BLOCK
395 | vk::Format::BC6H_SFLOAT_BLOCK
396 | vk::Format::BC7_UNORM_BLOCK
397 | vk::Format::BC7_SRGB_BLOCK
398 | vk::Format::ETC2_R8G8B8A8_UNORM_BLOCK
399 | vk::Format::ETC2_R8G8B8A8_SRGB_BLOCK
400 | vk::Format::EAC_R11G11_UNORM_BLOCK
401 | vk::Format::EAC_R11G11_SNORM_BLOCK => 16,
402 vk::Format::ASTC_4X4_SFLOAT_BLOCK
403 | vk::Format::ASTC_4X4_UNORM_BLOCK
404 | vk::Format::ASTC_4X4_SRGB_BLOCK
405 | vk::Format::ASTC_5X4_SFLOAT_BLOCK
406 | vk::Format::ASTC_5X4_UNORM_BLOCK
407 | vk::Format::ASTC_5X4_SRGB_BLOCK
408 | vk::Format::ASTC_5X5_SFLOAT_BLOCK
409 | vk::Format::ASTC_5X5_UNORM_BLOCK
410 | vk::Format::ASTC_5X5_SRGB_BLOCK
411 | vk::Format::ASTC_6X5_SFLOAT_BLOCK
412 | vk::Format::ASTC_6X5_UNORM_BLOCK
413 | vk::Format::ASTC_6X5_SRGB_BLOCK
414 | vk::Format::ASTC_6X6_SFLOAT_BLOCK
415 | vk::Format::ASTC_6X6_UNORM_BLOCK
416 | vk::Format::ASTC_6X6_SRGB_BLOCK
417 | vk::Format::ASTC_8X5_SFLOAT_BLOCK
418 | vk::Format::ASTC_8X5_UNORM_BLOCK
419 | vk::Format::ASTC_8X5_SRGB_BLOCK
420 | vk::Format::ASTC_8X6_SFLOAT_BLOCK
421 | vk::Format::ASTC_8X6_UNORM_BLOCK
422 | vk::Format::ASTC_8X6_SRGB_BLOCK
423 | vk::Format::ASTC_8X8_SFLOAT_BLOCK
424 | vk::Format::ASTC_8X8_UNORM_BLOCK
425 | vk::Format::ASTC_8X8_SRGB_BLOCK
426 | vk::Format::ASTC_10X5_SFLOAT_BLOCK
427 | vk::Format::ASTC_10X5_UNORM_BLOCK
428 | vk::Format::ASTC_10X5_SRGB_BLOCK
429 | vk::Format::ASTC_10X6_SFLOAT_BLOCK
430 | vk::Format::ASTC_10X6_UNORM_BLOCK
431 | vk::Format::ASTC_10X6_SRGB_BLOCK
432 | vk::Format::ASTC_10X8_SFLOAT_BLOCK
433 | vk::Format::ASTC_10X8_UNORM_BLOCK
434 | vk::Format::ASTC_10X8_SRGB_BLOCK
435 | vk::Format::ASTC_10X10_SFLOAT_BLOCK
436 | vk::Format::ASTC_10X10_UNORM_BLOCK
437 | vk::Format::ASTC_10X10_SRGB_BLOCK
438 | vk::Format::ASTC_12X10_SFLOAT_BLOCK
439 | vk::Format::ASTC_12X10_UNORM_BLOCK
440 | vk::Format::ASTC_12X10_SRGB_BLOCK
441 | vk::Format::ASTC_12X12_SFLOAT_BLOCK
442 | vk::Format::ASTC_12X12_UNORM_BLOCK
443 | vk::Format::ASTC_12X12_SRGB_BLOCK => 16,
444 vk::Format::G8B8G8R8_422_UNORM | vk::Format::B8G8R8G8_422_UNORM => 4,
445 vk::Format::G8_B8_R8_3PLANE_420_UNORM
446 | vk::Format::G8_B8R8_2PLANE_420_UNORM
447 | vk::Format::G8_B8_R8_3PLANE_422_UNORM
448 | vk::Format::G8_B8R8_2PLANE_422_UNORM
449 | vk::Format::G8_B8_R8_3PLANE_444_UNORM => 3,
450 vk::Format::R10X6G10X6B10X6A10X6_UNORM_4PACK16
451 | vk::Format::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
452 | vk::Format::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
453 | vk::Format::R12X4G12X4B12X4A12X4_UNORM_4PACK16
454 | vk::Format::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
455 | vk::Format::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
456 | vk::Format::G16B16G16R16_422_UNORM
457 | vk::Format::B16G16R16G16_422_UNORM => 8,
458 vk::Format::G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
459 | vk::Format::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
460 | vk::Format::G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
461 | vk::Format::G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
462 | vk::Format::G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
463 | vk::Format::G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
464 | vk::Format::G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
465 | vk::Format::G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
466 | vk::Format::G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
467 | vk::Format::G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
468 | vk::Format::G16_B16_R16_3PLANE_420_UNORM
469 | vk::Format::G16_B16R16_2PLANE_420_UNORM
470 | vk::Format::G16_B16_R16_3PLANE_422_UNORM
471 | vk::Format::G16_B16R16_2PLANE_422_UNORM
472 | vk::Format::G16_B16_R16_3PLANE_444_UNORM => 6,
473 vk::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG
474 | vk::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG
475 | vk::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG
476 | vk::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG
477 | vk::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG
478 | vk::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG
479 | vk::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG
480 | vk::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG => 8,
481 vk::Format::G8_B8R8_2PLANE_444_UNORM => 3,
482 vk::Format::G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16
483 | vk::Format::G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16
484 | vk::Format::G16_B16R16_2PLANE_444_UNORM => 6,
485 _ => 0,
490 }
491}
492
493pub const fn format_texel_block_extent(vk_format: vk::Format) -> (u32, u32) {
499 match vk_format {
500 vk::Format::UNDEFINED => (1, 1),
501 vk::Format::R4G4_UNORM_PACK8
502 | vk::Format::R8_UNORM
503 | vk::Format::R8_SNORM
504 | vk::Format::R8_USCALED
505 | vk::Format::R8_SSCALED
506 | vk::Format::R8_UINT
507 | vk::Format::R8_SINT
508 | vk::Format::R8_SRGB
509 | vk::Format::A1B5G5R5_UNORM_PACK16_KHR
510 | vk::Format::R10X6_UNORM_PACK16
511 | vk::Format::R12X4_UNORM_PACK16
512 | vk::Format::A4R4G4B4_UNORM_PACK16
513 | vk::Format::A4B4G4R4_UNORM_PACK16
514 | vk::Format::R4G4B4A4_UNORM_PACK16
515 | vk::Format::B4G4R4A4_UNORM_PACK16
516 | vk::Format::R5G6B5_UNORM_PACK16
517 | vk::Format::B5G6R5_UNORM_PACK16
518 | vk::Format::R5G5B5A1_UNORM_PACK16
519 | vk::Format::B5G5R5A1_UNORM_PACK16
520 | vk::Format::A1R5G5B5_UNORM_PACK16
521 | vk::Format::R8G8_UNORM
522 | vk::Format::R8G8_SNORM
523 | vk::Format::R8G8_USCALED
524 | vk::Format::R8G8_SSCALED
525 | vk::Format::R8G8_UINT
526 | vk::Format::R8G8_SINT
527 | vk::Format::R8G8_SRGB
528 | vk::Format::R16_UNORM
529 | vk::Format::R16_SNORM
530 | vk::Format::R16_USCALED
531 | vk::Format::R16_SSCALED
532 | vk::Format::R16_UINT
533 | vk::Format::R16_SINT
534 | vk::Format::R16_SFLOAT
535 | vk::Format::A8_UNORM_KHR
536 | vk::Format::R8G8B8_UNORM
537 | vk::Format::R8G8B8_SNORM
538 | vk::Format::R8G8B8_USCALED
539 | vk::Format::R8G8B8_SSCALED
540 | vk::Format::R8G8B8_UINT
541 | vk::Format::R8G8B8_SINT
542 | vk::Format::R8G8B8_SRGB
543 | vk::Format::B8G8R8_UNORM
544 | vk::Format::B8G8R8_SNORM
545 | vk::Format::B8G8R8_USCALED
546 | vk::Format::B8G8R8_SSCALED
547 | vk::Format::B8G8R8_UINT
548 | vk::Format::B8G8R8_SINT
549 | vk::Format::B8G8R8_SRGB
550 | vk::Format::R10X6G10X6_UNORM_2PACK16
551 | vk::Format::R12X4G12X4_UNORM_2PACK16
552 | vk::Format::R16G16_S10_5_NV
553 | vk::Format::R8G8B8A8_UNORM
554 | vk::Format::R8G8B8A8_SNORM
555 | vk::Format::R8G8B8A8_USCALED
556 | vk::Format::R8G8B8A8_SSCALED
557 | vk::Format::R8G8B8A8_UINT
558 | vk::Format::R8G8B8A8_SINT
559 | vk::Format::R8G8B8A8_SRGB
560 | vk::Format::B8G8R8A8_UNORM
561 | vk::Format::B8G8R8A8_SNORM
562 | vk::Format::B8G8R8A8_USCALED
563 | vk::Format::B8G8R8A8_SSCALED
564 | vk::Format::B8G8R8A8_UINT
565 | vk::Format::B8G8R8A8_SINT
566 | vk::Format::B8G8R8A8_SRGB
567 | vk::Format::A8B8G8R8_UNORM_PACK32
568 | vk::Format::A8B8G8R8_SNORM_PACK32
569 | vk::Format::A8B8G8R8_USCALED_PACK32
570 | vk::Format::A8B8G8R8_SSCALED_PACK32
571 | vk::Format::A8B8G8R8_UINT_PACK32
572 | vk::Format::A8B8G8R8_SINT_PACK32
573 | vk::Format::A8B8G8R8_SRGB_PACK32
574 | vk::Format::A2R10G10B10_UNORM_PACK32
575 | vk::Format::A2R10G10B10_SNORM_PACK32
576 | vk::Format::A2R10G10B10_USCALED_PACK32
577 | vk::Format::A2R10G10B10_SSCALED_PACK32
578 | vk::Format::A2R10G10B10_UINT_PACK32
579 | vk::Format::A2R10G10B10_SINT_PACK32
580 | vk::Format::A2B10G10R10_UNORM_PACK32
581 | vk::Format::A2B10G10R10_SNORM_PACK32
582 | vk::Format::A2B10G10R10_USCALED_PACK32
583 | vk::Format::A2B10G10R10_SSCALED_PACK32
584 | vk::Format::A2B10G10R10_UINT_PACK32
585 | vk::Format::A2B10G10R10_SINT_PACK32
586 | vk::Format::R16G16_UNORM
587 | vk::Format::R16G16_SNORM
588 | vk::Format::R16G16_USCALED
589 | vk::Format::R16G16_SSCALED
590 | vk::Format::R16G16_UINT
591 | vk::Format::R16G16_SINT
592 | vk::Format::R16G16_SFLOAT
593 | vk::Format::R32_UINT
594 | vk::Format::R32_SINT
595 | vk::Format::R32_SFLOAT
596 | vk::Format::B10G11R11_UFLOAT_PACK32
597 | vk::Format::E5B9G9R9_UFLOAT_PACK32
598 | vk::Format::R16G16B16_UNORM
599 | vk::Format::R16G16B16_SNORM
600 | vk::Format::R16G16B16_USCALED
601 | vk::Format::R16G16B16_SSCALED
602 | vk::Format::R16G16B16_UINT
603 | vk::Format::R16G16B16_SINT
604 | vk::Format::R16G16B16_SFLOAT
605 | vk::Format::R16G16B16A16_UNORM
606 | vk::Format::R16G16B16A16_SNORM
607 | vk::Format::R16G16B16A16_USCALED
608 | vk::Format::R16G16B16A16_SSCALED
609 | vk::Format::R16G16B16A16_UINT
610 | vk::Format::R16G16B16A16_SINT
611 | vk::Format::R16G16B16A16_SFLOAT
612 | vk::Format::R32G32_UINT
613 | vk::Format::R32G32_SINT
614 | vk::Format::R32G32_SFLOAT
615 | vk::Format::R64_UINT
616 | vk::Format::R64_SINT
617 | vk::Format::R64_SFLOAT
618 | vk::Format::R32G32B32_UINT
619 | vk::Format::R32G32B32_SINT
620 | vk::Format::R32G32B32_SFLOAT
621 | vk::Format::R32G32B32A32_UINT
622 | vk::Format::R32G32B32A32_SINT
623 | vk::Format::R32G32B32A32_SFLOAT
624 | vk::Format::R64G64_UINT
625 | vk::Format::R64G64_SINT
626 | vk::Format::R64G64_SFLOAT
627 | vk::Format::R64G64B64_UINT
628 | vk::Format::R64G64B64_SINT
629 | vk::Format::R64G64B64_SFLOAT
630 | vk::Format::R64G64B64A64_UINT
631 | vk::Format::R64G64B64A64_SINT
632 | vk::Format::R64G64B64A64_SFLOAT
633 | vk::Format::D16_UNORM
634 | vk::Format::X8_D24_UNORM_PACK32
635 | vk::Format::D32_SFLOAT
636 | vk::Format::S8_UINT
637 | vk::Format::D16_UNORM_S8_UINT
638 | vk::Format::D24_UNORM_S8_UINT
639 | vk::Format::D32_SFLOAT_S8_UINT => (1, 1),
640 vk::Format::BC1_RGB_UNORM_BLOCK
641 | vk::Format::BC1_RGB_SRGB_BLOCK
642 | vk::Format::BC1_RGBA_UNORM_BLOCK
643 | vk::Format::BC1_RGBA_SRGB_BLOCK
644 | vk::Format::BC2_UNORM_BLOCK
645 | vk::Format::BC2_SRGB_BLOCK
646 | vk::Format::BC3_UNORM_BLOCK
647 | vk::Format::BC3_SRGB_BLOCK
648 | vk::Format::BC4_UNORM_BLOCK
649 | vk::Format::BC4_SNORM_BLOCK
650 | vk::Format::BC5_UNORM_BLOCK
651 | vk::Format::BC5_SNORM_BLOCK
652 | vk::Format::BC6H_UFLOAT_BLOCK
653 | vk::Format::BC6H_SFLOAT_BLOCK
654 | vk::Format::BC7_UNORM_BLOCK
655 | vk::Format::BC7_SRGB_BLOCK
656 | vk::Format::ETC2_R8G8B8_UNORM_BLOCK
657 | vk::Format::ETC2_R8G8B8_SRGB_BLOCK
658 | vk::Format::ETC2_R8G8B8A1_UNORM_BLOCK
659 | vk::Format::ETC2_R8G8B8A1_SRGB_BLOCK
660 | vk::Format::ETC2_R8G8B8A8_UNORM_BLOCK
661 | vk::Format::ETC2_R8G8B8A8_SRGB_BLOCK
662 | vk::Format::EAC_R11_UNORM_BLOCK
663 | vk::Format::EAC_R11_SNORM_BLOCK
664 | vk::Format::EAC_R11G11_UNORM_BLOCK
665 | vk::Format::EAC_R11G11_SNORM_BLOCK => (4, 4),
666 vk::Format::ASTC_4X4_SFLOAT_BLOCK
667 | vk::Format::ASTC_4X4_UNORM_BLOCK
668 | vk::Format::ASTC_4X4_SRGB_BLOCK => (4, 4),
669 vk::Format::ASTC_5X4_SFLOAT_BLOCK
670 | vk::Format::ASTC_5X4_UNORM_BLOCK
671 | vk::Format::ASTC_5X4_SRGB_BLOCK => (5, 4),
672 vk::Format::ASTC_5X5_SFLOAT_BLOCK
673 | vk::Format::ASTC_5X5_UNORM_BLOCK
674 | vk::Format::ASTC_5X5_SRGB_BLOCK => (5, 5),
675 vk::Format::ASTC_6X5_SFLOAT_BLOCK
676 | vk::Format::ASTC_6X5_UNORM_BLOCK
677 | vk::Format::ASTC_6X5_SRGB_BLOCK => (6, 5),
678 vk::Format::ASTC_6X6_SFLOAT_BLOCK
679 | vk::Format::ASTC_6X6_UNORM_BLOCK
680 | vk::Format::ASTC_6X6_SRGB_BLOCK => (6, 6),
681 vk::Format::ASTC_8X5_SFLOAT_BLOCK
682 | vk::Format::ASTC_8X5_UNORM_BLOCK
683 | vk::Format::ASTC_8X5_SRGB_BLOCK => (8, 5),
684 vk::Format::ASTC_8X6_SFLOAT_BLOCK
685 | vk::Format::ASTC_8X6_UNORM_BLOCK
686 | vk::Format::ASTC_8X6_SRGB_BLOCK => (8, 6),
687 vk::Format::ASTC_8X8_SFLOAT_BLOCK
688 | vk::Format::ASTC_8X8_UNORM_BLOCK
689 | vk::Format::ASTC_8X8_SRGB_BLOCK => (8, 8),
690 vk::Format::ASTC_10X5_SFLOAT_BLOCK
691 | vk::Format::ASTC_10X5_UNORM_BLOCK
692 | vk::Format::ASTC_10X5_SRGB_BLOCK => (10, 5),
693 vk::Format::ASTC_10X6_SFLOAT_BLOCK
694 | vk::Format::ASTC_10X6_UNORM_BLOCK
695 | vk::Format::ASTC_10X6_SRGB_BLOCK => (10, 6),
696 vk::Format::ASTC_10X8_SFLOAT_BLOCK
697 | vk::Format::ASTC_10X8_UNORM_BLOCK
698 | vk::Format::ASTC_10X8_SRGB_BLOCK => (10, 8),
699 vk::Format::ASTC_10X10_SFLOAT_BLOCK
700 | vk::Format::ASTC_10X10_UNORM_BLOCK
701 | vk::Format::ASTC_10X10_SRGB_BLOCK => (10, 10),
702 vk::Format::ASTC_12X10_SFLOAT_BLOCK
703 | vk::Format::ASTC_12X10_UNORM_BLOCK
704 | vk::Format::ASTC_12X10_SRGB_BLOCK => (12, 10),
705 vk::Format::ASTC_12X12_SFLOAT_BLOCK
706 | vk::Format::ASTC_12X12_UNORM_BLOCK
707 | vk::Format::ASTC_12X12_SRGB_BLOCK => (12, 12),
708 vk::Format::G8B8G8R8_422_UNORM | vk::Format::B8G8R8G8_422_UNORM => (2, 1),
709 vk::Format::G8_B8_R8_3PLANE_420_UNORM
710 | vk::Format::G8_B8R8_2PLANE_420_UNORM
711 | vk::Format::G8_B8_R8_3PLANE_422_UNORM
712 | vk::Format::G8_B8R8_2PLANE_422_UNORM
713 | vk::Format::G8_B8_R8_3PLANE_444_UNORM
714 | vk::Format::R10X6G10X6B10X6A10X6_UNORM_4PACK16
715 | vk::Format::G10X6B10X6G10X6R10X6_422_UNORM_4PACK16
716 | vk::Format::B10X6G10X6R10X6G10X6_422_UNORM_4PACK16
717 | vk::Format::G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16
718 | vk::Format::G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
719 | vk::Format::G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16
720 | vk::Format::G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16
721 | vk::Format::G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16
722 | vk::Format::R12X4G12X4B12X4A12X4_UNORM_4PACK16
723 | vk::Format::G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16
724 | vk::Format::G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16
725 | vk::Format::G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16
726 | vk::Format::G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16
727 | vk::Format::G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16
728 | vk::Format::G16_B16_R16_3PLANE_420_UNORM
729 | vk::Format::G16_B16R16_2PLANE_420_UNORM
730 | vk::Format::G16_B16_R16_3PLANE_422_UNORM
731 | vk::Format::G16_B16R16_2PLANE_422_UNORM
732 | vk::Format::G16_B16_R16_3PLANE_444_UNORM
733 | vk::Format::G8_B8R8_2PLANE_444_UNORM
734 | vk::Format::G10X6_B10X6R10X6_2PLANE_444_UNORM_3PACK16
735 | vk::Format::G12X4_B12X4R12X4_2PLANE_444_UNORM_3PACK16
736 | vk::Format::G16_B16R16_2PLANE_444_UNORM => (1, 1),
737 vk::Format::G12X4B12X4G12X4R12X4_422_UNORM_4PACK16
738 | vk::Format::B12X4G12X4R12X4G12X4_422_UNORM_4PACK16
739 | vk::Format::G16B16G16R16_422_UNORM
740 | vk::Format::B16G16R16G16_422_UNORM => (2, 1),
741 vk::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG
742 | vk::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG
743 | vk::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG
744 | vk::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG => (8, 4),
745 vk::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG
746 | vk::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG
747 | vk::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG
748 | vk::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG => (4, 4),
749 _ => (1, 1),
754 }
755}
756
757pub(super) const fn image_subresource_range_from_layers(
758 vk::ImageSubresourceLayers {
759 aspect_mask,
760 mip_level,
761 base_array_layer,
762 layer_count,
763 }: vk::ImageSubresourceLayers,
764) -> vk::ImageSubresourceRange {
765 vk::ImageSubresourceRange {
766 aspect_mask,
767 base_mip_level: mip_level,
768 level_count: 1,
769 base_array_layer,
770 layer_count,
771 }
772}
773
774pub(super) const fn initial_image_layout_access(
775 ty: self::sync::AccessType,
776) -> self::sync::AccessType {
777 use self::sync::AccessType::*;
778 match ty {
779 DepthStencilAttachmentReadWrite => DepthStencilAttachmentRead,
780 _ => ty,
781 }
782}
783
784pub(super) const fn is_read_access(ty: self::sync::AccessType) -> bool {
785 use self::sync::AccessType::*;
786 match ty {
787 Nothing
788 | CommandBufferWriteNVX
789 | VertexShaderWrite
790 | TessellationControlShaderWrite
791 | TessellationEvaluationShaderWrite
792 | GeometryShaderWrite
793 | FragmentShaderWrite
794 | ColorAttachmentWrite
795 | DepthStencilAttachmentWrite
796 | ComputeShaderWrite
797 | AnyShaderWrite
798 | TransferWrite
799 | HostWrite
800 | AccelerationStructureBuildWrite
801 | AccelerationStructureBufferWrite
802 | MeshShaderWrite
803 | TaskShaderWrite => false,
804 CommandBufferReadNVX
805 | IndirectBuffer
806 | IndexBuffer
807 | VertexBuffer
808 | VertexShaderReadUniformBuffer
809 | VertexShaderReadSampledImageOrUniformTexelBuffer
810 | VertexShaderReadOther
811 | TessellationControlShaderReadUniformBuffer
812 | TessellationControlShaderReadSampledImageOrUniformTexelBuffer
813 | TessellationControlShaderReadOther
814 | TessellationEvaluationShaderReadUniformBuffer
815 | TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer
816 | TessellationEvaluationShaderReadOther
817 | GeometryShaderReadUniformBuffer
818 | GeometryShaderReadSampledImageOrUniformTexelBuffer
819 | GeometryShaderReadOther
820 | FragmentShaderReadUniformBuffer
821 | FragmentShaderReadSampledImageOrUniformTexelBuffer
822 | FragmentShaderReadColorInputAttachment
823 | FragmentShaderReadDepthStencilInputAttachment
824 | FragmentShaderReadOther
825 | ColorAttachmentRead
826 | DepthStencilAttachmentRead
827 | ComputeShaderReadUniformBuffer
828 | ComputeShaderReadSampledImageOrUniformTexelBuffer
829 | ComputeShaderReadOther
830 | AnyShaderReadUniformBuffer
831 | AnyShaderReadUniformBufferOrVertexBuffer
832 | AnyShaderReadSampledImageOrUniformTexelBuffer
833 | AnyShaderReadOther
834 | TransferRead
835 | HostRead
836 | Present
837 | RayTracingShaderReadSampledImageOrUniformTexelBuffer
838 | RayTracingShaderReadColorInputAttachment
839 | RayTracingShaderReadDepthStencilInputAttachment
840 | RayTracingShaderReadAccelerationStructure
841 | RayTracingShaderReadOther
842 | AccelerationStructureBuildRead
843 | MeshShaderReadUniformBuffer
844 | MeshShaderReadSampledImageOrUniformTexelBuffer
845 | MeshShaderReadOther
846 | TaskShaderReadUniformBuffer
847 | TaskShaderReadSampledImageOrUniformTexelBuffer
848 | TaskShaderReadOther
849 | DepthStencilAttachmentReadWrite
850 | DepthAttachmentWriteStencilReadOnly
851 | StencilAttachmentWriteDepthReadOnly
852 | ColorAttachmentReadWrite
853 | General
854 | ComputeShaderReadWrite => true,
855 }
856}
857
858#[profiling::function]
869fn merge_push_constant_ranges(pcr: &[vk::PushConstantRange]) -> Vec<vk::PushConstantRange> {
870 #[cfg(feature = "checked")]
872 {
873 let mut stage_flags = vk::ShaderStageFlags::empty();
874 for item in pcr.iter() {
875 assert_eq!(item.stage_flags.as_raw().count_ones(), 1);
876 assert!(!stage_flags.contains(item.stage_flags));
877 assert!(item.size > 0);
878
879 stage_flags |= item.stage_flags;
880 }
881 }
882
883 match pcr.len() {
884 0 => vec![],
885 1 => vec![pcr[0]],
886 _ => {
887 let mut res = pcr.to_vec();
888 let sort_fn = |lhs: &vk::PushConstantRange, rhs: &vk::PushConstantRange| match lhs
889 .offset
890 .cmp(&rhs.offset)
891 {
892 Ordering::Equal => lhs.size.cmp(&rhs.size),
893 res => res,
894 };
895
896 res.sort_unstable_by(sort_fn);
897
898 let mut i = 0;
899 let mut j = 1;
900
901 while j < res.len() {
902 let lhs = res[i];
903 let rhs = res[j];
904
905 if lhs.offset == rhs.offset && lhs.size == rhs.size {
906 res[i].stage_flags |= rhs.stage_flags;
907 let _ = res.remove(j);
908 } else if lhs.offset == rhs.offset {
909 res[i].stage_flags |= rhs.stage_flags;
910 res[j].offset += lhs.size;
911 res[j].size -= lhs.size;
912 res[j..].sort_unstable_by(sort_fn);
913 } else if lhs.offset + lhs.size > rhs.offset + rhs.size {
914 res[i].size = rhs.offset - lhs.offset;
915 res[j].stage_flags = lhs.stage_flags;
916 res[j].offset += rhs.size;
917 res[j].size = (lhs.offset + lhs.size) - (rhs.offset + rhs.size);
918 res.insert(
919 j,
920 vk::PushConstantRange {
921 stage_flags: lhs.stage_flags | rhs.stage_flags,
922 offset: rhs.offset,
923 size: rhs.size,
924 },
925 );
926 res[j..].sort_unstable_by(sort_fn);
927 i += 1;
928 j += 1;
929 } else if lhs.offset + lhs.size == rhs.offset + rhs.size {
930 res[i].size -= rhs.size;
931 res[j].stage_flags |= lhs.stage_flags;
932 i += 1;
933 j += 1;
934 } else if lhs.offset + lhs.size > rhs.offset
935 && lhs.offset + lhs.size < rhs.offset + rhs.size
936 {
937 res[i].size = rhs.offset - lhs.offset;
938 res[j].offset = lhs.offset + lhs.size;
939 res[j].size = (rhs.offset + rhs.size) - (lhs.offset + lhs.size);
940 res.insert(
941 j,
942 vk::PushConstantRange {
943 stage_flags: lhs.stage_flags | rhs.stage_flags,
944 offset: rhs.offset,
945 size: (lhs.offset + lhs.size) - rhs.offset,
946 },
947 );
948 res[j..].sort_unstable_by(sort_fn);
949 } else {
950 i += 1;
951 j += 1;
952 }
953 }
954
955 res
956 }
957 }
958}
959
960pub(super) const fn pipeline_stage_access_flags(
961 access_type: vk_sync::AccessType,
962) -> (vk::PipelineStageFlags, vk::AccessFlags) {
963 use {
964 vk::{AccessFlags as access, PipelineStageFlags as stage},
965 vk_sync::AccessType as ty,
966 };
967
968 match access_type {
969 ty::Nothing => (stage::empty(), access::empty()),
970 ty::CommandBufferReadNVX => (
971 stage::COMMAND_PREPROCESS_NV,
972 access::COMMAND_PREPROCESS_READ_NV,
973 ),
974 ty::IndirectBuffer => (stage::DRAW_INDIRECT, access::INDIRECT_COMMAND_READ),
975 ty::IndexBuffer => (stage::VERTEX_INPUT, access::INDEX_READ),
976 ty::VertexBuffer => (stage::VERTEX_INPUT, access::VERTEX_ATTRIBUTE_READ),
977 ty::VertexShaderReadUniformBuffer => (stage::VERTEX_SHADER, access::SHADER_READ),
978 ty::VertexShaderReadSampledImageOrUniformTexelBuffer => {
979 (stage::VERTEX_SHADER, access::SHADER_READ)
980 }
981 ty::VertexShaderReadOther => (stage::VERTEX_SHADER, access::SHADER_READ),
982 ty::TessellationControlShaderReadUniformBuffer => {
983 (stage::TESSELLATION_CONTROL_SHADER, access::UNIFORM_READ)
984 }
985 ty::TessellationControlShaderReadSampledImageOrUniformTexelBuffer => {
986 (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_READ)
987 }
988 ty::TessellationControlShaderReadOther => {
989 (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_READ)
990 }
991 ty::TessellationEvaluationShaderReadUniformBuffer => {
992 (stage::TESSELLATION_EVALUATION_SHADER, access::UNIFORM_READ)
993 }
994 ty::TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer => {
995 (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_READ)
996 }
997 ty::TessellationEvaluationShaderReadOther => {
998 (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_READ)
999 }
1000 ty::GeometryShaderReadUniformBuffer => (stage::GEOMETRY_SHADER, access::UNIFORM_READ),
1001 ty::GeometryShaderReadSampledImageOrUniformTexelBuffer => {
1002 (stage::GEOMETRY_SHADER, access::SHADER_READ)
1003 }
1004 ty::GeometryShaderReadOther => (stage::GEOMETRY_SHADER, access::SHADER_READ),
1005 ty::FragmentShaderReadUniformBuffer => (stage::FRAGMENT_SHADER, access::UNIFORM_READ),
1006 ty::FragmentShaderReadSampledImageOrUniformTexelBuffer => {
1007 (stage::FRAGMENT_SHADER, access::SHADER_READ)
1008 }
1009 ty::FragmentShaderReadColorInputAttachment => {
1010 (stage::FRAGMENT_SHADER, access::INPUT_ATTACHMENT_READ)
1011 }
1012 ty::FragmentShaderReadDepthStencilInputAttachment => {
1013 (stage::FRAGMENT_SHADER, access::INPUT_ATTACHMENT_READ)
1014 }
1015 ty::FragmentShaderReadOther => (stage::FRAGMENT_SHADER, access::SHADER_READ),
1016 ty::ColorAttachmentRead => (
1017 stage::COLOR_ATTACHMENT_OUTPUT,
1018 access::COLOR_ATTACHMENT_READ,
1019 ),
1020 ty::DepthStencilAttachmentRead => (
1021 stage::from_raw(
1022 stage::EARLY_FRAGMENT_TESTS.as_raw()
1023 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1024 ),
1025 access::DEPTH_STENCIL_ATTACHMENT_READ,
1026 ),
1027 ty::ComputeShaderReadUniformBuffer => (stage::COMPUTE_SHADER, access::UNIFORM_READ),
1028 ty::ComputeShaderReadSampledImageOrUniformTexelBuffer => {
1029 (stage::COMPUTE_SHADER, access::SHADER_READ)
1030 }
1031 ty::ComputeShaderReadOther => (stage::COMPUTE_SHADER, access::SHADER_READ),
1032 ty::AnyShaderReadUniformBuffer => (stage::ALL_COMMANDS, access::UNIFORM_READ),
1033 ty::AnyShaderReadUniformBufferOrVertexBuffer => (
1034 stage::ALL_COMMANDS,
1035 access::from_raw(
1036 access::UNIFORM_READ.as_raw() | vk::AccessFlags::VERTEX_ATTRIBUTE_READ.as_raw(),
1037 ),
1038 ),
1039 ty::AnyShaderReadSampledImageOrUniformTexelBuffer => {
1040 (stage::ALL_COMMANDS, access::SHADER_READ)
1041 }
1042 ty::AnyShaderReadOther => (stage::ALL_COMMANDS, access::SHADER_READ),
1043 ty::TransferRead => (stage::TRANSFER, access::TRANSFER_READ),
1044 ty::HostRead => (stage::HOST, access::HOST_READ),
1045 ty::Present => (stage::empty(), access::empty()),
1046 ty::CommandBufferWriteNVX => (
1047 stage::COMMAND_PREPROCESS_NV,
1048 access::COMMAND_PREPROCESS_WRITE_NV,
1049 ),
1050 ty::VertexShaderWrite => (stage::VERTEX_SHADER, access::SHADER_WRITE),
1051 ty::TessellationControlShaderWrite => {
1052 (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_WRITE)
1053 }
1054 ty::TessellationEvaluationShaderWrite => {
1055 (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_WRITE)
1056 }
1057 ty::GeometryShaderWrite => (stage::GEOMETRY_SHADER, access::SHADER_WRITE),
1058 ty::FragmentShaderWrite => (stage::FRAGMENT_SHADER, access::SHADER_WRITE),
1059 ty::ColorAttachmentWrite => (
1060 stage::COLOR_ATTACHMENT_OUTPUT,
1061 access::COLOR_ATTACHMENT_WRITE,
1062 ),
1063 ty::DepthStencilAttachmentWrite => (
1064 stage::from_raw(
1065 stage::EARLY_FRAGMENT_TESTS.as_raw()
1066 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1067 ),
1068 access::DEPTH_STENCIL_ATTACHMENT_WRITE,
1069 ),
1070 ty::DepthStencilAttachmentReadWrite => (
1071 stage::from_raw(
1072 stage::EARLY_FRAGMENT_TESTS.as_raw()
1073 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1074 ),
1075 access::from_raw(
1076 access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
1077 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
1078 ),
1079 ),
1080 ty::DepthAttachmentWriteStencilReadOnly => (
1081 stage::from_raw(
1082 stage::EARLY_FRAGMENT_TESTS.as_raw()
1083 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1084 ),
1085 access::from_raw(
1086 access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
1087 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
1088 ),
1089 ),
1090 ty::StencilAttachmentWriteDepthReadOnly => (
1091 stage::from_raw(
1092 stage::EARLY_FRAGMENT_TESTS.as_raw()
1093 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
1094 ),
1095 access::from_raw(
1096 access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
1097 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
1098 ),
1099 ),
1100 ty::ComputeShaderWrite => (stage::COMPUTE_SHADER, access::SHADER_WRITE),
1101 ty::ComputeShaderReadWrite => (
1102 stage::COMPUTE_SHADER,
1103 access::from_raw(access::SHADER_WRITE.as_raw() | access::SHADER_READ.as_raw()),
1104 ),
1105 ty::AnyShaderWrite => (stage::ALL_COMMANDS, access::SHADER_WRITE),
1106 ty::TransferWrite => (stage::TRANSFER, access::TRANSFER_WRITE),
1107 ty::HostWrite => (stage::HOST, access::HOST_WRITE),
1108 ty::ColorAttachmentReadWrite => (
1109 stage::COLOR_ATTACHMENT_OUTPUT,
1110 access::from_raw(
1111 access::COLOR_ATTACHMENT_READ.as_raw()
1112 | vk::AccessFlags::COLOR_ATTACHMENT_WRITE.as_raw(),
1113 ),
1114 ),
1115 ty::General => (
1116 stage::ALL_COMMANDS,
1117 access::from_raw(access::MEMORY_READ.as_raw() | vk::AccessFlags::MEMORY_WRITE.as_raw()),
1118 ),
1119 ty::RayTracingShaderReadSampledImageOrUniformTexelBuffer => {
1120 (stage::RAY_TRACING_SHADER_KHR, access::SHADER_READ)
1121 }
1122 ty::RayTracingShaderReadColorInputAttachment => {
1123 (stage::RAY_TRACING_SHADER_KHR, access::INPUT_ATTACHMENT_READ)
1124 }
1125 ty::RayTracingShaderReadDepthStencilInputAttachment => {
1126 (stage::RAY_TRACING_SHADER_KHR, access::INPUT_ATTACHMENT_READ)
1127 }
1128 ty::RayTracingShaderReadAccelerationStructure => (
1129 stage::RAY_TRACING_SHADER_KHR,
1130 access::ACCELERATION_STRUCTURE_READ_KHR,
1131 ),
1132 ty::RayTracingShaderReadOther => (stage::RAY_TRACING_SHADER_KHR, access::SHADER_READ),
1133 ty::AccelerationStructureBuildWrite => (
1134 stage::ACCELERATION_STRUCTURE_BUILD_KHR,
1135 access::ACCELERATION_STRUCTURE_WRITE_KHR,
1136 ),
1137 ty::AccelerationStructureBuildRead => (
1138 stage::ACCELERATION_STRUCTURE_BUILD_KHR,
1139 access::ACCELERATION_STRUCTURE_READ_KHR,
1140 ),
1141 ty::AccelerationStructureBufferWrite => (
1142 stage::ACCELERATION_STRUCTURE_BUILD_KHR,
1143 access::TRANSFER_WRITE,
1144 ),
1145 ty::MeshShaderReadUniformBuffer => (stage::MESH_SHADER_EXT, access::SHADER_READ),
1146 ty::MeshShaderReadSampledImageOrUniformTexelBuffer => {
1147 (stage::MESH_SHADER_EXT, access::SHADER_READ)
1148 }
1149 ty::MeshShaderReadOther => (stage::MESH_SHADER_EXT, access::SHADER_READ),
1150 ty::TaskShaderReadUniformBuffer => (stage::TASK_SHADER_EXT, access::SHADER_READ),
1151 ty::TaskShaderReadSampledImageOrUniformTexelBuffer => {
1152 (stage::TASK_SHADER_EXT, access::SHADER_READ)
1153 }
1154 ty::TaskShaderReadOther => (stage::TASK_SHADER_EXT, access::SHADER_READ),
1155 ty::MeshShaderWrite => (stage::MESH_SHADER_EXT, access::SHADER_WRITE),
1156 ty::TaskShaderWrite => (stage::TASK_SHADER_EXT, access::SHADER_WRITE),
1157 }
1158}
1159
1160#[derive(Clone, Copy, Debug)]
1170pub enum DriverError {
1171 InvalidData,
1173
1174 Unsupported,
1176
1177 OutOfMemory,
1181}
1182
1183impl DriverError {
1184 fn from_alloc_err(err: AllocationError) -> Self {
1185 match err {
1186 AllocationError::OutOfMemory => Self::OutOfMemory,
1187 AllocationError::InvalidAllocationCreateDesc
1188 | AllocationError::InvalidAllocatorCreateDesc(_) => Self::InvalidData,
1189 AllocationError::FailedToMap(_)
1190 | AllocationError::NoCompatibleMemoryTypeFound
1191 | AllocationError::Internal(_)
1192 | AllocationError::BarrierLayoutNeedsDevice10
1193 | AllocationError::CastableFormatsRequiresEnhancedBarriers
1194 | AllocationError::CastableFormatsRequiresAtLeastDevice12 => Self::Unsupported,
1195 }
1196 }
1197}
1198
1199impl From<Infallible> for DriverError {
1200 fn from(value: Infallible) -> Self {
1201 match value {}
1202 }
1203}
1204
1205impl Display for DriverError {
1206 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1207 write!(f, "{:?}", self)
1208 }
1209}
1210
1211impl Error for DriverError {}
1212
1213#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1214pub(super) enum SharingMode {
1215 Concurrent,
1216 Exclusive(Option<(u32, u32)>),
1217}
1218
1219impl SharingMode {
1220 const MODE_CONCURRENT: u64 = u64::MAX;
1221 const MODE_UNKNOWN: u64 = u64::MAX - 1;
1222
1223 pub(super) const fn decode(val: u64) -> Self {
1224 if val == Self::MODE_CONCURRENT {
1225 Self::Concurrent
1226 } else if val == Self::MODE_UNKNOWN {
1227 Self::Exclusive(None)
1228 } else {
1229 Self::Exclusive(Some(((val >> 32) as u32, val as u32)))
1230 }
1231 }
1232
1233 pub(super) const fn encode(self) -> u64 {
1234 match self {
1235 SharingMode::Concurrent => Self::MODE_CONCURRENT,
1236 SharingMode::Exclusive(None) => Self::MODE_UNKNOWN,
1237 SharingMode::Exclusive(Some((family, index))) => (family as u64) << 32 | index as u64,
1238 }
1239 }
1240}
1241
1242#[cfg(test)]
1243mod test {
1244 use {super::merge_push_constant_ranges, ash::vk};
1245
1246 macro_rules! assert_pcr_eq {
1247 ($lhs: expr, $rhs: expr,) => {
1248 assert_eq!($lhs.stage_flags, $rhs.stage_flags, "Stages flags not equal");
1249 assert_eq!($lhs.offset, $rhs.offset, "Offset not equal");
1250 assert_eq!($lhs.size, $rhs.size, "Size not equal");
1251 };
1252 }
1253
1254 fn reference_merge_push_constant_ranges(
1255 pcr: &[vk::PushConstantRange],
1256 ) -> Vec<vk::PushConstantRange> {
1257 if pcr.is_empty() {
1258 return vec![];
1259 }
1260 let end = pcr.iter().map(|r| r.offset + r.size).max().unwrap();
1261 let mut per_byte = vec![0u32; end as usize];
1262 for r in pcr {
1263 let raw = r.stage_flags.as_raw();
1264 let range_end = r.offset + r.size;
1265 for byte in per_byte[r.offset as usize..range_end as usize].iter_mut() {
1266 *byte |= raw;
1267 }
1268 }
1269 let mut result = Vec::new();
1270 let mut i = 0usize;
1271 while (i as u32) < end {
1272 let flags = per_byte[i];
1273 if flags == 0 {
1274 i += 1;
1275 continue;
1276 }
1277 let start = i as u32;
1278 while (i as u32) < end && per_byte[i] == flags {
1279 i += 1;
1280 }
1281 result.push(vk::PushConstantRange {
1282 stage_flags: vk::ShaderStageFlags::from_raw(flags),
1283 offset: start,
1284 size: (i as u32) - start,
1285 });
1286 }
1287 result
1288 }
1289
1290 fn assert_merge_invariants(input: &[vk::PushConstantRange], output: &[vk::PushConstantRange]) {
1291 let expected = reference_merge_push_constant_ranges(input);
1292 assert_eq!(
1293 output.len(),
1294 expected.len(),
1295 "length mismatch\n input: {input:?}\n got: {output:?}\n expected: {expected:?}"
1296 );
1297 for (idx, (got, exp)) in output.iter().zip(expected.iter()).enumerate() {
1298 assert_eq!(
1299 got.stage_flags, exp.stage_flags,
1300 "result[{idx}] stage_flags mismatch\n input: {input:?}\n got: {output:?}\n expected: {expected:?}"
1301 );
1302 assert_eq!(
1303 got.offset, exp.offset,
1304 "result[{idx}] offset mismatch\n input: {input:?}\n got: {output:?}\n expected: {expected:?}"
1305 );
1306 assert_eq!(
1307 got.size, exp.size,
1308 "result[{idx}] size mismatch\n input: {input:?}\n got: {output:?}\n expected: {expected:?}"
1309 );
1310 }
1311 }
1312
1313 #[test]
1314 pub fn push_constant_ranges_complex() {
1315 let res = merge_push_constant_ranges(&[
1316 vk::PushConstantRange {
1317 stage_flags: vk::ShaderStageFlags::VERTEX,
1318 offset: 8,
1319 size: 16,
1320 },
1321 vk::PushConstantRange {
1322 stage_flags: vk::ShaderStageFlags::GEOMETRY,
1323 offset: 20,
1324 size: 48,
1325 },
1326 vk::PushConstantRange {
1327 stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL,
1328 offset: 24,
1329 size: 8,
1330 },
1331 vk::PushConstantRange {
1332 stage_flags: vk::ShaderStageFlags::TESSELLATION_EVALUATION,
1333 offset: 28,
1334 size: 32,
1335 },
1336 vk::PushConstantRange {
1337 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1338 offset: 40,
1339 size: 128,
1340 },
1341 ]);
1342
1343 assert_eq!(res.len(), 8);
1344 assert_pcr_eq!(
1345 res[0],
1346 vk::PushConstantRange {
1347 stage_flags: vk::ShaderStageFlags::VERTEX,
1348 offset: 8,
1349 size: 12,
1350 },
1351 );
1352 assert_pcr_eq!(
1353 res[1],
1354 vk::PushConstantRange {
1355 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
1356 offset: 20,
1357 size: 4,
1358 },
1359 );
1360 assert_pcr_eq!(
1361 res[2],
1362 vk::PushConstantRange {
1363 stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL
1364 | vk::ShaderStageFlags::GEOMETRY,
1365 offset: 24,
1366 size: 4,
1367 },
1368 );
1369 assert_pcr_eq!(
1370 res[3],
1371 vk::PushConstantRange {
1372 stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL
1373 | vk::ShaderStageFlags::TESSELLATION_EVALUATION
1374 | vk::ShaderStageFlags::GEOMETRY,
1375 offset: 28,
1376 size: 4,
1377 },
1378 );
1379 assert_pcr_eq!(
1380 res[4],
1381 vk::PushConstantRange {
1382 stage_flags: vk::ShaderStageFlags::GEOMETRY
1383 | vk::ShaderStageFlags::TESSELLATION_EVALUATION,
1384 offset: 32,
1385 size: 8,
1386 },
1387 );
1388 assert_pcr_eq!(
1389 res[5],
1390 vk::PushConstantRange {
1391 stage_flags: vk::ShaderStageFlags::GEOMETRY
1392 | vk::ShaderStageFlags::TESSELLATION_EVALUATION
1393 | vk::ShaderStageFlags::FRAGMENT,
1394 offset: 40,
1395 size: 20,
1396 },
1397 );
1398 assert_pcr_eq!(
1399 res[6],
1400 vk::PushConstantRange {
1401 stage_flags: vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::GEOMETRY,
1402 offset: 60,
1403 size: 8,
1404 },
1405 );
1406 assert_pcr_eq!(
1407 res[7],
1408 vk::PushConstantRange {
1409 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1410 offset: 68,
1411 size: 100,
1412 },
1413 );
1414 }
1415
1416 #[test]
1417 pub fn push_constant_ranges_disjoint() {
1418 let res = merge_push_constant_ranges(&[
1419 vk::PushConstantRange {
1420 stage_flags: vk::ShaderStageFlags::VERTEX,
1421 offset: 0,
1422 size: 32,
1423 },
1424 vk::PushConstantRange {
1425 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1426 offset: 32,
1427 size: 64,
1428 },
1429 ]);
1430
1431 assert_eq!(res.len(), 2);
1432 assert_pcr_eq!(
1433 res[0],
1434 vk::PushConstantRange {
1435 stage_flags: vk::ShaderStageFlags::VERTEX,
1436 offset: 0,
1437 size: 32,
1438 },
1439 );
1440 assert_pcr_eq!(
1441 res[1],
1442 vk::PushConstantRange {
1443 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1444 offset: 32,
1445 size: 64,
1446 },
1447 );
1448 }
1449
1450 #[test]
1451 pub fn push_constant_ranges_equal() {
1452 let res = merge_push_constant_ranges(&[
1453 vk::PushConstantRange {
1454 stage_flags: vk::ShaderStageFlags::VERTEX,
1455 offset: 0,
1456 size: 32,
1457 },
1458 vk::PushConstantRange {
1459 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1460 offset: 0,
1461 size: 32,
1462 },
1463 ]);
1464
1465 assert_eq!(res.len(), 1);
1466 assert_pcr_eq!(
1467 res[0],
1468 vk::PushConstantRange {
1469 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1470 offset: 0,
1471 size: 32,
1472 },
1473 );
1474 }
1475
1476 #[test]
1477 pub fn push_constant_ranges_overlap() {
1478 let res = merge_push_constant_ranges(&[
1479 vk::PushConstantRange {
1480 stage_flags: vk::ShaderStageFlags::VERTEX,
1481 offset: 0,
1482 size: 24,
1483 },
1484 vk::PushConstantRange {
1485 stage_flags: vk::ShaderStageFlags::GEOMETRY,
1486 offset: 8,
1487 size: 24,
1488 },
1489 vk::PushConstantRange {
1490 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1491 offset: 20,
1492 size: 28,
1493 },
1494 ]);
1495
1496 assert_eq!(res.len(), 5);
1497 assert_pcr_eq!(
1498 res[0],
1499 vk::PushConstantRange {
1500 stage_flags: vk::ShaderStageFlags::VERTEX,
1501 offset: 0,
1502 size: 8,
1503 },
1504 );
1505 assert_pcr_eq!(
1506 res[1],
1507 vk::PushConstantRange {
1508 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
1509 offset: 8,
1510 size: 12,
1511 },
1512 );
1513 assert_pcr_eq!(
1514 res[2],
1515 vk::PushConstantRange {
1516 stage_flags: vk::ShaderStageFlags::VERTEX
1517 | vk::ShaderStageFlags::GEOMETRY
1518 | vk::ShaderStageFlags::FRAGMENT,
1519 offset: 20,
1520 size: 4,
1521 },
1522 );
1523 assert_pcr_eq!(
1524 res[3],
1525 vk::PushConstantRange {
1526 stage_flags: vk::ShaderStageFlags::GEOMETRY | vk::ShaderStageFlags::FRAGMENT,
1527 offset: 24,
1528 size: 8,
1529 },
1530 );
1531 assert_pcr_eq!(
1532 res[4],
1533 vk::PushConstantRange {
1534 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1535 offset: 32,
1536 size: 16,
1537 },
1538 );
1539 }
1540
1541 #[test]
1542 pub fn push_constant_ranges_subset() {
1543 let res = merge_push_constant_ranges(&[
1544 vk::PushConstantRange {
1545 stage_flags: vk::ShaderStageFlags::VERTEX,
1546 offset: 0,
1547 size: 64,
1548 },
1549 vk::PushConstantRange {
1550 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1551 offset: 16,
1552 size: 8,
1553 },
1554 ]);
1555
1556 assert_eq!(res.len(), 3);
1557 assert_pcr_eq!(
1558 res[0],
1559 vk::PushConstantRange {
1560 stage_flags: vk::ShaderStageFlags::VERTEX,
1561 offset: 0,
1562 size: 16,
1563 },
1564 );
1565 assert_pcr_eq!(
1566 res[1],
1567 vk::PushConstantRange {
1568 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1569 offset: 16,
1570 size: 8,
1571 },
1572 );
1573 assert_pcr_eq!(
1574 res[2],
1575 vk::PushConstantRange {
1576 stage_flags: vk::ShaderStageFlags::VERTEX,
1577 offset: 24,
1578 size: 40,
1579 },
1580 );
1581 }
1582
1583 #[test]
1584 pub fn push_constant_ranges_superset() {
1585 let res = merge_push_constant_ranges(&[
1586 vk::PushConstantRange {
1587 stage_flags: vk::ShaderStageFlags::VERTEX,
1588 offset: 0,
1589 size: 64,
1590 },
1591 vk::PushConstantRange {
1592 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1593 offset: 0,
1594 size: 80,
1595 },
1596 ]);
1597
1598 assert_eq!(res.len(), 2);
1599 assert_pcr_eq!(
1600 res[0],
1601 vk::PushConstantRange {
1602 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1603 offset: 0,
1604 size: 64,
1605 },
1606 );
1607 assert_pcr_eq!(
1608 res[1],
1609 vk::PushConstantRange {
1610 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1611 offset: 64,
1612 size: 16,
1613 },
1614 );
1615 }
1616
1617 #[test]
1618 pub fn push_constant_ranges_single() {
1619 let input = [vk::PushConstantRange {
1620 stage_flags: vk::ShaderStageFlags::VERTEX,
1621 offset: 16,
1622 size: 32,
1623 }];
1624 let res = merge_push_constant_ranges(&input);
1625 assert_eq!(res.len(), 1);
1626 assert_pcr_eq!(
1627 res[0],
1628 vk::PushConstantRange {
1629 stage_flags: vk::ShaderStageFlags::VERTEX,
1630 offset: 16,
1631 size: 32,
1632 },
1633 );
1634 assert_merge_invariants(&input, &res);
1635 }
1636
1637 #[test]
1638 pub fn push_constant_ranges_three_identical() {
1639 let input = [
1640 vk::PushConstantRange {
1641 stage_flags: vk::ShaderStageFlags::VERTEX,
1642 offset: 0,
1643 size: 32,
1644 },
1645 vk::PushConstantRange {
1646 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1647 offset: 0,
1648 size: 32,
1649 },
1650 vk::PushConstantRange {
1651 stage_flags: vk::ShaderStageFlags::COMPUTE,
1652 offset: 0,
1653 size: 32,
1654 },
1655 ];
1656 let res = merge_push_constant_ranges(&input);
1657 assert_eq!(res.len(), 1);
1658 assert_pcr_eq!(
1659 res[0],
1660 vk::PushConstantRange {
1661 stage_flags: vk::ShaderStageFlags::VERTEX
1662 | vk::ShaderStageFlags::FRAGMENT
1663 | vk::ShaderStageFlags::COMPUTE,
1664 offset: 0,
1665 size: 32,
1666 },
1667 );
1668 assert_merge_invariants(&input, &res);
1669 }
1670
1671 #[test]
1672 pub fn push_constant_ranges_three_same_offset() {
1673 let input = [
1674 vk::PushConstantRange {
1675 stage_flags: vk::ShaderStageFlags::VERTEX,
1676 offset: 0,
1677 size: 8,
1678 },
1679 vk::PushConstantRange {
1680 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1681 offset: 0,
1682 size: 16,
1683 },
1684 vk::PushConstantRange {
1685 stage_flags: vk::ShaderStageFlags::COMPUTE,
1686 offset: 0,
1687 size: 32,
1688 },
1689 ];
1690 let res = merge_push_constant_ranges(&input);
1691 assert_eq!(res.len(), 3);
1692 assert_pcr_eq!(
1693 res[0],
1694 vk::PushConstantRange {
1695 stage_flags: vk::ShaderStageFlags::VERTEX
1696 | vk::ShaderStageFlags::FRAGMENT
1697 | vk::ShaderStageFlags::COMPUTE,
1698 offset: 0,
1699 size: 8,
1700 },
1701 );
1702 assert_pcr_eq!(
1703 res[1],
1704 vk::PushConstantRange {
1705 stage_flags: vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::COMPUTE,
1706 offset: 8,
1707 size: 8,
1708 },
1709 );
1710 assert_pcr_eq!(
1711 res[2],
1712 vk::PushConstantRange {
1713 stage_flags: vk::ShaderStageFlags::COMPUTE,
1714 offset: 16,
1715 size: 16,
1716 },
1717 );
1718 assert_merge_invariants(&input, &res);
1719 }
1720
1721 #[test]
1722 pub fn push_constant_ranges_nested_chain() {
1723 let input = [
1724 vk::PushConstantRange {
1725 stage_flags: vk::ShaderStageFlags::VERTEX,
1726 offset: 0,
1727 size: 64,
1728 },
1729 vk::PushConstantRange {
1730 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1731 offset: 8,
1732 size: 48,
1733 },
1734 vk::PushConstantRange {
1735 stage_flags: vk::ShaderStageFlags::COMPUTE,
1736 offset: 16,
1737 size: 32,
1738 },
1739 ];
1740 let res = merge_push_constant_ranges(&input);
1741 assert_eq!(res.len(), 5);
1742 assert_pcr_eq!(
1743 res[0],
1744 vk::PushConstantRange {
1745 stage_flags: vk::ShaderStageFlags::VERTEX,
1746 offset: 0,
1747 size: 8,
1748 },
1749 );
1750 assert_pcr_eq!(
1751 res[1],
1752 vk::PushConstantRange {
1753 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1754 offset: 8,
1755 size: 8,
1756 },
1757 );
1758 assert_pcr_eq!(
1759 res[2],
1760 vk::PushConstantRange {
1761 stage_flags: vk::ShaderStageFlags::VERTEX
1762 | vk::ShaderStageFlags::FRAGMENT
1763 | vk::ShaderStageFlags::COMPUTE,
1764 offset: 16,
1765 size: 32,
1766 },
1767 );
1768 assert_pcr_eq!(
1769 res[3],
1770 vk::PushConstantRange {
1771 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
1772 offset: 48,
1773 size: 8,
1774 },
1775 );
1776 assert_pcr_eq!(
1777 res[4],
1778 vk::PushConstantRange {
1779 stage_flags: vk::ShaderStageFlags::VERTEX,
1780 offset: 56,
1781 size: 8,
1782 },
1783 );
1784 assert_merge_invariants(&input, &res);
1785 }
1786
1787 #[test]
1788 pub fn push_constant_ranges_touching() {
1789 let input = [
1790 vk::PushConstantRange {
1791 stage_flags: vk::ShaderStageFlags::VERTEX,
1792 offset: 0,
1793 size: 16,
1794 },
1795 vk::PushConstantRange {
1796 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1797 offset: 16,
1798 size: 16,
1799 },
1800 vk::PushConstantRange {
1801 stage_flags: vk::ShaderStageFlags::COMPUTE,
1802 offset: 32,
1803 size: 16,
1804 },
1805 ];
1806 let res = merge_push_constant_ranges(&input);
1807 assert_eq!(res.len(), 3);
1808 assert_pcr_eq!(
1809 res[0],
1810 vk::PushConstantRange {
1811 stage_flags: vk::ShaderStageFlags::VERTEX,
1812 offset: 0,
1813 size: 16,
1814 },
1815 );
1816 assert_pcr_eq!(
1817 res[1],
1818 vk::PushConstantRange {
1819 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1820 offset: 16,
1821 size: 16,
1822 },
1823 );
1824 assert_pcr_eq!(
1825 res[2],
1826 vk::PushConstantRange {
1827 stage_flags: vk::ShaderStageFlags::COMPUTE,
1828 offset: 32,
1829 size: 16,
1830 },
1831 );
1832 assert_merge_invariants(&input, &res);
1833 }
1834
1835 #[test]
1836 pub fn push_constant_ranges_complex_interleave() {
1837 let input = [
1838 vk::PushConstantRange {
1839 stage_flags: vk::ShaderStageFlags::VERTEX,
1840 offset: 0,
1841 size: 24,
1842 },
1843 vk::PushConstantRange {
1844 stage_flags: vk::ShaderStageFlags::GEOMETRY,
1845 offset: 8,
1846 size: 24,
1847 },
1848 vk::PushConstantRange {
1849 stage_flags: vk::ShaderStageFlags::COMPUTE,
1850 offset: 16,
1851 size: 24,
1852 },
1853 vk::PushConstantRange {
1854 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1855 offset: 32,
1856 size: 24,
1857 },
1858 ];
1859 let res = merge_push_constant_ranges(&input);
1860 assert_eq!(res.len(), 6);
1861 assert_pcr_eq!(
1862 res[0],
1863 vk::PushConstantRange {
1864 stage_flags: vk::ShaderStageFlags::VERTEX,
1865 offset: 0,
1866 size: 8,
1867 },
1868 );
1869 assert_pcr_eq!(
1870 res[1],
1871 vk::PushConstantRange {
1872 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
1873 offset: 8,
1874 size: 8,
1875 },
1876 );
1877 assert_pcr_eq!(
1878 res[2],
1879 vk::PushConstantRange {
1880 stage_flags: vk::ShaderStageFlags::VERTEX
1881 | vk::ShaderStageFlags::GEOMETRY
1882 | vk::ShaderStageFlags::COMPUTE,
1883 offset: 16,
1884 size: 8,
1885 },
1886 );
1887 assert_pcr_eq!(
1888 res[3],
1889 vk::PushConstantRange {
1890 stage_flags: vk::ShaderStageFlags::GEOMETRY | vk::ShaderStageFlags::COMPUTE,
1891 offset: 24,
1892 size: 8,
1893 },
1894 );
1895 assert_pcr_eq!(
1896 res[4],
1897 vk::PushConstantRange {
1898 stage_flags: vk::ShaderStageFlags::COMPUTE | vk::ShaderStageFlags::FRAGMENT,
1899 offset: 32,
1900 size: 8,
1901 },
1902 );
1903 assert_pcr_eq!(
1904 res[5],
1905 vk::PushConstantRange {
1906 stage_flags: vk::ShaderStageFlags::FRAGMENT,
1907 offset: 40,
1908 size: 16,
1909 },
1910 );
1911 assert_merge_invariants(&input, &res);
1912 }
1913
1914 #[test]
1915 pub fn push_constant_ranges_fuzz() {
1916 use rand::Rng;
1917 use rand::SeedableRng;
1918 use rand::rngs::StdRng;
1919
1920 let stages = [
1921 vk::ShaderStageFlags::VERTEX,
1922 vk::ShaderStageFlags::FRAGMENT,
1923 vk::ShaderStageFlags::GEOMETRY,
1924 vk::ShaderStageFlags::TESSELLATION_CONTROL,
1925 vk::ShaderStageFlags::TESSELLATION_EVALUATION,
1926 vk::ShaderStageFlags::COMPUTE,
1927 ];
1928
1929 for seed in 0..10000 {
1930 let mut rng = StdRng::seed_from_u64(seed);
1931 let count = rng.random_range(0..=stages.len());
1932
1933 let mut available: Vec<usize> = (0..stages.len()).collect();
1934 for i in (1..available.len()).rev() {
1935 let j = rng.random_range(0..=i);
1936 available.swap(i, j);
1937 }
1938
1939 let input: Vec<vk::PushConstantRange> = available
1940 .iter()
1941 .take(count)
1942 .map(|&idx| {
1943 let offset = rng.random_range(0u32..128);
1944 let size = rng.random_range(1u32..64);
1945 vk::PushConstantRange {
1946 stage_flags: stages[idx],
1947 offset,
1948 size,
1949 }
1950 })
1951 .collect();
1952
1953 let result = merge_push_constant_ranges(&input);
1954 assert_merge_invariants(&input, &result);
1955 }
1956 }
1957}