Add to_file function for image
This commit is contained in:
parent
530f0d4e03
commit
69ec318579
1 changed files with 83 additions and 0 deletions
|
@ -5,6 +5,7 @@ use crate::prelude::*;
|
|||
use anyhow::Result;
|
||||
|
||||
use std::cmp;
|
||||
use std::path::Path;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
||||
|
@ -776,6 +777,88 @@ impl Image {
|
|||
VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL => VK_ACCESS_SHADER_READ_BIT.into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_file(self: &Arc<Image>, path: impl AsRef<Path>) -> Result<()> {
|
||||
let buffer = self.copy_image_to_buffer()?;
|
||||
let memory = buffer.map_complete()?;
|
||||
|
||||
let image = image::RgbaImage::from_raw(
|
||||
self.width,
|
||||
self.height,
|
||||
memory.iter().map(|&v| v).collect(),
|
||||
)
|
||||
.ok_or(anyhow::anyhow!(
|
||||
"failed to create image from raw while saving to file: {:?}",
|
||||
path.as_ref()
|
||||
))?;
|
||||
|
||||
image.save(path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn copy_image_to_buffer(self: &Arc<Image>) -> Result<Arc<Buffer<u8>>> {
|
||||
let buffer = Buffer::builder()
|
||||
.set_usage(VK_BUFFER_USAGE_TRANSFER_DST_BIT)
|
||||
.set_memory_usage(MemoryUsage::GpuToCpu)
|
||||
.set_size((self.width * self.height * 4) as VkDeviceSize)
|
||||
.build(self.device.clone())?;
|
||||
|
||||
let command_buffer =
|
||||
CommandBuffer::new_primary().build(self.device.clone(), self.queue.clone())?;
|
||||
|
||||
SingleSubmit::builder(&command_buffer, &self.queue, |recorder| {
|
||||
// copy info for copying the content of the buffer into the image
|
||||
let buffer_image_copy = VkBufferImageCopy {
|
||||
bufferOffset: 0,
|
||||
bufferRowLength: 0,
|
||||
bufferImageHeight: 0,
|
||||
imageSubresource: VkImageSubresourceLayers {
|
||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
||||
mipLevel: 0,
|
||||
baseArrayLayer: 0,
|
||||
layerCount: 1,
|
||||
},
|
||||
imageOffset: VkOffset3D { x: 0, y: 0, z: 0 },
|
||||
imageExtent: VkExtent3D {
|
||||
width: self.width(),
|
||||
height: self.height(),
|
||||
depth: 1,
|
||||
},
|
||||
};
|
||||
|
||||
// subresource information
|
||||
let subresource_range = VkImageSubresourceRange {
|
||||
aspectMask: VK_IMAGE_ASPECT_COLOR_BIT.into(),
|
||||
baseMipLevel: 0,
|
||||
levelCount: 1,
|
||||
baseArrayLayer: 0,
|
||||
layerCount: 1,
|
||||
};
|
||||
|
||||
let current_layout = self.image_layout();
|
||||
|
||||
recorder.set_image_layout(
|
||||
self,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
subresource_range.clone(),
|
||||
);
|
||||
|
||||
recorder.copy_image_to_buffer(
|
||||
self,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
&buffer,
|
||||
&[buffer_image_copy],
|
||||
);
|
||||
|
||||
recorder.set_image_layout(self, current_layout, subresource_range);
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.submit()?;
|
||||
|
||||
Ok(buffer)
|
||||
}
|
||||
}
|
||||
|
||||
impl VulkanDevice for Image {
|
||||
|
|
Loading…
Reference in a new issue