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