// Currently this copies the entire buffer to an entire image;
// we could improve it by coping regions/extents.
Currently this copies the entire buffer to an entire image;
we could improve it by coping regions/extents.
Currently this copies the entire buffer to an entire image ; we could improve it by coping regions / extents .
pub fn copy_in_from_buffer(
        &mut self,
        device: &Device,
        commander: &Commander,
        buffer: &Buffer,
        main_texture_size: u32,
        min_mipmap_size: u32)
        -> Result<(), Error>
    {
        use dacite::core::{CommandBufferBeginInfo, CommandBufferUsageFlags,
                           CommandBufferResetFlags,
                           ImageMemoryBarrier, QueueFamilyIndex,
                           DependencyFlags,
                           FenceCreateInfo, FenceCreateFlags,
                           SubmitInfo, Timeout, ImageAspectFlags, OptionalMipLevels,
                           OptionalArrayLayers, BufferImageCopy,
                           ImageSubresourceLayers, Offset3D};
        commander.xfr_command_buffer.reset(CommandBufferResetFlags::RELEASE_RESOURCES)?;
        let command_buffer_begin_info = CommandBufferBeginInfo {
            flags: CommandBufferUsageFlags::ONE_TIME_SUBMIT,
            inheritance_info: None,
            chain: None,
        };
        commander.xfr_command_buffer.begin(&command_buffer_begin_info)?;
        let image_barrier = ImageMemoryBarrier {
            src_access_mask: AccessFlags::empty(),
            dst_access_mask: AccessFlags::TRANSFER_WRITE,
            old_layout: ImageLayout::Undefined,
            new_layout: ImageLayout::TransferDstOptimal,
            src_queue_family_index: QueueFamilyIndex::Ignored,
            dst_queue_family_index: QueueFamilyIndex::Ignored,
            image: self.image.clone(),
            subresource_range: ImageSubresourceRange {
                aspect_mask: if self.image_wrap_type == ImageWrapType::Depth {
                    ImageAspectFlags::DEPTH
                } else {
                    ImageAspectFlags::COLOR
                },
                base_mip_level: 0,
                level_count: OptionalMipLevels::MipLevels(self.mip_levels),
                base_array_layer: 0,
                layer_count: match self.image_wrap_type {
                    ImageWrapType::Cubemap => OptionalArrayLayers::ArrayLayers(6),
                    _ => OptionalArrayLayers::ArrayLayers(1),
                }
            },
            chain: None,
        };
        commander.xfr_command_buffer.pipeline_barrier(
            PipelineStageFlags::TRANSFER,
            PipelineStageFlags::TRANSFER,
            DependencyFlags::empty(),
            None,
            None,
            Some(&[image_barrier]));
        let mut buffer_copy_regions = Vec::new();
        let mut buffer_offset: u32 = 0;
        let mut thissize = main_texture_size;
        let mut image_extent = self.extent;
        for mip in 0..self.mip_levels {
            buffer_copy_regions.push( BufferImageCopy {
                buffer_offset: buffer_offset as u64,
                // 0 means 'tightly packed' according to image_extent,
                buffer_row_length: 0,
                // 0 means 'tightly packed' according to image_extent,
                buffer_image_height: 0,
                image_subresource: ImageSubresourceLayers {
                    aspect_mask: if self.image_wrap_type == ImageWrapType::Depth {
                        ImageAspectFlags::DEPTH
                    } else {
                        ImageAspectFlags::COLOR
                    },
                    mip_level: mip,
                    base_array_layer: 0,
                    layer_count: match self.image_wrap_type {
                        ImageWrapType::Cubemap => 6,
                        _ => 1,
                    },
                },
                image_offset: Offset3D {
                    x: 0,
                    y: 0,
                    z: 0
                },
                image_extent: image_extent,
            });
            buffer_offset += thissize;
            thissize /= 4;
            if thissize < min_mipmap_size {
                thissize = min_mipmap_size;
            }
            image_extent.width /= 2;
            image_extent.height /= 2;
        }
        commander.xfr_command_buffer.copy_buffer_to_image(
            buffer, //src_buffer
            &self.image, // dst_image
            ImageLayout::TransferDstOptimal, // dst_image_layout
            &*buffer_copy_regions, // regions
        );
        commander.xfr_command_buffer.end()?;
        let fence = {
            let create_info = FenceCreateInfo {
                flags: FenceCreateFlags::empty(),
                chain: None
            };
            device.create_fence(&create_info, None)?
        };
        // or fence.reset()?; if we take one as a parameter
        // submit the command buffer
        let submit_info = SubmitInfo {
            wait_semaphores: vec![],
            wait_dst_stage_mask: vec![PipelineStageFlags::TOP_OF_PIPE],
            command_buffers: vec![commander.xfr_command_buffer.clone()],
            signal_semaphores: vec![],
            chain: None,
        };
        commander.xfr_queue.submit(Some(&[submit_info]), Some(&fence))?;
        let _success = fence.wait_for(Timeout::Infinite)?;
        Ok(())
    }
