1use crate::{
2 command_buffer::{RecordingCommandBuffer, Result},
3 resource::{AccessTypes, ImageLayoutType},
4 Id,
5};
6use ash::vk;
7use smallvec::SmallVec;
8use std::cmp;
9use vulkano::{
10 buffer::Buffer,
11 device::DeviceOwned,
12 image::{sampler::Filter, Image, ImageAspects, ImageSubresourceLayers},
13 DeviceSize, Version, VulkanObject,
14};
15
16impl RecordingCommandBuffer<'_> {
18 pub unsafe fn copy_buffer(
20 &mut self,
21 copy_buffer_info: &CopyBufferInfo<'_>,
22 ) -> Result<&mut Self> {
23 Ok(unsafe { self.copy_buffer_unchecked(copy_buffer_info) })
24 }
25
26 pub unsafe fn copy_buffer_unchecked(
27 &mut self,
28 copy_buffer_info: &CopyBufferInfo<'_>,
29 ) -> &mut Self {
30 let &CopyBufferInfo {
31 src_buffer,
32 dst_buffer,
33 regions,
34 _ne: _,
35 } = copy_buffer_info;
36
37 let src_buffer = unsafe { self.accesses.buffer_unchecked(src_buffer) };
38 let dst_buffer = unsafe { self.accesses.buffer_unchecked(dst_buffer) };
39
40 let fns = self.device().fns();
41
42 if self.device().api_version() >= Version::V1_3
43 || self.device().enabled_extensions().khr_copy_commands2
44 {
45 let cmd_copy_buffer2 = if self.device().api_version() >= Version::V1_3 {
46 fns.v1_3.cmd_copy_buffer2
47 } else {
48 fns.khr_copy_commands2.cmd_copy_buffer2_khr
49 };
50
51 if regions.is_empty() {
52 let regions_vk = [vk::BufferCopy2::default()
53 .src_offset(0)
54 .dst_offset(0)
55 .size(cmp::min(src_buffer.size(), dst_buffer.size()))];
56
57 let copy_buffer_info_vk = vk::CopyBufferInfo2::default()
58 .src_buffer(src_buffer.handle())
59 .dst_buffer(dst_buffer.handle())
60 .regions(®ions_vk);
61
62 unsafe { cmd_copy_buffer2(self.handle(), ©_buffer_info_vk) };
63 } else {
64 let regions_vk = regions
65 .iter()
66 .map(|region| {
67 let &BufferCopy {
68 src_offset,
69 dst_offset,
70 size,
71 _ne,
72 } = region;
73
74 vk::BufferCopy2::default()
75 .src_offset(src_offset)
76 .dst_offset(dst_offset)
77 .size(size)
78 })
79 .collect::<SmallVec<[_; 8]>>();
80
81 let copy_buffer_info_vk = vk::CopyBufferInfo2::default()
82 .src_buffer(src_buffer.handle())
83 .dst_buffer(dst_buffer.handle())
84 .regions(®ions_vk);
85
86 unsafe { cmd_copy_buffer2(self.handle(), ©_buffer_info_vk) };
87 }
88 } else {
89 let cmd_copy_buffer = fns.v1_0.cmd_copy_buffer;
90
91 if regions.is_empty() {
92 let region_vk = vk::BufferCopy {
93 src_offset: 0,
94 dst_offset: 0,
95 size: cmp::min(src_buffer.size(), dst_buffer.size()),
96 };
97
98 unsafe {
99 cmd_copy_buffer(
100 self.handle(),
101 src_buffer.handle(),
102 dst_buffer.handle(),
103 1,
104 ®ion_vk,
105 )
106 };
107 } else {
108 let regions_vk = regions
109 .iter()
110 .map(|copy| {
111 let &BufferCopy {
112 src_offset,
113 dst_offset,
114 size,
115 _ne: _,
116 } = copy;
117
118 vk::BufferCopy {
119 src_offset,
120 dst_offset,
121 size,
122 }
123 })
124 .collect::<SmallVec<[_; 8]>>();
125
126 unsafe {
127 cmd_copy_buffer(
128 self.handle(),
129 src_buffer.handle(),
130 dst_buffer.handle(),
131 regions_vk.len() as u32,
132 regions_vk.as_ptr(),
133 )
134 };
135 }
136 }
137
138 self
139 }
140
141 pub unsafe fn copy_image(&mut self, copy_image_info: &CopyImageInfo<'_>) -> Result<&mut Self> {
157 Ok(unsafe { self.copy_image_unchecked(copy_image_info) })
158 }
159
160 pub unsafe fn copy_image_unchecked(
161 &mut self,
162 copy_image_info: &CopyImageInfo<'_>,
163 ) -> &mut Self {
164 let &CopyImageInfo {
165 src_image,
166 src_image_layout,
167 dst_image,
168 dst_image_layout,
169 regions,
170 _ne: _,
171 } = copy_image_info;
172
173 let src_image = unsafe { self.accesses.image_unchecked(src_image) };
174 let src_image_layout = AccessTypes::COPY_TRANSFER_READ.image_layout(src_image_layout);
175 let dst_image = unsafe { self.accesses.image_unchecked(dst_image) };
176 let dst_image_layout = AccessTypes::COPY_TRANSFER_WRITE.image_layout(dst_image_layout);
177
178 let fns = self.device().fns();
179
180 if self.device().api_version() >= Version::V1_3
181 || self.device().enabled_extensions().khr_copy_commands2
182 {
183 let cmd_copy_image2 = if self.device().api_version() >= Version::V1_3 {
184 fns.v1_3.cmd_copy_image2
185 } else {
186 fns.khr_copy_commands2.cmd_copy_image2_khr
187 };
188
189 if regions.is_empty() {
190 let min_array_layers = cmp::min(src_image.array_layers(), dst_image.array_layers());
191 let src_extent = src_image.extent();
192 let dst_extent = dst_image.extent();
193 let regions_vk = [vk::ImageCopy2::default()
194 .src_subresource(
195 ImageSubresourceLayers {
196 array_layers: 0..min_array_layers,
197 ..src_image.subresource_layers()
198 }
199 .to_vk(),
200 )
201 .src_offset(convert_offset([0; 3]))
202 .dst_subresource(
203 ImageSubresourceLayers {
204 array_layers: 0..min_array_layers,
205 ..dst_image.subresource_layers()
206 }
207 .to_vk(),
208 )
209 .dst_offset(convert_offset([0; 3]))
210 .extent(convert_extent([
211 cmp::min(src_extent[0], dst_extent[0]),
212 cmp::min(src_extent[1], dst_extent[1]),
213 cmp::min(src_extent[2], dst_extent[2]),
214 ]))];
215
216 let copy_image_info_vk = vk::CopyImageInfo2::default()
217 .src_image(src_image.handle())
218 .src_image_layout(src_image_layout.into())
219 .dst_image(dst_image.handle())
220 .dst_image_layout(dst_image_layout.into())
221 .regions(®ions_vk);
222
223 unsafe { cmd_copy_image2(self.handle(), ©_image_info_vk) };
224 } else {
225 let regions_vk = regions
226 .iter()
227 .map(|region| {
228 let &ImageCopy {
229 ref src_subresource,
230 src_offset,
231 ref dst_subresource,
232 dst_offset,
233 extent,
234 _ne: _,
235 } = region;
236
237 vk::ImageCopy2::default()
238 .src_subresource(src_subresource.to_vk())
239 .src_offset(convert_offset(src_offset))
240 .dst_subresource(dst_subresource.to_vk())
241 .dst_offset(convert_offset(dst_offset))
242 .extent(convert_extent(extent))
243 })
244 .collect::<SmallVec<[_; 8]>>();
245
246 let copy_image_info_vk = vk::CopyImageInfo2::default()
247 .src_image(src_image.handle())
248 .src_image_layout(src_image_layout.into())
249 .dst_image(dst_image.handle())
250 .dst_image_layout(dst_image_layout.into())
251 .regions(®ions_vk);
252
253 unsafe { cmd_copy_image2(self.handle(), ©_image_info_vk) };
254 }
255 } else {
256 let cmd_copy_image = fns.v1_0.cmd_copy_image;
257
258 if regions.is_empty() {
259 let min_array_layers = cmp::min(src_image.array_layers(), dst_image.array_layers());
260 let src_extent = src_image.extent();
261 let dst_extent = dst_image.extent();
262 let region_vk = vk::ImageCopy {
263 src_subresource: ImageSubresourceLayers {
264 array_layers: 0..min_array_layers,
265 ..src_image.subresource_layers()
266 }
267 .to_vk(),
268 src_offset: convert_offset([0; 3]),
269 dst_subresource: ImageSubresourceLayers {
270 array_layers: 0..min_array_layers,
271 ..dst_image.subresource_layers()
272 }
273 .to_vk(),
274 dst_offset: convert_offset([0; 3]),
275 extent: convert_extent([
276 cmp::min(src_extent[0], dst_extent[0]),
277 cmp::min(src_extent[1], dst_extent[1]),
278 cmp::min(src_extent[2], dst_extent[2]),
279 ]),
280 };
281
282 unsafe {
283 cmd_copy_image(
284 self.handle(),
285 src_image.handle(),
286 src_image_layout.into(),
287 dst_image.handle(),
288 dst_image_layout.into(),
289 1,
290 ®ion_vk,
291 )
292 };
293 } else {
294 let regions_vk: SmallVec<[_; 8]> = regions
295 .iter()
296 .map(|region| {
297 let &ImageCopy {
298 ref src_subresource,
299 src_offset,
300 ref dst_subresource,
301 dst_offset,
302 extent,
303 _ne: _,
304 } = region;
305
306 vk::ImageCopy {
307 src_subresource: src_subresource.to_vk(),
308 src_offset: convert_offset(src_offset),
309 dst_subresource: dst_subresource.to_vk(),
310 dst_offset: convert_offset(dst_offset),
311 extent: convert_extent(extent),
312 }
313 })
314 .collect();
315
316 unsafe {
317 cmd_copy_image(
318 self.handle(),
319 src_image.handle(),
320 src_image_layout.into(),
321 dst_image.handle(),
322 dst_image_layout.into(),
323 regions_vk.len() as u32,
324 regions_vk.as_ptr(),
325 )
326 };
327 }
328 }
329
330 self
331 }
332
333 pub unsafe fn copy_buffer_to_image(
335 &mut self,
336 copy_buffer_to_image_info: &CopyBufferToImageInfo<'_>,
337 ) -> Result<&mut Self> {
338 Ok(unsafe { self.copy_buffer_to_image_unchecked(copy_buffer_to_image_info) })
339 }
340
341 pub unsafe fn copy_buffer_to_image_unchecked(
342 &mut self,
343 copy_buffer_to_image_info: &CopyBufferToImageInfo<'_>,
344 ) -> &mut Self {
345 let &CopyBufferToImageInfo {
346 src_buffer,
347 dst_image,
348 dst_image_layout,
349 regions,
350 _ne: _,
351 } = copy_buffer_to_image_info;
352
353 let src_buffer = unsafe { self.accesses.buffer_unchecked(src_buffer) };
354 let dst_image = unsafe { self.accesses.image_unchecked(dst_image) };
355 let dst_image_layout = AccessTypes::COPY_TRANSFER_WRITE.image_layout(dst_image_layout);
356
357 let fns = self.device().fns();
358
359 if self.device().api_version() >= Version::V1_3
360 || self.device().enabled_extensions().khr_copy_commands2
361 {
362 let cmd_copy_buffer_to_image2 = if self.device().api_version() >= Version::V1_3 {
363 fns.v1_3.cmd_copy_buffer_to_image2
364 } else {
365 fns.khr_copy_commands2.cmd_copy_buffer_to_image2_khr
366 };
367
368 if regions.is_empty() {
369 let regions_vk = [vk::BufferImageCopy2::default()
370 .buffer_offset(0)
371 .buffer_row_length(0)
372 .buffer_image_height(0)
373 .image_subresource(dst_image.subresource_layers().to_vk())
374 .image_offset(convert_offset([0; 3]))
375 .image_extent(convert_extent(dst_image.extent()))];
376
377 let copy_buffer_to_image_info_vk = vk::CopyBufferToImageInfo2::default()
378 .src_buffer(src_buffer.handle())
379 .dst_image(dst_image.handle())
380 .dst_image_layout(dst_image_layout.into())
381 .regions(®ions_vk);
382
383 unsafe { cmd_copy_buffer_to_image2(self.handle(), ©_buffer_to_image_info_vk) };
384 } else {
385 let regions_vk = regions
386 .iter()
387 .map(|region| {
388 let &BufferImageCopy {
389 buffer_offset,
390 buffer_row_length,
391 buffer_image_height,
392 ref image_subresource,
393 image_offset,
394 image_extent,
395 _ne: _,
396 } = region;
397
398 vk::BufferImageCopy2::default()
399 .buffer_offset(buffer_offset)
400 .buffer_row_length(buffer_row_length)
401 .buffer_image_height(buffer_image_height)
402 .image_subresource(image_subresource.to_vk())
403 .image_offset(convert_offset(image_offset))
404 .image_extent(convert_extent(image_extent))
405 })
406 .collect::<SmallVec<[_; 8]>>();
407
408 let copy_buffer_to_image_info_vk = vk::CopyBufferToImageInfo2::default()
409 .src_buffer(src_buffer.handle())
410 .dst_image(dst_image.handle())
411 .dst_image_layout(dst_image_layout.into())
412 .regions(®ions_vk);
413
414 unsafe { cmd_copy_buffer_to_image2(self.handle(), ©_buffer_to_image_info_vk) };
415 }
416 } else {
417 let cmd_copy_buffer_to_image = fns.v1_0.cmd_copy_buffer_to_image;
418
419 if regions.is_empty() {
420 let region_vk = vk::BufferImageCopy {
421 buffer_offset: 0,
422 buffer_row_length: 0,
423 buffer_image_height: 0,
424 image_subresource: dst_image.subresource_layers().to_vk(),
425 image_offset: convert_offset([0; 3]),
426 image_extent: convert_extent(dst_image.extent()),
427 };
428
429 unsafe {
430 cmd_copy_buffer_to_image(
431 self.handle(),
432 src_buffer.handle(),
433 dst_image.handle(),
434 dst_image_layout.into(),
435 1,
436 ®ion_vk,
437 )
438 };
439 } else {
440 let regions_vk = regions
441 .iter()
442 .map(|region| {
443 let &BufferImageCopy {
444 buffer_offset,
445 buffer_row_length,
446 buffer_image_height,
447 ref image_subresource,
448 image_offset,
449 image_extent,
450 _ne: _,
451 } = region;
452
453 vk::BufferImageCopy {
454 buffer_offset,
455 buffer_row_length,
456 buffer_image_height,
457 image_subresource: image_subresource.to_vk(),
458 image_offset: convert_offset(image_offset),
459 image_extent: convert_extent(image_extent),
460 }
461 })
462 .collect::<SmallVec<[_; 8]>>();
463
464 unsafe {
465 cmd_copy_buffer_to_image(
466 self.handle(),
467 src_buffer.handle(),
468 dst_image.handle(),
469 dst_image_layout.into(),
470 regions_vk.len() as u32,
471 regions_vk.as_ptr(),
472 )
473 };
474 }
475 }
476
477 self
478 }
479
480 pub unsafe fn copy_image_to_buffer(
482 &mut self,
483 copy_image_to_buffer_info: &CopyImageToBufferInfo<'_>,
484 ) -> Result<&mut Self> {
485 Ok(unsafe { self.copy_image_to_buffer_unchecked(copy_image_to_buffer_info) })
486 }
487
488 pub unsafe fn copy_image_to_buffer_unchecked(
489 &mut self,
490 copy_image_to_buffer_info: &CopyImageToBufferInfo<'_>,
491 ) -> &mut Self {
492 let &CopyImageToBufferInfo {
493 src_image,
494 src_image_layout,
495 dst_buffer,
496 regions,
497 _ne: _,
498 } = copy_image_to_buffer_info;
499
500 let src_image = unsafe { self.accesses.image_unchecked(src_image) };
501 let src_image_layout = AccessTypes::COPY_TRANSFER_READ.image_layout(src_image_layout);
502 let dst_buffer = unsafe { self.accesses.buffer_unchecked(dst_buffer) };
503
504 let fns = self.device().fns();
505
506 if self.device().api_version() >= Version::V1_3
507 || self.device().enabled_extensions().khr_copy_commands2
508 {
509 let cmd_copy_image_to_buffer2 = if self.device().api_version() >= Version::V1_3 {
510 fns.v1_3.cmd_copy_image_to_buffer2
511 } else {
512 fns.khr_copy_commands2.cmd_copy_image_to_buffer2_khr
513 };
514
515 if regions.is_empty() {
516 let regions_vk = [vk::BufferImageCopy2::default()
517 .buffer_offset(0)
518 .buffer_row_length(0)
519 .buffer_image_height(0)
520 .image_subresource(src_image.subresource_layers().to_vk())
521 .image_offset(convert_offset([0; 3]))
522 .image_extent(convert_extent(src_image.extent()))];
523
524 let copy_image_to_buffer_info_vk = vk::CopyImageToBufferInfo2::default()
525 .src_image(src_image.handle())
526 .src_image_layout(src_image_layout.into())
527 .dst_buffer(dst_buffer.handle())
528 .regions(®ions_vk);
529
530 unsafe { cmd_copy_image_to_buffer2(self.handle(), ©_image_to_buffer_info_vk) };
531 } else {
532 let regions_vk = regions
533 .iter()
534 .map(|region| {
535 let &BufferImageCopy {
536 buffer_offset,
537 buffer_row_length,
538 buffer_image_height,
539 ref image_subresource,
540 image_offset,
541 image_extent,
542 _ne: _,
543 } = region;
544
545 vk::BufferImageCopy2::default()
546 .buffer_offset(buffer_offset)
547 .buffer_row_length(buffer_row_length)
548 .buffer_image_height(buffer_image_height)
549 .image_subresource(image_subresource.to_vk())
550 .image_offset(convert_offset(image_offset))
551 .image_extent(convert_extent(image_extent))
552 })
553 .collect::<SmallVec<[_; 8]>>();
554
555 let copy_image_to_buffer_info_vk = vk::CopyImageToBufferInfo2::default()
556 .src_image(src_image.handle())
557 .src_image_layout(src_image_layout.into())
558 .dst_buffer(dst_buffer.handle())
559 .regions(®ions_vk);
560
561 unsafe { cmd_copy_image_to_buffer2(self.handle(), ©_image_to_buffer_info_vk) };
562 }
563 } else {
564 let cmd_copy_image_to_buffer = fns.v1_0.cmd_copy_image_to_buffer;
565
566 if regions.is_empty() {
567 let region_vk = vk::BufferImageCopy {
568 buffer_offset: 0,
569 buffer_row_length: 0,
570 buffer_image_height: 0,
571 image_subresource: src_image.subresource_layers().to_vk(),
572 image_offset: convert_offset([0; 3]),
573 image_extent: convert_extent(src_image.extent()),
574 };
575
576 unsafe {
577 cmd_copy_image_to_buffer(
578 self.handle(),
579 src_image.handle(),
580 src_image_layout.into(),
581 dst_buffer.handle(),
582 1,
583 ®ion_vk,
584 )
585 };
586 } else {
587 let regions_vk = regions
588 .iter()
589 .map(|region| {
590 let &BufferImageCopy {
591 buffer_offset,
592 buffer_row_length,
593 buffer_image_height,
594 ref image_subresource,
595 image_offset,
596 image_extent,
597 _ne: _,
598 } = region;
599
600 vk::BufferImageCopy {
601 buffer_offset,
602 buffer_row_length,
603 buffer_image_height,
604 image_subresource: image_subresource.to_vk(),
605 image_offset: convert_offset(image_offset),
606 image_extent: convert_extent(image_extent),
607 }
608 })
609 .collect::<SmallVec<[_; 8]>>();
610
611 unsafe {
612 cmd_copy_image_to_buffer(
613 self.handle(),
614 src_image.handle(),
615 src_image_layout.into(),
616 dst_buffer.handle(),
617 regions_vk.len() as u32,
618 regions_vk.as_ptr(),
619 )
620 };
621 }
622 }
623
624 self
625 }
626
627 pub unsafe fn blit_image(&mut self, blit_image_info: &BlitImageInfo<'_>) -> Result<&mut Self> {
654 Ok(unsafe { self.blit_image_unchecked(blit_image_info) })
655 }
656
657 pub unsafe fn blit_image_unchecked(
658 &mut self,
659 blit_image_info: &BlitImageInfo<'_>,
660 ) -> &mut Self {
661 let &BlitImageInfo {
662 src_image,
663 src_image_layout,
664 dst_image,
665 dst_image_layout,
666 regions,
667 filter,
668 _ne: _,
669 } = blit_image_info;
670
671 let src_image = unsafe { self.accesses.image_unchecked(src_image) };
672 let src_image_layout = AccessTypes::BLIT_TRANSFER_READ.image_layout(src_image_layout);
673 let dst_image = unsafe { self.accesses.image_unchecked(dst_image) };
674 let dst_image_layout = AccessTypes::BLIT_TRANSFER_WRITE.image_layout(dst_image_layout);
675
676 let fns = self.device().fns();
677
678 if self.device().api_version() >= Version::V1_3
679 || self.device().enabled_extensions().khr_copy_commands2
680 {
681 let cmd_blit_image2 = if self.device().api_version() >= Version::V1_3 {
682 fns.v1_3.cmd_blit_image2
683 } else {
684 fns.khr_copy_commands2.cmd_blit_image2_khr
685 };
686
687 if regions.is_empty() {
688 let min_array_layers = cmp::min(src_image.array_layers(), dst_image.array_layers());
689 let regions_vk = [vk::ImageBlit2::default()
690 .src_subresource(
691 ImageSubresourceLayers {
692 array_layers: 0..min_array_layers,
693 ..src_image.subresource_layers()
694 }
695 .to_vk(),
696 )
697 .src_offsets([[0; 3], src_image.extent()].map(convert_offset))
698 .dst_subresource(
699 ImageSubresourceLayers {
700 array_layers: 0..min_array_layers,
701 ..src_image.subresource_layers()
702 }
703 .to_vk(),
704 )
705 .dst_offsets([[0; 3], dst_image.extent()].map(convert_offset))];
706
707 let blit_image_info_vk = vk::BlitImageInfo2::default()
708 .src_image(src_image.handle())
709 .src_image_layout(src_image_layout.into())
710 .dst_image(dst_image.handle())
711 .dst_image_layout(dst_image_layout.into())
712 .regions(®ions_vk)
713 .filter(filter.into());
714
715 unsafe { cmd_blit_image2(self.handle(), &blit_image_info_vk) };
716 } else {
717 let regions_vk = regions
718 .iter()
719 .map(|region| {
720 let &ImageBlit {
721 ref src_subresource,
722 src_offsets,
723 ref dst_subresource,
724 dst_offsets,
725 _ne: _,
726 } = region;
727
728 vk::ImageBlit2::default()
729 .src_subresource(src_subresource.to_vk())
730 .src_offsets(src_offsets.map(convert_offset))
731 .dst_subresource(dst_subresource.to_vk())
732 .dst_offsets(dst_offsets.map(convert_offset))
733 })
734 .collect::<SmallVec<[_; 8]>>();
735
736 let blit_image_info_vk = vk::BlitImageInfo2::default()
737 .src_image(src_image.handle())
738 .src_image_layout(src_image_layout.into())
739 .dst_image(dst_image.handle())
740 .dst_image_layout(dst_image_layout.into())
741 .regions(®ions_vk)
742 .filter(filter.into());
743
744 unsafe { cmd_blit_image2(self.handle(), &blit_image_info_vk) };
745 }
746 } else {
747 let cmd_blit_image = fns.v1_0.cmd_blit_image;
748
749 if regions.is_empty() {
750 let min_array_layers = cmp::min(src_image.array_layers(), dst_image.array_layers());
751 let region_vk = vk::ImageBlit {
752 src_subresource: ImageSubresourceLayers {
753 array_layers: 0..min_array_layers,
754 ..src_image.subresource_layers()
755 }
756 .to_vk(),
757 src_offsets: [[0; 3], src_image.extent()].map(convert_offset),
758 dst_subresource: ImageSubresourceLayers {
759 array_layers: 0..min_array_layers,
760 ..dst_image.subresource_layers()
761 }
762 .to_vk(),
763 dst_offsets: [[0; 3], dst_image.extent()].map(convert_offset),
764 };
765
766 unsafe {
767 cmd_blit_image(
768 self.handle(),
769 src_image.handle(),
770 src_image_layout.into(),
771 dst_image.handle(),
772 dst_image_layout.into(),
773 1,
774 ®ion_vk,
775 filter.into(),
776 )
777 };
778 } else {
779 let regions_vk = regions
780 .iter()
781 .map(|region| {
782 let &ImageBlit {
783 ref src_subresource,
784 src_offsets,
785 ref dst_subresource,
786 dst_offsets,
787 _ne: _,
788 } = region;
789
790 vk::ImageBlit {
791 src_subresource: src_subresource.to_vk(),
792 src_offsets: src_offsets.map(convert_offset),
793 dst_subresource: dst_subresource.to_vk(),
794 dst_offsets: dst_offsets.map(convert_offset),
795 }
796 })
797 .collect::<SmallVec<[_; 8]>>();
798
799 unsafe {
800 cmd_blit_image(
801 self.handle(),
802 src_image.handle(),
803 src_image_layout.into(),
804 dst_image.handle(),
805 dst_image_layout.into(),
806 regions_vk.len() as u32,
807 regions_vk.as_ptr(),
808 filter.into(),
809 )
810 };
811 }
812 }
813
814 self
815 }
816
817 pub unsafe fn resolve_image(
819 &mut self,
820 resolve_image_info: &ResolveImageInfo<'_>,
821 ) -> Result<&mut Self> {
822 Ok(unsafe { self.resolve_image_unchecked(resolve_image_info) })
823 }
824
825 pub unsafe fn resolve_image_unchecked(
826 &mut self,
827 resolve_image_info: &ResolveImageInfo<'_>,
828 ) -> &mut Self {
829 let &ResolveImageInfo {
830 src_image,
831 src_image_layout,
832 dst_image,
833 dst_image_layout,
834 regions,
835 _ne: _,
836 } = resolve_image_info;
837
838 let src_image = unsafe { self.accesses.image_unchecked(src_image) };
839 let src_image_layout = AccessTypes::RESOLVE_TRANSFER_READ.image_layout(src_image_layout);
840 let dst_image = unsafe { self.accesses.image_unchecked(dst_image) };
841 let dst_image_layout = AccessTypes::RESOLVE_TRANSFER_WRITE.image_layout(dst_image_layout);
842
843 let fns = self.device().fns();
844
845 if self.device().api_version() >= Version::V1_3
846 || self.device().enabled_extensions().khr_copy_commands2
847 {
848 let cmd_resolve_image2 = if self.device().api_version() >= Version::V1_3 {
849 fns.v1_3.cmd_resolve_image2
850 } else {
851 fns.khr_copy_commands2.cmd_resolve_image2_khr
852 };
853
854 if regions.is_empty() {
855 let min_array_layers = cmp::min(src_image.array_layers(), dst_image.array_layers());
856 let src_extent = src_image.extent();
857 let dst_extent = dst_image.extent();
858 let regions_vk = [vk::ImageResolve2::default()
859 .src_subresource(
860 ImageSubresourceLayers {
861 array_layers: 0..min_array_layers,
862 ..src_image.subresource_layers()
863 }
864 .to_vk(),
865 )
866 .src_offset(convert_offset([0; 3]))
867 .dst_subresource(
868 ImageSubresourceLayers {
869 array_layers: 0..min_array_layers,
870 ..src_image.subresource_layers()
871 }
872 .to_vk(),
873 )
874 .dst_offset(convert_offset([0; 3]))
875 .extent(convert_extent([
876 cmp::min(src_extent[0], dst_extent[0]),
877 cmp::min(src_extent[1], dst_extent[1]),
878 cmp::min(src_extent[2], dst_extent[2]),
879 ]))];
880
881 let resolve_image_info_vk = vk::ResolveImageInfo2::default()
882 .src_image(src_image.handle())
883 .src_image_layout(src_image_layout.into())
884 .dst_image(dst_image.handle())
885 .dst_image_layout(dst_image_layout.into())
886 .regions(®ions_vk);
887
888 unsafe { cmd_resolve_image2(self.handle(), &resolve_image_info_vk) };
889 } else {
890 let regions_vk = regions
891 .iter()
892 .map(|region| {
893 let &ImageResolve {
894 ref src_subresource,
895 src_offset,
896 ref dst_subresource,
897 dst_offset,
898 extent,
899 _ne: _,
900 } = region;
901
902 vk::ImageResolve2::default()
903 .src_subresource(src_subresource.to_vk())
904 .src_offset(convert_offset(src_offset))
905 .dst_subresource(dst_subresource.to_vk())
906 .dst_offset(convert_offset(dst_offset))
907 .extent(convert_extent(extent))
908 })
909 .collect::<SmallVec<[_; 8]>>();
910
911 let resolve_image_info_vk = vk::ResolveImageInfo2::default()
912 .src_image(src_image.handle())
913 .src_image_layout(src_image_layout.into())
914 .dst_image(dst_image.handle())
915 .dst_image_layout(dst_image_layout.into())
916 .regions(®ions_vk);
917
918 unsafe { cmd_resolve_image2(self.handle(), &resolve_image_info_vk) };
919 }
920 } else {
921 let cmd_resolve_image = fns.v1_0.cmd_resolve_image;
922
923 if regions.is_empty() {
924 let min_array_layers = cmp::min(src_image.array_layers(), dst_image.array_layers());
925 let src_extent = src_image.extent();
926 let dst_extent = dst_image.extent();
927 let regions_vk = [vk::ImageResolve {
928 src_subresource: ImageSubresourceLayers {
929 array_layers: 0..min_array_layers,
930 ..src_image.subresource_layers()
931 }
932 .to_vk(),
933 src_offset: convert_offset([0; 3]),
934 dst_subresource: ImageSubresourceLayers {
935 array_layers: 0..min_array_layers,
936 ..dst_image.subresource_layers()
937 }
938 .to_vk(),
939 dst_offset: convert_offset([0; 3]),
940 extent: convert_extent([
941 cmp::min(src_extent[0], dst_extent[0]),
942 cmp::min(src_extent[1], dst_extent[1]),
943 cmp::min(src_extent[2], dst_extent[2]),
944 ]),
945 }];
946
947 unsafe {
948 cmd_resolve_image(
949 self.handle(),
950 src_image.handle(),
951 src_image_layout.into(),
952 dst_image.handle(),
953 dst_image_layout.into(),
954 regions_vk.len() as u32,
955 regions_vk.as_ptr(),
956 )
957 };
958 } else {
959 let regions_vk = regions
960 .iter()
961 .map(|region| {
962 let &ImageResolve {
963 ref src_subresource,
964 src_offset,
965 ref dst_subresource,
966 dst_offset,
967 extent,
968 _ne: _,
969 } = region;
970
971 vk::ImageResolve {
972 src_subresource: src_subresource.to_vk(),
973 src_offset: convert_offset(src_offset),
974 dst_subresource: dst_subresource.to_vk(),
975 dst_offset: convert_offset(dst_offset),
976 extent: convert_extent(extent),
977 }
978 })
979 .collect::<SmallVec<[_; 8]>>();
980
981 unsafe {
982 cmd_resolve_image(
983 self.handle(),
984 src_image.handle(),
985 src_image_layout.into(),
986 dst_image.handle(),
987 dst_image_layout.into(),
988 regions_vk.len() as u32,
989 regions_vk.as_ptr(),
990 )
991 };
992 }
993 }
994
995 self
996 }
997}
998
999#[derive(Clone, Debug)]
1003pub struct CopyBufferInfo<'a> {
1004 pub src_buffer: Id<Buffer>,
1008
1009 pub dst_buffer: Id<Buffer>,
1013
1014 pub regions: &'a [BufferCopy<'a>],
1019
1020 pub _ne: crate::NonExhaustive<'a>,
1021}
1022
1023impl Default for CopyBufferInfo<'_> {
1024 #[inline]
1025 fn default() -> Self {
1026 CopyBufferInfo {
1027 src_buffer: Id::INVALID,
1028 dst_buffer: Id::INVALID,
1029 regions: &[],
1030 _ne: crate::NE,
1031 }
1032 }
1033}
1034
1035#[derive(Clone, Debug)]
1037pub struct BufferCopy<'a> {
1038 pub src_offset: DeviceSize,
1043
1044 pub dst_offset: DeviceSize,
1049
1050 pub size: DeviceSize,
1054
1055 pub _ne: crate::NonExhaustive<'a>,
1056}
1057
1058impl Default for BufferCopy<'_> {
1059 #[inline]
1060 fn default() -> Self {
1061 Self {
1062 src_offset: 0,
1063 dst_offset: 0,
1064 size: 0,
1065 _ne: crate::NE,
1066 }
1067 }
1068}
1069
1070#[derive(Clone, Debug)]
1072pub struct CopyImageInfo<'a> {
1073 pub src_image: Id<Image>,
1077
1078 pub src_image_layout: ImageLayoutType,
1082
1083 pub dst_image: Id<Image>,
1087
1088 pub dst_image_layout: ImageLayoutType,
1092
1093 pub regions: &'a [ImageCopy<'a>],
1099
1100 pub _ne: crate::NonExhaustive<'a>,
1101}
1102
1103impl Default for CopyImageInfo<'_> {
1104 #[inline]
1105 fn default() -> Self {
1106 CopyImageInfo {
1107 src_image: Id::INVALID,
1108 src_image_layout: ImageLayoutType::Optimal,
1109 dst_image: Id::INVALID,
1110 dst_image_layout: ImageLayoutType::Optimal,
1111 regions: &[],
1112 _ne: crate::NE,
1113 }
1114 }
1115}
1116
1117#[derive(Clone, Debug)]
1119pub struct ImageCopy<'a> {
1120 pub src_subresource: ImageSubresourceLayers,
1124
1125 pub src_offset: [u32; 3],
1129
1130 pub dst_subresource: ImageSubresourceLayers,
1134
1135 pub dst_offset: [u32; 3],
1139
1140 pub extent: [u32; 3],
1144
1145 pub _ne: crate::NonExhaustive<'a>,
1146}
1147
1148impl Default for ImageCopy<'_> {
1149 #[inline]
1150 fn default() -> Self {
1151 Self {
1152 src_subresource: ImageSubresourceLayers {
1153 aspects: ImageAspects::empty(),
1154 mip_level: 0,
1155 array_layers: 0..0,
1156 },
1157 src_offset: [0; 3],
1158 dst_subresource: ImageSubresourceLayers {
1159 aspects: ImageAspects::empty(),
1160 mip_level: 0,
1161 array_layers: 0..0,
1162 },
1163 dst_offset: [0; 3],
1164 extent: [0; 3],
1165 _ne: crate::NE,
1166 }
1167 }
1168}
1169
1170#[derive(Clone, Debug)]
1172pub struct CopyBufferToImageInfo<'a> {
1173 pub src_buffer: Id<Buffer>,
1177
1178 pub dst_image: Id<Image>,
1182
1183 pub dst_image_layout: ImageLayoutType,
1187
1188 pub regions: &'a [BufferImageCopy<'a>],
1193
1194 pub _ne: crate::NonExhaustive<'a>,
1195}
1196
1197impl Default for CopyBufferToImageInfo<'_> {
1198 #[inline]
1199 fn default() -> Self {
1200 CopyBufferToImageInfo {
1201 src_buffer: Id::INVALID,
1202 dst_image: Id::INVALID,
1203 dst_image_layout: ImageLayoutType::Optimal,
1204 regions: &[],
1205 _ne: crate::NE,
1206 }
1207 }
1208}
1209
1210#[derive(Clone, Debug)]
1212pub struct CopyImageToBufferInfo<'a> {
1213 pub src_image: Id<Image>,
1217
1218 pub src_image_layout: ImageLayoutType,
1222
1223 pub dst_buffer: Id<Buffer>,
1227
1228 pub regions: &'a [BufferImageCopy<'a>],
1233
1234 pub _ne: crate::NonExhaustive<'a>,
1235}
1236
1237impl Default for CopyImageToBufferInfo<'_> {
1238 #[inline]
1239 fn default() -> Self {
1240 CopyImageToBufferInfo {
1241 src_image: Id::INVALID,
1242 src_image_layout: ImageLayoutType::Optimal,
1243 dst_buffer: Id::INVALID,
1244 regions: &[],
1245 _ne: crate::NE,
1246 }
1247 }
1248}
1249
1250#[derive(Clone, Debug)]
1252pub struct BufferImageCopy<'a> {
1253 pub buffer_offset: DeviceSize,
1257
1258 pub buffer_row_length: u32,
1264
1265 pub buffer_image_height: u32,
1271
1272 pub image_subresource: ImageSubresourceLayers,
1276
1277 pub image_offset: [u32; 3],
1281
1282 pub image_extent: [u32; 3],
1286
1287 pub _ne: crate::NonExhaustive<'a>,
1288}
1289
1290impl Default for BufferImageCopy<'_> {
1291 #[inline]
1292 fn default() -> Self {
1293 Self {
1294 buffer_offset: 0,
1295 buffer_row_length: 0,
1296 buffer_image_height: 0,
1297 image_subresource: ImageSubresourceLayers {
1298 aspects: ImageAspects::empty(),
1299 mip_level: 0,
1300 array_layers: 0..0,
1301 },
1302 image_offset: [0; 3],
1303 image_extent: [0; 3],
1304 _ne: crate::NE,
1305 }
1306 }
1307}
1308
1309#[derive(Clone, Debug)]
1311pub struct BlitImageInfo<'a> {
1312 pub src_image: Id<Image>,
1316
1317 pub src_image_layout: ImageLayoutType,
1321
1322 pub dst_image: Id<Image>,
1326
1327 pub dst_image_layout: ImageLayoutType,
1331
1332 pub regions: &'a [ImageBlit<'a>],
1339
1340 pub filter: Filter,
1345
1346 pub _ne: crate::NonExhaustive<'a>,
1347}
1348
1349impl Default for BlitImageInfo<'_> {
1350 #[inline]
1351 fn default() -> Self {
1352 BlitImageInfo {
1353 src_image: Id::INVALID,
1354 src_image_layout: ImageLayoutType::Optimal,
1355 dst_image: Id::INVALID,
1356 dst_image_layout: ImageLayoutType::Optimal,
1357 regions: &[],
1358 filter: Filter::Nearest,
1359 _ne: crate::NE,
1360 }
1361 }
1362}
1363
1364#[derive(Clone, Debug)]
1366pub struct ImageBlit<'a> {
1367 pub src_subresource: ImageSubresourceLayers,
1371
1372 pub src_offsets: [[u32; 3]; 2],
1379
1380 pub dst_subresource: ImageSubresourceLayers,
1384
1385 pub dst_offsets: [[u32; 3]; 2],
1392
1393 pub _ne: crate::NonExhaustive<'a>,
1394}
1395
1396impl Default for ImageBlit<'_> {
1397 #[inline]
1398 fn default() -> Self {
1399 Self {
1400 src_subresource: ImageSubresourceLayers {
1401 aspects: ImageAspects::empty(),
1402 mip_level: 0,
1403 array_layers: 0..0,
1404 },
1405 src_offsets: [[0; 3]; 2],
1406 dst_subresource: ImageSubresourceLayers {
1407 aspects: ImageAspects::empty(),
1408 mip_level: 0,
1409 array_layers: 0..0,
1410 },
1411 dst_offsets: [[0; 3]; 2],
1412 _ne: crate::NE,
1413 }
1414 }
1415}
1416
1417#[derive(Clone, Debug)]
1419pub struct ResolveImageInfo<'a> {
1420 pub src_image: Id<Image>,
1424
1425 pub src_image_layout: ImageLayoutType,
1429
1430 pub dst_image: Id<Image>,
1434
1435 pub dst_image_layout: ImageLayoutType,
1439
1440 pub regions: &'a [ImageResolve<'a>],
1446
1447 pub _ne: crate::NonExhaustive<'a>,
1448}
1449
1450impl Default for ResolveImageInfo<'_> {
1451 #[inline]
1452 fn default() -> Self {
1453 ResolveImageInfo {
1454 src_image: Id::INVALID,
1455 src_image_layout: ImageLayoutType::Optimal,
1456 dst_image: Id::INVALID,
1457 dst_image_layout: ImageLayoutType::Optimal,
1458 regions: &[],
1459 _ne: crate::NE,
1460 }
1461 }
1462}
1463
1464#[derive(Clone, Debug)]
1466pub struct ImageResolve<'a> {
1467 pub src_subresource: ImageSubresourceLayers,
1471
1472 pub src_offset: [u32; 3],
1476
1477 pub dst_subresource: ImageSubresourceLayers,
1481
1482 pub dst_offset: [u32; 3],
1486
1487 pub extent: [u32; 3],
1491
1492 pub _ne: crate::NonExhaustive<'a>,
1493}
1494
1495impl Default for ImageResolve<'_> {
1496 #[inline]
1497 fn default() -> Self {
1498 Self {
1499 src_subresource: ImageSubresourceLayers {
1500 aspects: ImageAspects::empty(),
1501 mip_level: 0,
1502 array_layers: 0..0,
1503 },
1504 src_offset: [0; 3],
1505 dst_subresource: ImageSubresourceLayers {
1506 aspects: ImageAspects::empty(),
1507 mip_level: 0,
1508 array_layers: 0..0,
1509 },
1510 dst_offset: [0; 3],
1511 extent: [0; 3],
1512 _ne: crate::NE,
1513 }
1514 }
1515}
1516
1517fn convert_offset(offset: [u32; 3]) -> vk::Offset3D {
1518 vk::Offset3D {
1519 x: offset[0] as i32,
1520 y: offset[1] as i32,
1521 z: offset[2] as i32,
1522 }
1523}
1524
1525fn convert_extent(extent: [u32; 3]) -> vk::Extent3D {
1526 vk::Extent3D {
1527 width: extent[0],
1528 height: extent[1],
1529 depth: extent[2],
1530 }
1531}