1pub mod accel_struct;
30pub mod buffer;
31pub mod compute;
32pub mod device;
33pub mod graphic;
34pub mod image;
35pub mod physical_device;
36pub mod ray_trace;
37pub mod render_pass;
38pub mod shader;
39pub mod surface;
40pub mod swapchain;
41
42mod cmd_buf;
43mod descriptor_set;
44mod descriptor_set_layout;
45mod instance;
46
47#[allow(unused)]
49#[path = "../../contrib/vk-sync/src/lib.rs"]
50pub(crate) mod vk_sync;
51
52pub use {
53 self::{cmd_buf::CommandBuffer, instance::Instance},
54 ash::{self},
55 vk_sync::AccessType,
56};
57
58#[deprecated = "Use driver::render_pass::ResolveMode instead"]
60pub type ResolveMode = self::render_pass::ResolveMode;
61
62pub(crate) use self::{
63 cmd_buf::CommandBufferInfo,
64 descriptor_set::{DescriptorPool, DescriptorPoolInfo, DescriptorSet},
65 descriptor_set_layout::DescriptorSetLayout,
66 render_pass::{
67 AttachmentInfo, AttachmentRef, FramebufferAttachmentImageInfo, FramebufferInfo, RenderPass,
68 RenderPassInfo, SubpassDependency, SubpassInfo,
69 },
70 shader::{Descriptor, DescriptorBindingMap, DescriptorInfo},
71 surface::Surface,
72};
73
74use {
75 self::{
76 buffer::{Buffer, BufferInfo},
77 graphic::{DepthStencilMode, GraphicPipeline, VertexInputState},
78 image::SampleCount,
79 },
80 ash::vk,
81 std::{
82 cmp::Ordering,
83 error::Error,
84 fmt::{Display, Formatter},
85 },
86 vk_sync::ImageLayout,
87};
88
89pub(super) const fn format_aspect_mask(fmt: vk::Format) -> vk::ImageAspectFlags {
90 match fmt {
91 vk::Format::D16_UNORM | vk::Format::D32_SFLOAT | vk::Format::X8_D24_UNORM_PACK32 => {
92 vk::ImageAspectFlags::DEPTH
93 }
94 vk::Format::S8_UINT => vk::ImageAspectFlags::STENCIL,
95 vk::Format::D16_UNORM_S8_UINT
96 | vk::Format::D24_UNORM_S8_UINT
97 | vk::Format::D32_SFLOAT_S8_UINT => vk::ImageAspectFlags::from_raw(
98 vk::ImageAspectFlags::DEPTH.as_raw() | vk::ImageAspectFlags::STENCIL.as_raw(),
99 ),
100 _ => vk::ImageAspectFlags::COLOR,
101 }
102}
103
104pub const fn format_texel_block_size(fmt: vk::Format) -> u32 {
106 match fmt {
107 vk::Format::R4G4_UNORM_PACK8
108 | vk::Format::R8_UNORM
109 | vk::Format::R8_SNORM
110 | vk::Format::R8_USCALED
111 | vk::Format::R8_SSCALED
112 | vk::Format::R8_UINT
113 | vk::Format::R8_SINT
114 | vk::Format::R8_SRGB => 1,
115 vk::Format::A1B5G5R5_UNORM_PACK16_KHR
116 | vk::Format::R10X6_UNORM_PACK16
117 | vk::Format::R12X4_UNORM_PACK16
118 | vk::Format::A4R4G4B4_UNORM_PACK16
119 | vk::Format::A4B4G4R4_UNORM_PACK16
120 | vk::Format::R4G4B4A4_UNORM_PACK16
121 | vk::Format::B4G4R4A4_UNORM_PACK16
122 | vk::Format::R5G6B5_UNORM_PACK16
123 | vk::Format::B5G6R5_UNORM_PACK16
124 | vk::Format::R5G5B5A1_UNORM_PACK16
125 | vk::Format::B5G5R5A1_UNORM_PACK16
126 | vk::Format::A1R5G5B5_UNORM_PACK16
127 | vk::Format::R8G8_UNORM
128 | vk::Format::R8G8_SNORM
129 | vk::Format::R8G8_USCALED
130 | vk::Format::R8G8_SSCALED
131 | vk::Format::R8G8_UINT
132 | vk::Format::R8G8_SINT
133 | vk::Format::R8G8_SRGB
134 | vk::Format::R16_UNORM
135 | vk::Format::R16_SNORM
136 | vk::Format::R16_USCALED
137 | vk::Format::R16_SSCALED
138 | vk::Format::R16_UINT
139 | vk::Format::R16_SINT
140 | vk::Format::R16_SFLOAT => 2,
141 vk::Format::A8_UNORM_KHR => 1,
142 vk::Format::R8G8B8_UNORM
143 | vk::Format::R8G8B8_SNORM
144 | vk::Format::R8G8B8_USCALED
145 | vk::Format::R8G8B8_SSCALED
146 | vk::Format::R8G8B8_UINT
147 | vk::Format::R8G8B8_SINT
148 | vk::Format::R8G8B8_SRGB
149 | vk::Format::B8G8R8_UNORM
150 | vk::Format::B8G8R8_SNORM
151 | vk::Format::B8G8R8_USCALED
152 | vk::Format::B8G8R8_SSCALED
153 | vk::Format::B8G8R8_UINT
154 | vk::Format::B8G8R8_SINT
155 | vk::Format::B8G8R8_SRGB => 3,
156 vk::Format::R10X6G10X6_UNORM_2PACK16
157 | vk::Format::R12X4G12X4_UNORM_2PACK16
158 | vk::Format::R16G16_S10_5_NV
159 | vk::Format::R8G8B8A8_UNORM
160 | vk::Format::R8G8B8A8_SNORM
161 | vk::Format::R8G8B8A8_USCALED
162 | vk::Format::R8G8B8A8_SSCALED
163 | vk::Format::R8G8B8A8_UINT
164 | vk::Format::R8G8B8A8_SINT
165 | vk::Format::R8G8B8A8_SRGB
166 | vk::Format::B8G8R8A8_UNORM
167 | vk::Format::B8G8R8A8_SNORM
168 | vk::Format::B8G8R8A8_USCALED
169 | vk::Format::B8G8R8A8_SSCALED
170 | vk::Format::B8G8R8A8_UINT
171 | vk::Format::B8G8R8A8_SINT
172 | vk::Format::B8G8R8A8_SRGB
173 | vk::Format::A8B8G8R8_UNORM_PACK32
174 | vk::Format::A8B8G8R8_SNORM_PACK32
175 | vk::Format::A8B8G8R8_USCALED_PACK32
176 | vk::Format::A8B8G8R8_SSCALED_PACK32
177 | vk::Format::A8B8G8R8_UINT_PACK32
178 | vk::Format::A8B8G8R8_SINT_PACK32
179 | vk::Format::A8B8G8R8_SRGB_PACK32
180 | vk::Format::A2R10G10B10_UNORM_PACK32
181 | vk::Format::A2R10G10B10_SNORM_PACK32
182 | vk::Format::A2R10G10B10_USCALED_PACK32
183 | vk::Format::A2R10G10B10_SSCALED_PACK32
184 | vk::Format::A2R10G10B10_UINT_PACK32
185 | vk::Format::A2R10G10B10_SINT_PACK32
186 | vk::Format::A2B10G10R10_UNORM_PACK32
187 | vk::Format::A2B10G10R10_SNORM_PACK32
188 | vk::Format::A2B10G10R10_USCALED_PACK32
189 | vk::Format::A2B10G10R10_SSCALED_PACK32
190 | vk::Format::A2B10G10R10_UINT_PACK32
191 | vk::Format::A2B10G10R10_SINT_PACK32
192 | vk::Format::R16G16_UNORM
193 | vk::Format::R16G16_SNORM
194 | vk::Format::R16G16_USCALED
195 | vk::Format::R16G16_SSCALED
196 | vk::Format::R16G16_UINT
197 | vk::Format::R16G16_SINT
198 | vk::Format::R16G16_SFLOAT
199 | vk::Format::R32_UINT
200 | vk::Format::R32_SINT
201 | vk::Format::R32_SFLOAT
202 | vk::Format::B10G11R11_UFLOAT_PACK32
203 | vk::Format::E5B9G9R9_UFLOAT_PACK32 => 4,
204 vk::Format::R16G16B16_UNORM
205 | vk::Format::R16G16B16_SNORM
206 | vk::Format::R16G16B16_USCALED
207 | vk::Format::R16G16B16_SSCALED
208 | vk::Format::R16G16B16_UINT
209 | vk::Format::R16G16B16_SINT
210 | vk::Format::R16G16B16_SFLOAT => 6,
211 vk::Format::R16G16B16A16_UNORM
212 | vk::Format::R16G16B16A16_SNORM
213 | vk::Format::R16G16B16A16_USCALED
214 | vk::Format::R16G16B16A16_SSCALED
215 | vk::Format::R16G16B16A16_UINT
216 | vk::Format::R16G16B16A16_SINT
217 | vk::Format::R16G16B16A16_SFLOAT
218 | vk::Format::R32G32_UINT
219 | vk::Format::R32G32_SINT
220 | vk::Format::R32G32_SFLOAT
221 | vk::Format::R64_UINT
222 | vk::Format::R64_SINT
223 | vk::Format::R64_SFLOAT => 8,
224 vk::Format::R32G32B32_UINT | vk::Format::R32G32B32_SINT | vk::Format::R32G32B32_SFLOAT => {
225 12
226 }
227 vk::Format::R32G32B32A32_UINT
228 | vk::Format::R32G32B32A32_SINT
229 | vk::Format::R32G32B32A32_SFLOAT
230 | vk::Format::R64G64_UINT
231 | vk::Format::R64G64_SINT
232 | vk::Format::R64G64_SFLOAT => 16,
233 vk::Format::R64G64B64_UINT | vk::Format::R64G64B64_SINT | vk::Format::R64G64B64_SFLOAT => {
234 24
235 }
236 vk::Format::R64G64B64A64_UINT
237 | vk::Format::R64G64B64A64_SINT
238 | vk::Format::R64G64B64A64_SFLOAT => 32,
239 vk::Format::D16_UNORM => 2,
240 vk::Format::X8_D24_UNORM_PACK32 => 4,
241 vk::Format::D32_SFLOAT => 4,
242 vk::Format::S8_UINT => 1,
243 vk::Format::D16_UNORM_S8_UINT => 3,
244 vk::Format::D24_UNORM_S8_UINT => 4,
245 vk::Format::D32_SFLOAT_S8_UINT => 5,
246 _ => {
247 unimplemented!()
249 }
250 }
251}
252
253pub(super) const fn image_subresource_range_from_layers(
254 vk::ImageSubresourceLayers {
255 aspect_mask,
256 mip_level,
257 base_array_layer,
258 layer_count,
259 }: vk::ImageSubresourceLayers,
260) -> vk::ImageSubresourceRange {
261 vk::ImageSubresourceRange {
262 aspect_mask,
263 base_mip_level: mip_level,
264 level_count: 1,
265 base_array_layer,
266 layer_count,
267 }
268}
269
270pub(super) const fn image_access_layout(access: AccessType) -> ImageLayout {
271 if matches!(access, AccessType::Present | AccessType::ComputeShaderWrite) {
272 ImageLayout::General
273 } else {
274 ImageLayout::Optimal
275 }
276}
277
278pub(super) const fn initial_image_layout_access(ty: AccessType) -> AccessType {
279 use AccessType::*;
280 match ty {
281 DepthStencilAttachmentReadWrite => DepthStencilAttachmentRead,
282 _ => ty,
283 }
284}
285
286pub(super) const fn is_read_access(ty: AccessType) -> bool {
287 !is_write_access(ty)
288}
289
290pub(super) const fn is_write_access(ty: AccessType) -> bool {
291 use AccessType::*;
292 match ty {
293 Nothing
294 | CommandBufferReadNVX
295 | IndirectBuffer
296 | IndexBuffer
297 | VertexBuffer
298 | VertexShaderReadUniformBuffer
299 | VertexShaderReadSampledImageOrUniformTexelBuffer
300 | VertexShaderReadOther
301 | TessellationControlShaderReadUniformBuffer
302 | TessellationControlShaderReadSampledImageOrUniformTexelBuffer
303 | TessellationControlShaderReadOther
304 | TessellationEvaluationShaderReadUniformBuffer
305 | TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer
306 | TessellationEvaluationShaderReadOther
307 | GeometryShaderReadUniformBuffer
308 | GeometryShaderReadSampledImageOrUniformTexelBuffer
309 | GeometryShaderReadOther
310 | FragmentShaderReadUniformBuffer
311 | FragmentShaderReadSampledImageOrUniformTexelBuffer
312 | FragmentShaderReadColorInputAttachment
313 | FragmentShaderReadDepthStencilInputAttachment
314 | FragmentShaderReadOther
315 | ColorAttachmentRead
316 | DepthStencilAttachmentRead
317 | ComputeShaderReadUniformBuffer
318 | ComputeShaderReadSampledImageOrUniformTexelBuffer
319 | ComputeShaderReadOther
320 | AnyShaderReadUniformBuffer
321 | AnyShaderReadUniformBufferOrVertexBuffer
322 | AnyShaderReadSampledImageOrUniformTexelBuffer
323 | AnyShaderReadOther
324 | TransferRead
325 | HostRead
326 | Present
327 | RayTracingShaderReadSampledImageOrUniformTexelBuffer
328 | RayTracingShaderReadColorInputAttachment
329 | RayTracingShaderReadDepthStencilInputAttachment
330 | RayTracingShaderReadAccelerationStructure
331 | RayTracingShaderReadOther
332 | AccelerationStructureBuildRead => false,
333 CommandBufferWriteNVX
334 | VertexShaderWrite
335 | TessellationControlShaderWrite
336 | TessellationEvaluationShaderWrite
337 | GeometryShaderWrite
338 | FragmentShaderWrite
339 | ColorAttachmentWrite
340 | DepthStencilAttachmentWrite
341 | DepthStencilAttachmentReadWrite
342 | DepthAttachmentWriteStencilReadOnly
343 | StencilAttachmentWriteDepthReadOnly
344 | ComputeShaderWrite
345 | AnyShaderWrite
346 | TransferWrite
347 | HostWrite
348 | ColorAttachmentReadWrite
349 | General
350 | AccelerationStructureBuildWrite
351 | AccelerationStructureBufferWrite
352 | ComputeShaderReadWrite => true,
353 }
354}
355
356#[profiling::function]
367fn merge_push_constant_ranges(pcr: &[vk::PushConstantRange]) -> Vec<vk::PushConstantRange> {
368 #[cfg(debug_assertions)]
370 {
371 let mut stage_flags = vk::ShaderStageFlags::empty();
372 for item in pcr.iter() {
373 assert_eq!(item.stage_flags.as_raw().count_ones(), 1);
374 assert!(!stage_flags.contains(item.stage_flags));
375 assert!(item.size > 0);
376
377 stage_flags |= item.stage_flags;
378 }
379 }
380
381 match pcr.len() {
382 0 => vec![],
383 1 => vec![pcr[0]],
384 _ => {
385 let mut res = pcr.to_vec();
386 let sort_fn = |lhs: &vk::PushConstantRange, rhs: &vk::PushConstantRange| match lhs
387 .offset
388 .cmp(&rhs.offset)
389 {
390 Ordering::Equal => lhs.size.cmp(&rhs.size),
391 res => res,
392 };
393
394 res.sort_unstable_by(sort_fn);
395
396 let mut i = 0;
397 let mut j = 1;
398
399 while j < res.len() {
400 let lhs = res[i];
401 let rhs = res[j];
402
403 if lhs.offset == rhs.offset && lhs.size == rhs.size {
404 res[i].stage_flags |= rhs.stage_flags;
405 let _ = res.remove(j);
406 } else if lhs.offset == rhs.offset {
407 res[i].stage_flags |= rhs.stage_flags;
408 res[j].offset += lhs.size;
409 res[j].size -= lhs.size;
410 res[j..].sort_unstable_by(sort_fn);
411 } else if lhs.offset + lhs.size > rhs.offset + rhs.size {
412 res[i].size = rhs.offset - lhs.offset;
413 res[j].stage_flags = lhs.stage_flags;
414 res[j].offset += rhs.size;
415 res[j].size = (lhs.offset + lhs.size) - (rhs.offset + rhs.size);
416 res.insert(
417 j,
418 vk::PushConstantRange {
419 stage_flags: lhs.stage_flags | rhs.stage_flags,
420 offset: rhs.offset,
421 size: rhs.size,
422 },
423 );
424 i += 1;
425 j += 1;
426 } else if lhs.offset + lhs.size == rhs.offset + rhs.size {
427 res[i].size -= rhs.size;
428 res[j].stage_flags |= lhs.stage_flags;
429 i += 1;
430 j += 1;
431 } else if lhs.offset + lhs.size > rhs.offset
432 && lhs.offset + lhs.size < rhs.offset + rhs.size
433 {
434 res[i].size = rhs.offset - lhs.offset;
435 res[j].offset = lhs.offset + lhs.size;
436 res[j].size = (rhs.offset + rhs.size) - (lhs.offset + lhs.size);
437 res.insert(
438 j,
439 vk::PushConstantRange {
440 stage_flags: lhs.stage_flags | rhs.stage_flags,
441 offset: rhs.offset,
442 size: (lhs.offset + lhs.size) - rhs.offset,
443 },
444 );
445 res[j..].sort_unstable_by(sort_fn);
446 } else {
447 i += 1;
448 j += 1;
449 }
450 }
451
452 res
453 }
454 }
455}
456
457pub(super) const fn pipeline_stage_access_flags(
458 access_type: AccessType,
459) -> (vk::PipelineStageFlags, vk::AccessFlags) {
460 use {
461 AccessType as ty,
462 vk::{AccessFlags as access, PipelineStageFlags as stage},
463 };
464
465 match access_type {
466 ty::Nothing => (stage::empty(), access::empty()),
467 ty::CommandBufferReadNVX => (
468 stage::COMMAND_PREPROCESS_NV,
469 access::COMMAND_PREPROCESS_READ_NV,
470 ),
471 ty::IndirectBuffer => (stage::DRAW_INDIRECT, access::INDIRECT_COMMAND_READ),
472 ty::IndexBuffer => (stage::VERTEX_INPUT, access::INDEX_READ),
473 ty::VertexBuffer => (stage::VERTEX_INPUT, access::VERTEX_ATTRIBUTE_READ),
474 ty::VertexShaderReadUniformBuffer => (stage::VERTEX_SHADER, access::SHADER_READ),
475 ty::VertexShaderReadSampledImageOrUniformTexelBuffer => {
476 (stage::VERTEX_SHADER, access::SHADER_READ)
477 }
478 ty::VertexShaderReadOther => (stage::VERTEX_SHADER, access::SHADER_READ),
479 ty::TessellationControlShaderReadUniformBuffer => {
480 (stage::TESSELLATION_CONTROL_SHADER, access::UNIFORM_READ)
481 }
482 ty::TessellationControlShaderReadSampledImageOrUniformTexelBuffer => {
483 (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_READ)
484 }
485 ty::TessellationControlShaderReadOther => {
486 (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_READ)
487 }
488 ty::TessellationEvaluationShaderReadUniformBuffer => {
489 (stage::TESSELLATION_EVALUATION_SHADER, access::UNIFORM_READ)
490 }
491 ty::TessellationEvaluationShaderReadSampledImageOrUniformTexelBuffer => {
492 (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_READ)
493 }
494 ty::TessellationEvaluationShaderReadOther => {
495 (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_READ)
496 }
497 ty::GeometryShaderReadUniformBuffer => (stage::GEOMETRY_SHADER, access::UNIFORM_READ),
498 ty::GeometryShaderReadSampledImageOrUniformTexelBuffer => {
499 (stage::GEOMETRY_SHADER, access::SHADER_READ)
500 }
501 ty::GeometryShaderReadOther => (stage::GEOMETRY_SHADER, access::SHADER_READ),
502 ty::FragmentShaderReadUniformBuffer => (stage::FRAGMENT_SHADER, access::UNIFORM_READ),
503 ty::FragmentShaderReadSampledImageOrUniformTexelBuffer => {
504 (stage::FRAGMENT_SHADER, access::SHADER_READ)
505 }
506 ty::FragmentShaderReadColorInputAttachment => {
507 (stage::FRAGMENT_SHADER, access::INPUT_ATTACHMENT_READ)
508 }
509 ty::FragmentShaderReadDepthStencilInputAttachment => {
510 (stage::FRAGMENT_SHADER, access::INPUT_ATTACHMENT_READ)
511 }
512 ty::FragmentShaderReadOther => (stage::FRAGMENT_SHADER, access::SHADER_READ),
513 ty::ColorAttachmentRead => (
514 stage::COLOR_ATTACHMENT_OUTPUT,
515 access::COLOR_ATTACHMENT_READ,
516 ),
517 ty::DepthStencilAttachmentRead => (
518 stage::from_raw(
519 stage::EARLY_FRAGMENT_TESTS.as_raw()
520 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
521 ),
522 access::DEPTH_STENCIL_ATTACHMENT_READ,
523 ),
524 ty::ComputeShaderReadUniformBuffer => (stage::COMPUTE_SHADER, access::UNIFORM_READ),
525 ty::ComputeShaderReadSampledImageOrUniformTexelBuffer => {
526 (stage::COMPUTE_SHADER, access::SHADER_READ)
527 }
528 ty::ComputeShaderReadOther => (stage::COMPUTE_SHADER, access::SHADER_READ),
529 ty::AnyShaderReadUniformBuffer => (stage::ALL_COMMANDS, access::UNIFORM_READ),
530 ty::AnyShaderReadUniformBufferOrVertexBuffer => (
531 stage::ALL_COMMANDS,
532 access::from_raw(
533 access::UNIFORM_READ.as_raw() | vk::AccessFlags::VERTEX_ATTRIBUTE_READ.as_raw(),
534 ),
535 ),
536 ty::AnyShaderReadSampledImageOrUniformTexelBuffer => {
537 (stage::ALL_COMMANDS, access::SHADER_READ)
538 }
539 ty::AnyShaderReadOther => (stage::ALL_COMMANDS, access::SHADER_READ),
540 ty::TransferRead => (stage::TRANSFER, access::TRANSFER_READ),
541 ty::HostRead => (stage::HOST, access::HOST_READ),
542 ty::Present => (stage::empty(), access::empty()),
543 ty::CommandBufferWriteNVX => (
544 stage::COMMAND_PREPROCESS_NV,
545 access::COMMAND_PREPROCESS_WRITE_NV,
546 ),
547 ty::VertexShaderWrite => (stage::VERTEX_SHADER, access::SHADER_WRITE),
548 ty::TessellationControlShaderWrite => {
549 (stage::TESSELLATION_CONTROL_SHADER, access::SHADER_WRITE)
550 }
551 ty::TessellationEvaluationShaderWrite => {
552 (stage::TESSELLATION_EVALUATION_SHADER, access::SHADER_WRITE)
553 }
554 ty::GeometryShaderWrite => (stage::GEOMETRY_SHADER, access::SHADER_WRITE),
555 ty::FragmentShaderWrite => (stage::FRAGMENT_SHADER, access::SHADER_WRITE),
556 ty::ColorAttachmentWrite => (
557 stage::COLOR_ATTACHMENT_OUTPUT,
558 access::COLOR_ATTACHMENT_WRITE,
559 ),
560 ty::DepthStencilAttachmentWrite => (
561 stage::from_raw(
562 stage::EARLY_FRAGMENT_TESTS.as_raw()
563 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
564 ),
565 access::DEPTH_STENCIL_ATTACHMENT_WRITE,
566 ),
567 ty::DepthStencilAttachmentReadWrite => (
568 stage::from_raw(
569 stage::EARLY_FRAGMENT_TESTS.as_raw()
570 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
571 ),
572 access::from_raw(
573 access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
574 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
575 ),
576 ),
577 ty::DepthAttachmentWriteStencilReadOnly => (
578 stage::from_raw(
579 stage::EARLY_FRAGMENT_TESTS.as_raw()
580 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
581 ),
582 access::from_raw(
583 access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
584 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
585 ),
586 ),
587 ty::StencilAttachmentWriteDepthReadOnly => (
588 stage::from_raw(
589 stage::EARLY_FRAGMENT_TESTS.as_raw()
590 | vk::PipelineStageFlags::LATE_FRAGMENT_TESTS.as_raw(),
591 ),
592 access::from_raw(
593 access::DEPTH_STENCIL_ATTACHMENT_WRITE.as_raw()
594 | vk::AccessFlags::DEPTH_STENCIL_ATTACHMENT_READ.as_raw(),
595 ),
596 ),
597 ty::ComputeShaderWrite => (stage::COMPUTE_SHADER, access::SHADER_WRITE),
598 ty::ComputeShaderReadWrite => (
599 stage::COMPUTE_SHADER,
600 access::from_raw(access::SHADER_WRITE.as_raw() | access::SHADER_READ.as_raw()),
601 ),
602 ty::AnyShaderWrite => (stage::ALL_COMMANDS, access::SHADER_WRITE),
603 ty::TransferWrite => (stage::TRANSFER, access::TRANSFER_WRITE),
604 ty::HostWrite => (stage::HOST, access::HOST_WRITE),
605 ty::ColorAttachmentReadWrite => (
606 stage::COLOR_ATTACHMENT_OUTPUT,
607 access::from_raw(
608 access::COLOR_ATTACHMENT_READ.as_raw()
609 | vk::AccessFlags::COLOR_ATTACHMENT_WRITE.as_raw(),
610 ),
611 ),
612 ty::General => (
613 stage::ALL_COMMANDS,
614 access::from_raw(access::MEMORY_READ.as_raw() | vk::AccessFlags::MEMORY_WRITE.as_raw()),
615 ),
616 ty::RayTracingShaderReadSampledImageOrUniformTexelBuffer => {
617 (stage::RAY_TRACING_SHADER_KHR, access::SHADER_READ)
618 }
619 ty::RayTracingShaderReadColorInputAttachment => {
620 (stage::RAY_TRACING_SHADER_KHR, access::INPUT_ATTACHMENT_READ)
621 }
622 ty::RayTracingShaderReadDepthStencilInputAttachment => {
623 (stage::RAY_TRACING_SHADER_KHR, access::INPUT_ATTACHMENT_READ)
624 }
625 ty::RayTracingShaderReadAccelerationStructure => (
626 stage::RAY_TRACING_SHADER_KHR,
627 access::ACCELERATION_STRUCTURE_READ_KHR,
628 ),
629 ty::RayTracingShaderReadOther => (stage::RAY_TRACING_SHADER_KHR, access::SHADER_READ),
630 ty::AccelerationStructureBuildWrite => (
631 stage::ACCELERATION_STRUCTURE_BUILD_KHR,
632 access::ACCELERATION_STRUCTURE_WRITE_KHR,
633 ),
634 ty::AccelerationStructureBuildRead => (
635 stage::ACCELERATION_STRUCTURE_BUILD_KHR,
636 access::ACCELERATION_STRUCTURE_READ_KHR,
637 ),
638 ty::AccelerationStructureBufferWrite => (
639 stage::ACCELERATION_STRUCTURE_BUILD_KHR,
640 access::TRANSFER_WRITE,
641 ),
642 }
643}
644
645#[derive(Debug)]
655pub enum DriverError {
656 InvalidData,
658
659 Unsupported,
661
662 OutOfMemory,
666}
667
668impl Display for DriverError {
669 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
670 write!(f, "{:?}", self)
671 }
672}
673
674impl Error for DriverError {}
675
676#[cfg(test)]
677mod tests {
678 use {super::merge_push_constant_ranges, ash::vk};
679
680 macro_rules! assert_pcr_eq {
681 ($lhs: expr, $rhs: expr,) => {
682 assert_eq!($lhs.stage_flags, $rhs.stage_flags, "Stages flags not equal");
683 assert_eq!($lhs.offset, $rhs.offset, "Offset not equal");
684 assert_eq!($lhs.size, $rhs.size, "Size not equal");
685 };
686 }
687
688 #[test]
689 pub fn push_constant_ranges_complex() {
690 let res = merge_push_constant_ranges(&[
691 vk::PushConstantRange {
692 stage_flags: vk::ShaderStageFlags::VERTEX,
693 offset: 8,
694 size: 16,
695 },
696 vk::PushConstantRange {
697 stage_flags: vk::ShaderStageFlags::GEOMETRY,
698 offset: 20,
699 size: 48,
700 },
701 vk::PushConstantRange {
702 stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL,
703 offset: 24,
704 size: 8,
705 },
706 vk::PushConstantRange {
707 stage_flags: vk::ShaderStageFlags::TESSELLATION_EVALUATION,
708 offset: 28,
709 size: 32,
710 },
711 vk::PushConstantRange {
712 stage_flags: vk::ShaderStageFlags::FRAGMENT,
713 offset: 40,
714 size: 128,
715 },
716 ]);
717
718 assert_eq!(res.len(), 8);
719 assert_pcr_eq!(
720 res[0],
721 vk::PushConstantRange {
722 stage_flags: vk::ShaderStageFlags::VERTEX,
723 offset: 8,
724 size: 12,
725 },
726 );
727 assert_pcr_eq!(
728 res[1],
729 vk::PushConstantRange {
730 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
731 offset: 20,
732 size: 4,
733 },
734 );
735 assert_pcr_eq!(
736 res[2],
737 vk::PushConstantRange {
738 stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL
739 | vk::ShaderStageFlags::GEOMETRY,
740 offset: 24,
741 size: 4,
742 },
743 );
744 assert_pcr_eq!(
745 res[3],
746 vk::PushConstantRange {
747 stage_flags: vk::ShaderStageFlags::TESSELLATION_CONTROL
748 | vk::ShaderStageFlags::TESSELLATION_EVALUATION
749 | vk::ShaderStageFlags::GEOMETRY,
750 offset: 28,
751 size: 4,
752 },
753 );
754 assert_pcr_eq!(
755 res[4],
756 vk::PushConstantRange {
757 stage_flags: vk::ShaderStageFlags::GEOMETRY
758 | vk::ShaderStageFlags::TESSELLATION_EVALUATION,
759 offset: 32,
760 size: 8,
761 },
762 );
763 assert_pcr_eq!(
764 res[5],
765 vk::PushConstantRange {
766 stage_flags: vk::ShaderStageFlags::GEOMETRY
767 | vk::ShaderStageFlags::TESSELLATION_EVALUATION
768 | vk::ShaderStageFlags::FRAGMENT,
769 offset: 40,
770 size: 20,
771 },
772 );
773 assert_pcr_eq!(
774 res[6],
775 vk::PushConstantRange {
776 stage_flags: vk::ShaderStageFlags::FRAGMENT | vk::ShaderStageFlags::GEOMETRY,
777 offset: 60,
778 size: 8,
779 },
780 );
781 assert_pcr_eq!(
782 res[7],
783 vk::PushConstantRange {
784 stage_flags: vk::ShaderStageFlags::FRAGMENT,
785 offset: 68,
786 size: 100,
787 },
788 );
789 }
790
791 #[test]
792 pub fn push_constant_ranges_disjoint() {
793 let res = merge_push_constant_ranges(&[
794 vk::PushConstantRange {
795 stage_flags: vk::ShaderStageFlags::VERTEX,
796 offset: 0,
797 size: 32,
798 },
799 vk::PushConstantRange {
800 stage_flags: vk::ShaderStageFlags::FRAGMENT,
801 offset: 32,
802 size: 64,
803 },
804 ]);
805
806 assert_eq!(res.len(), 2);
807 assert_pcr_eq!(
808 res[0],
809 vk::PushConstantRange {
810 stage_flags: vk::ShaderStageFlags::VERTEX,
811 offset: 0,
812 size: 32,
813 },
814 );
815 assert_pcr_eq!(
816 res[1],
817 vk::PushConstantRange {
818 stage_flags: vk::ShaderStageFlags::FRAGMENT,
819 offset: 32,
820 size: 64,
821 },
822 );
823 }
824
825 #[test]
826 pub fn push_constant_ranges_equal() {
827 let res = merge_push_constant_ranges(&[
828 vk::PushConstantRange {
829 stage_flags: vk::ShaderStageFlags::VERTEX,
830 offset: 0,
831 size: 32,
832 },
833 vk::PushConstantRange {
834 stage_flags: vk::ShaderStageFlags::FRAGMENT,
835 offset: 0,
836 size: 32,
837 },
838 ]);
839
840 assert_eq!(res.len(), 1);
841 assert_pcr_eq!(
842 res[0],
843 vk::PushConstantRange {
844 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
845 offset: 0,
846 size: 32,
847 },
848 );
849 }
850
851 #[test]
852 pub fn push_constant_ranges_overlap() {
853 let res = merge_push_constant_ranges(&[
854 vk::PushConstantRange {
855 stage_flags: vk::ShaderStageFlags::VERTEX,
856 offset: 0,
857 size: 24,
858 },
859 vk::PushConstantRange {
860 stage_flags: vk::ShaderStageFlags::GEOMETRY,
861 offset: 8,
862 size: 24,
863 },
864 vk::PushConstantRange {
865 stage_flags: vk::ShaderStageFlags::FRAGMENT,
866 offset: 20,
867 size: 28,
868 },
869 ]);
870
871 assert_eq!(res.len(), 5);
872 assert_pcr_eq!(
873 res[0],
874 vk::PushConstantRange {
875 stage_flags: vk::ShaderStageFlags::VERTEX,
876 offset: 0,
877 size: 8,
878 },
879 );
880 assert_pcr_eq!(
881 res[1],
882 vk::PushConstantRange {
883 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::GEOMETRY,
884 offset: 8,
885 size: 12,
886 },
887 );
888 assert_pcr_eq!(
889 res[2],
890 vk::PushConstantRange {
891 stage_flags: vk::ShaderStageFlags::VERTEX
892 | vk::ShaderStageFlags::GEOMETRY
893 | vk::ShaderStageFlags::FRAGMENT,
894 offset: 20,
895 size: 4,
896 },
897 );
898 assert_pcr_eq!(
899 res[3],
900 vk::PushConstantRange {
901 stage_flags: vk::ShaderStageFlags::GEOMETRY | vk::ShaderStageFlags::FRAGMENT,
902 offset: 24,
903 size: 8,
904 },
905 );
906 assert_pcr_eq!(
907 res[4],
908 vk::PushConstantRange {
909 stage_flags: vk::ShaderStageFlags::FRAGMENT,
910 offset: 32,
911 size: 16,
912 },
913 );
914 }
915
916 #[test]
917 pub fn push_constant_ranges_subset() {
918 let res = merge_push_constant_ranges(&[
919 vk::PushConstantRange {
920 stage_flags: vk::ShaderStageFlags::VERTEX,
921 offset: 0,
922 size: 64,
923 },
924 vk::PushConstantRange {
925 stage_flags: vk::ShaderStageFlags::FRAGMENT,
926 offset: 16,
927 size: 8,
928 },
929 ]);
930
931 assert_eq!(res.len(), 3);
932 assert_pcr_eq!(
933 res[0],
934 vk::PushConstantRange {
935 stage_flags: vk::ShaderStageFlags::VERTEX,
936 offset: 0,
937 size: 16,
938 },
939 );
940 assert_pcr_eq!(
941 res[1],
942 vk::PushConstantRange {
943 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
944 offset: 16,
945 size: 8,
946 },
947 );
948 assert_pcr_eq!(
949 res[2],
950 vk::PushConstantRange {
951 stage_flags: vk::ShaderStageFlags::VERTEX,
952 offset: 24,
953 size: 40,
954 },
955 );
956 }
957
958 #[test]
959 pub fn push_constant_ranges_superset() {
960 let res = merge_push_constant_ranges(&[
961 vk::PushConstantRange {
962 stage_flags: vk::ShaderStageFlags::VERTEX,
963 offset: 0,
964 size: 64,
965 },
966 vk::PushConstantRange {
967 stage_flags: vk::ShaderStageFlags::FRAGMENT,
968 offset: 0,
969 size: 80,
970 },
971 ]);
972
973 assert_eq!(res.len(), 2);
974 assert_pcr_eq!(
975 res[0],
976 vk::PushConstantRange {
977 stage_flags: vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
978 offset: 0,
979 size: 64,
980 },
981 );
982 assert_pcr_eq!(
983 res[1],
984 vk::PushConstantRange {
985 stage_flags: vk::ShaderStageFlags::FRAGMENT,
986 offset: 64,
987 size: 16,
988 },
989 );
990 }
991}