diff options
Diffstat (limited to 'stockton-render/src/draw/buffers/dedicated_image.rs')
-rw-r--r-- | stockton-render/src/draw/buffers/dedicated_image.rs | 199 |
1 files changed, 4 insertions, 195 deletions
diff --git a/stockton-render/src/draw/buffers/dedicated_image.rs b/stockton-render/src/draw/buffers/dedicated_image.rs index 38a23c9..878d304 100644 --- a/stockton-render/src/draw/buffers/dedicated_image.rs +++ b/stockton-render/src/draw/buffers/dedicated_image.rs @@ -1,18 +1,16 @@ //! A dedicated image. Used for depth buffers. -use super::create_buffer; -use crate::draw::texture::{LoadableImage, PIXEL_SIZE}; +use crate::draw::texture::PIXEL_SIZE; use crate::types::*; -use std::{array::IntoIter, convert::TryInto, iter::empty, mem::ManuallyDrop}; +use std::mem::ManuallyDrop; use anyhow::{Context, Result}; use hal::{ - buffer::Usage as BufUsage, - format::{Aspects, Format, Swizzle}, + format::{Format, Swizzle}, image::{SubresourceRange, Usage, Usage as ImgUsage, ViewKind}, memory, - memory::{Properties, Segment}, + memory::Properties, MemoryTypeId, }; use thiserror::Error; @@ -122,195 +120,6 @@ impl DedicatedLoadedImage { }) } - /// Load the given image - pub fn load<T: LoadableImage>( - &mut self, - img: T, - device: &mut DeviceT, - adapter: &Adapter, - command_queue: &mut QueueT, - command_pool: &mut CommandPoolT, - ) -> Result<()> { - let initial_row_size = PIXEL_SIZE * img.width() as usize; - let limits = adapter.physical_device.properties().limits; - let row_alignment_mask = limits.optimal_buffer_copy_pitch_alignment as u32 - 1; - - let row_size = - ((initial_row_size as u32 + row_alignment_mask) & !row_alignment_mask) as usize; - let total_size = (row_size * (img.height() as usize)) as u64; - debug_assert!(row_size as usize >= initial_row_size); - - // Make a staging buffer - let (staging_buffer, mut staging_memory) = create_buffer( - device, - adapter, - BufUsage::TRANSFER_SRC, - memory::Properties::CPU_VISIBLE | memory::Properties::COHERENT, - total_size, - ) - .context("Error creating staging buffer")?; - - // Copy everything into it - unsafe { - let mapped_memory: *mut u8 = std::mem::transmute( - device - .map_memory( - &mut staging_memory, - Segment { - offset: 0, - size: None, - }, - ) - .context("Error mapping staging memory")?, - ); - - for y in 0..img.height() as usize { - let dest_base: isize = (y * row_size).try_into()?; - img.copy_row(y as u32, mapped_memory.offset(dest_base)); - } - - device.unmap_memory(&mut staging_memory); - } - - // Copy from staging to image memory - let buf = unsafe { - use hal::command::{BufferImageCopy, CommandBufferFlags}; - use hal::image::{Access, Extent, Layout, Offset, SubresourceLayers}; - use hal::memory::Barrier; - use hal::pso::PipelineStage; - - // Get a command buffer - let mut buf = command_pool.allocate_one(hal::command::Level::Primary); - buf.begin_primary(CommandBufferFlags::ONE_TIME_SUBMIT); - - // Setup the layout of our image for copying - let image_barrier = Barrier::Image { - states: (Access::empty(), Layout::Undefined) - ..(Access::TRANSFER_WRITE, Layout::TransferDstOptimal), - target: &(*self.image), - families: None, - range: SubresourceRange { - aspects: Aspects::COLOR, - level_start: 0, - level_count: Some(1), - layer_start: 0, - layer_count: Some(1), - }, - }; - buf.pipeline_barrier( - PipelineStage::TOP_OF_PIPE..PipelineStage::TRANSFER, - memory::Dependencies::empty(), - IntoIter::new([image_barrier]), - ); - - // Copy from buffer to image - buf.copy_buffer_to_image( - &staging_buffer, - &(*self.image), - Layout::TransferDstOptimal, - IntoIter::new([BufferImageCopy { - buffer_offset: 0, - buffer_width: (row_size / PIXEL_SIZE) as u32, - buffer_height: img.height(), - image_layers: SubresourceLayers { - aspects: Aspects::COLOR, - level: 0, - layers: 0..1, - }, - image_offset: Offset { x: 0, y: 0, z: 0 }, - image_extent: Extent { - width: img.width(), - height: img.height(), - depth: 1, - }, - }]), - ); - - // Setup the layout of our image for shaders - let image_barrier = Barrier::Image { - states: (Access::TRANSFER_WRITE, Layout::TransferDstOptimal) - ..(Access::SHADER_READ, Layout::ShaderReadOnlyOptimal), - target: &(*self.image), - families: None, - range: SubresourceRange { - aspects: Aspects::COLOR, - level_start: 0, - level_count: Some(1), - layer_start: 0, - layer_count: Some(1), - }, - }; - - buf.pipeline_barrier( - PipelineStage::TRANSFER..PipelineStage::FRAGMENT_SHADER, - memory::Dependencies::empty(), - IntoIter::new([image_barrier]), - ); - - buf.finish(); - - buf - }; - - // Submit our commands and wait for them to finish - unsafe { - let mut setup_finished = device - .create_fence(false) - .context("Error creating setup_finished fence")?; - command_queue.submit( - IntoIter::new([&buf]), - empty(), - empty(), - Some(&mut setup_finished), - ); - - device - .wait_for_fence(&setup_finished, core::u64::MAX) - .context("Error waiting for image load to finish")?; - device.destroy_fence(setup_finished); - }; - - // Clean up temp resources - unsafe { - command_pool.free(std::iter::once(buf)); - - device.free_memory(staging_memory); - device.destroy_buffer(staging_buffer); - } - - Ok(()) - } - - /// Load the given image into a new buffer - pub fn load_into_new<T: LoadableImage>( - img: T, - device: &mut DeviceT, - adapter: &Adapter, - command_queue: &mut QueueT, - command_pool: &mut CommandPoolT, - format: Format, - usage: Usage, - ) -> Result<DedicatedLoadedImage> { - let mut loaded_image = Self::new( - device, - adapter, - format, - usage | Usage::TRANSFER_DST, - SubresourceRange { - aspects: Aspects::COLOR, - level_start: 0, - level_count: Some(1), - layer_start: 0, - layer_count: Some(1), - }, - img.width() as usize, - img.height() as usize, - )?; - loaded_image.load(img, device, adapter, command_queue, command_pool)?; - - Ok(loaded_image) - } - /// Properly frees/destroys all the objects in this struct /// Dropping without doing this is a bad idea pub fn deactivate(self, device: &mut DeviceT) { |