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