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