pub fn copy_in_from_buffer ( & mut self , device : & Device , commander : & Commander , buffer : & Buffer , main_texture_size : u32 , min_mipmap_size : u32 ) -> Result < ( ) , Error > { use dacite :: core :: { CommandBufferBeginInfo , CommandBufferUsageFlags , CommandBufferResetFlags , ImageMemoryBarrier , QueueFamilyIndex , DependencyFlags , FenceCreateInfo , FenceCreateFlags , SubmitInfo , Timeout , ImageAspectFlags , OptionalMipLevels , OptionalArrayLayers , BufferImageCopy , ImageSubresourceLayers , Offset3D } ; commander . xfr_command_buffer . reset ( CommandBufferResetFlags :: RELEASE_RESOURCES ) ? ; let command_buffer_begin_info = CommandBufferBeginInfo { flags : CommandBufferUsageFlags :: ONE_TIME_SUBMIT , inheritance_info : None , chain : None , } ; commander . xfr_command_buffer . begin ( & command_buffer_begin_info ) ? ; let image_barrier = ImageMemoryBarrier { src_access_mask : AccessFlags :: empty ( ) , dst_access_mask : AccessFlags :: TRANSFER_WRITE , old_layout : ImageLayout :: Undefined , new_layout : ImageLayout :: TransferDstOptimal , src_queue_family_index : QueueFamilyIndex :: Ignored , dst_queue_family_index : QueueFamilyIndex :: Ignored , image : self . image . clone ( ) , subresource_range : ImageSubresourceRange { aspect_mask : if self . image_wrap_type == ImageWrapType :: Depth { ImageAspectFlags :: DEPTH } else { ImageAspectFlags :: COLOR } , base_mip_level : 0 , level_count : OptionalMipLevels :: MipLevels ( self . mip_levels ) , base_array_layer : 0 , layer_count : match self . image_wrap_type { ImageWrapType :: Cubemap => OptionalArrayLayers :: ArrayLayers ( 6 ) , _ => OptionalArrayLayers :: ArrayLayers ( 1 ) , } } , chain : None , } ; commander . xfr_command_buffer . pipeline_barrier ( PipelineStageFlags :: TRANSFER , PipelineStageFlags :: TRANSFER , DependencyFlags :: empty ( ) , None , None , Some ( & [ image_barrier ] ) ) ; let mut buffer_copy_regions = Vec :: new ( ) ; let mut buffer_offset : u32 = 0 ; let mut thissize = main_texture_size ; let mut image_extent = self . extent ; for mip in 0 .. self . mip_levels { buffer_copy_regions . push ( BufferImageCopy { buffer_offset : buffer_offset as u64 , // 0 means 'tightly packed' according to image_extent, buffer_row_length : 0 , // 0 means 'tightly packed' according to image_extent, buffer_image_height : 0 , image_subresource : ImageSubresourceLayers { aspect_mask : if self . image_wrap_type == ImageWrapType :: Depth { ImageAspectFlags :: DEPTH } else { ImageAspectFlags :: COLOR } , mip_level : mip , base_array_layer : 0 , layer_count : match self . image_wrap_type { ImageWrapType :: Cubemap => 6 , _ => 1 , } , } , image_offset : Offset3D { x : 0 , y : 0 , z : 0 } , image_extent : image_extent , } ) ; buffer_offset += thissize ; thissize /= 4 ; if thissize < min_mipmap_size { thissize = min_mipmap_size ; } image_extent . width /= 2 ; image_extent . height /= 2 ; } commander . xfr_command_buffer . copy_buffer_to_image ( buffer , //src_buffer & self . image , // dst_image ImageLayout :: TransferDstOptimal , // dst_image_layout & * buffer_copy_regions , // regions ) ; commander . xfr_command_buffer . end ( ) ? ; let fence = { let create_info = FenceCreateInfo { flags : FenceCreateFlags :: empty ( ) , chain : None } ; device . create_fence ( & create_info , None ) ? } ; // or fence.reset()?; if we take one as a parameter // submit the command buffer let submit_info = SubmitInfo { wait_semaphores : vec ! [ ] , wait_dst_stage_mask : vec ! [ PipelineStageFlags TOP_OF_PIPE ] , command_buffers : vec ! [ commander xfr_command_buffer clone ( ) ] , signal_semaphores : vec ! [ ] , chain : None , } ; commander . xfr_queue . submit ( Some ( & [ submit_info ] ) , Some ( & fence ) ) ? ; let _success = fence . wait_for ( Timeout :: Infinite ) ? ; Ok ( ( ) ) }
Currently this copies the entire buffer to an entire image;
we could improve it by coping regions/extents.
Currently this copies the entire buffer to an entire image ; we could improve it by coping regions / extents .
&mut self
device
&Device
commander
&Commander
buffer
&Buffer
main_texture_size
u32
min_mipmap_size
u32