Complete section 28

This commit is contained in:
Timothy Warren 2023-04-14 10:21:26 -04:00
parent 425577029d
commit 3e453a8170
1 changed files with 114 additions and 1 deletions

View File

@ -231,6 +231,8 @@ impl AppData {
/// Here be Dragons
pub unsafe fn destroy(&mut self, instance: &Instance, device: &Device) {
self.destroy_swapchain(device);
device.destroy_image(self.texture_image, None);
device.free_memory(self.texture_image_memory, None);
device.destroy_descriptor_set_layout(self.descriptor_set_layout, None);
device.destroy_buffer(self.index_buffer, None);
@ -684,6 +686,7 @@ impl AppData {
//================================================
fn create_texture_image(&mut self, instance: &Instance, device: &Device) -> Result<()> {
// Load the image
let image = File::open("resources/texture.png")?;
let decoder = png::Decoder::new(image);
@ -695,7 +698,8 @@ impl AppData {
let size = reader.info().raw_bytes() as u64;
let (width, height) = reader.info().size();
let (_, staging_buffer_memory) = unsafe {
// Create the staging buffer
let (staging_buffer, staging_buffer_memory) = unsafe {
self.create_buffer(
instance,
device,
@ -727,6 +731,27 @@ impl AppData {
self.texture_image = texture_image;
self.texture_image_memory = texture_image_memory;
self.transition_image_layout(
device,
self.texture_image,
vk::Format::R8G8B8A8_SRGB,
vk::ImageLayout::UNDEFINED,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
)?;
self.copy_buffer_to_image(device, staging_buffer, self.texture_image, width, height)?;
self.transition_image_layout(
device,
self.texture_image,
vk::Format::R8G8B8A8_SRGB,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
)?;
device.destroy_buffer(staging_buffer, None);
device.free_memory(staging_buffer_memory, None);
}
Ok(())
@ -1079,8 +1104,96 @@ impl AppData {
old_layout: vk::ImageLayout,
new_layout: vk::ImageLayout,
) -> Result<()> {
let (src_access_mask, dst_access_mask, src_stage_mask, dst_stage_mask) =
match (old_layout, new_layout) {
(vk::ImageLayout::UNDEFINED, vk::ImageLayout::TRANSFER_DST_OPTIMAL) => (
vk::AccessFlags::empty(),
vk::AccessFlags::TRANSFER_WRITE,
vk::PipelineStageFlags::TOP_OF_PIPE,
vk::PipelineStageFlags::TRANSFER,
),
(
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
) => (
vk::AccessFlags::TRANSFER_WRITE,
vk::AccessFlags::SHADER_READ,
vk::PipelineStageFlags::TRANSFER,
vk::PipelineStageFlags::FRAGMENT_SHADER,
),
_ => return Err(anyhow!("Unsupported image layout transition!")),
};
let command_buffer = self.begin_single_time_commands(device)?;
let subresource = vk::ImageSubresourceRange::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.base_mip_level(0)
.level_count(1)
.base_array_layer(0)
.layer_count(1);
let barrier = vk::ImageMemoryBarrier::builder()
.old_layout(old_layout)
.new_layout(new_layout)
.src_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
.dst_queue_family_index(vk::QUEUE_FAMILY_IGNORED)
.image(image)
.subresource_range(subresource)
.src_access_mask(src_access_mask)
.dst_access_mask(dst_access_mask);
device.cmd_pipeline_barrier(
command_buffer,
src_stage_mask,
dst_stage_mask,
vk::DependencyFlags::empty(),
&[] as &[vk::MemoryBarrier],
&[] as &[vk::BufferMemoryBarrier],
&[barrier],
);
self.end_single_time_commands(device, command_buffer)?;
Ok(())
}
unsafe fn copy_buffer_to_image(
&self,
device: &Device,
buffer: vk::Buffer,
image: vk::Image,
width: u32,
height: u32,
) -> Result<()> {
let command_buffer = self.begin_single_time_commands(device)?;
let subresource = vk::ImageSubresourceLayers::builder()
.aspect_mask(vk::ImageAspectFlags::COLOR)
.mip_level(0)
.base_array_layer(0)
.layer_count(1);
let region = vk::BufferImageCopy::builder()
.buffer_offset(0)
.buffer_row_length(0)
.buffer_image_height(0)
.image_subresource(subresource)
.image_offset(vk::Offset3D { x: 0, y: 0, z: 0 })
.image_extent(vk::Extent3D {
width,
height,
depth: 1,
});
device.cmd_copy_buffer_to_image(
command_buffer,
buffer,
image,
vk::ImageLayout::TRANSFER_DST_OPTIMAL,
&[region],
);
self.end_single_time_commands(device, command_buffer)?;
Ok(())