fn load_image_with_staging_initialization(
    &self, pixels: impl ImageData, magnification_filter: MagnificationMinificationFilter,
    minification_filter: MagnificationMinificationFilter, address_u: TextureAddressMode,
    address_v: TextureAddressMode, address_w: TextureAddressMode, mip_levels: u32,
  ) -> SarektResult<ResourceWithMemory> {
    if mip_levels < 1 {
      return Err(SarektError::IllegalMipmapCount);
    }

    let dimens = pixels.dimensions();

    let (pixel_bytes, format) = {
      let format = pixels.format()?.into();
      let format_suitable = unsafe {
        self
          .instance
          .get_physical_device_format_properties(self.physical_device, format)
          .optimal_tiling_features
          .contains(vk::FormatFeatureFlags::SAMPLED_IMAGE)
      };

      if !format_suitable {
        // Format not usable for a sampled image, convert to one garunteed by vulkan
        warn!(
          "Using an image with unsupported format: {:?}, converting to rgba, consider baking a \
           new texture",
          format
        );
        let pixels = pixels.into_rgba8();
        let format = pixels.format()?.into();
        (pixels.into_bytes(), format)
      } else {
        let format = pixels.format()?.into();
        (pixels.into_bytes(), format)
      }
    };

    info!(
      "Loading image with dimensions {:?}, and {} bytes",
      dimens,
      pixel_bytes.len()
    );

    let (staging_buffer, staging_allocation, _) =
      self.create_staging_buffer(pixel_bytes.len() as u64)?;

    let data = self.allocator.map_memory(&staging_allocation)?;
    unsafe {
      data.copy_from_nonoverlapping(pixel_bytes.as_ptr() as *const u8, pixel_bytes.len());
    }
    self.allocator.unmap_memory(&staging_allocation)?;

    // Only need to be a transfer source if blitting to itself when creating
    // mipmaps.
    let transfer_src_flag = if mip_levels > 1 {
      vk::ImageUsageFlags::TRANSFER_SRC
    } else {
      vk::ImageUsageFlags::empty()
    };
    let (image, image_allocation, _) = self.create_gpu_image(
      dimens,
      format,
      vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::SAMPLED | transfer_src_flag,
      self.transfer_queue_family,
      mip_levels,
      NumSamples::One,
    )?;

    let extent = vk::Extent3D {
      width: dimens.0,
      height: dimens.1,
      depth: 1,
    };
    self.transfer_staging_to_gpu_buffer_or_image(
      pixel_bytes.len() as u64,
      staging_buffer,
      ImageOrBuffer::Image(image, format, extent),
      Some(mip_levels),
    )?;

    info!("Destroying staging buffer and memory...");
    self
      .allocator
      .destroy_buffer(staging_buffer, &staging_allocation)?;

    // TODO(issue#29) IMAGES propogate up this parameter to allow users to create
    // stencil etc, this will involve a Sarekt non vulkan enum in
    // buffers_and_images.
    let image_view = self.create_image_view(
      image,
      format.into(),
      vk::ImageAspectFlags::COLOR,
      mip_levels,
    )?;
    let sampler = self.create_sampler(
      magnification_filter,
      minification_filter,
      address_u,
      address_v,
      address_w,
      mip_levels,
    )?;

    Ok(ResourceWithMemory::Image(ImageAndMemory {
      allocation: image_allocation,
      image_and_view: unsafe { ImageAndView::new(image, image_view) },
      sampler: Some(sampler),
    }))
  }
/// The procedure for loading an image in vulkan could use a staging image,
/// but its just as well we use a staging buffer, which is easier and [could even be faster](https://developer.nvidia.com/vulkan-memory-management)
/// TODO(issue#18) IMAGES MIPMAPPING
The procedure for loading an image in vulkan could use a staging image,
but its just as well we use a staging buffer, which is easier and [could even be faster]
TODO(issue#18) IMAGES MIPMAPPING
The procedure for loading an image in vulkan could use a staging image but its just as well we use a staging buffer which is easier and [ could even be faster ] TODO ( issue#18 ) IMAGES MIPMAPPING
fn load_image_with_staging_initialization(
    &self, pixels: impl ImageData, magnification_filter: MagnificationMinificationFilter,
    minification_filter: MagnificationMinificationFilter, address_u: TextureAddressMode,
    address_v: TextureAddressMode, address_w: TextureAddressMode, mip_levels: u32,
  ) -> SarektResult<ResourceWithMemory> {
    if mip_levels < 1 {
      return Err(SarektError::IllegalMipmapCount);
    }
    let dimens = pixels.dimensions();
    let (pixel_bytes, format) = {
      let format = pixels.format()?.into();
      let format_suitable = unsafe {
        self
          .instance
          .get_physical_device_format_properties(self.physical_device, format)
          .optimal_tiling_features
          .contains(vk::FormatFeatureFlags::SAMPLED_IMAGE)
      };
      if !format_suitable {
        // Format not usable for a sampled image, convert to one garunteed by vulkan
        warn!(
          "Using an image with unsupported format: {:?}, converting to rgba, consider baking a \
           new texture",
          format
        );
        let pixels = pixels.into_rgba8();
        let format = pixels.format()?.into();
        (pixels.into_bytes(), format)
      } else {
        let format = pixels.format()?.into();
        (pixels.into_bytes(), format)
      }
    };
    info!(
      "Loading image with dimensions {:?}, and {} bytes",
      dimens,
      pixel_bytes.len()
    );
    let (staging_buffer, staging_allocation, _) =
      self.create_staging_buffer(pixel_bytes.len() as u64)?;
    let data = self.allocator.map_memory(&staging_allocation)?;
    unsafe {
      data.copy_from_nonoverlapping(pixel_bytes.as_ptr() as *const u8, pixel_bytes.len());
    }
    self.allocator.unmap_memory(&staging_allocation)?;
    // Only need to be a transfer source if blitting to itself when creating
    // mipmaps.
    let transfer_src_flag = if mip_levels > 1 {
      vk::ImageUsageFlags::TRANSFER_SRC
    } else {
      vk::ImageUsageFlags::empty()
    };
    let (image, image_allocation, _) = self.create_gpu_image(
      dimens,
      format,
      vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::SAMPLED | transfer_src_flag,
      self.transfer_queue_family,
      mip_levels,
      NumSamples::One,
    )?;
    let extent = vk::Extent3D {
      width: dimens.0,
      height: dimens.1,
      depth: 1,
    };
    self.transfer_staging_to_gpu_buffer_or_image(
      pixel_bytes.len() as u64,
      staging_buffer,
      ImageOrBuffer::Image(image, format, extent),
      Some(mip_levels),
    )?;
    info!("Destroying staging buffer and memory...");
    self
      .allocator
      .destroy_buffer(staging_buffer, &staging_allocation)?;
    // TODO(issue#29) IMAGES propogate up this parameter to allow users to create
    // stencil etc, this will involve a Sarekt non vulkan enum in
    // buffers_and_images.
    let image_view = self.create_image_view(
      image,
      format.into(),
      vk::ImageAspectFlags::COLOR,
      mip_levels,
    )?;
    let sampler = self.create_sampler(
      magnification_filter,
      minification_filter,
      address_u,
      address_v,
      address_w,
      mip_levels,
    )?;
    Ok(ResourceWithMemory::Image(ImageAndMemory {
      allocation: image_allocation,
      image_and_view: unsafe { ImageAndView::new(image, image_view) },
      sampler: Some(sampler),
    }))
  }
fn load_image_with_staging_initialization ( & self , pixels : impl ImageData , magnification_filter : MagnificationMinificationFilter , minification_filter : MagnificationMinificationFilter , address_u : TextureAddressMode , address_v : TextureAddressMode , address_w : TextureAddressMode , mip_levels : u32 , ) -> SarektResult < ResourceWithMemory > { if mip_levels < 1 { return Err ( SarektError :: IllegalMipmapCount ) ; } let dimens = pixels . dimensions ( ) ; let ( pixel_bytes , format ) = { let format = pixels . format ( ) ? . into ( ) ; let format_suitable = unsafe { self . instance . get_physical_device_format_properties ( self . physical_device , format ) . optimal_tiling_features . contains ( vk :: FormatFeatureFlags :: SAMPLED_IMAGE ) } ; if ! format_suitable { // Format not usable for a sampled image, convert to one garunteed by vulkan warn ! ( " \
 " format ) ; let pixels = pixels . into_rgba8 ( ) ; let format = pixels . format ( ) ? . into ( ) ; ( pixels . into_bytes ( ) , format ) } else { let format = pixels . format ( ) ? . into ( ) ; ( pixels . into_bytes ( ) , format ) } } ; info ! ( " " dimens pixel_bytes len ( ) ) ; let ( staging_buffer , staging_allocation , _ ) = self . create_staging_buffer ( pixel_bytes . len ( ) as u64 ) ? ; let data = self . allocator . map_memory ( & staging_allocation ) ? ; unsafe { data . copy_from_nonoverlapping ( pixel_bytes . as_ptr ( ) as * const u8 , pixel_bytes . len ( ) ) ; } self . allocator . unmap_memory ( & staging_allocation ) ? ; // Only need to be a transfer source if blitting to itself when creating // mipmaps. let transfer_src_flag = if mip_levels > 1 { vk :: ImageUsageFlags :: TRANSFER_SRC } else { vk :: ImageUsageFlags :: empty ( ) } ; let ( image , image_allocation , _ ) = self . create_gpu_image ( dimens , format , vk :: ImageUsageFlags :: TRANSFER_DST | vk :: ImageUsageFlags :: SAMPLED | transfer_src_flag , self . transfer_queue_family , mip_levels , NumSamples :: One , ) ? ; let extent = vk :: Extent3D { width : dimens . 0 , height : dimens . 1 , depth : 1 , } ; self . transfer_staging_to_gpu_buffer_or_image ( pixel_bytes . len ( ) as u64 , staging_buffer , ImageOrBuffer :: Image ( image , format , extent ) , Some ( mip_levels ) , ) ? ; info ! ( " " ) ; self . allocator . destroy_buffer ( staging_buffer , & staging_allocation ) ? ; // TODO(issue#29) IMAGES propogate up this parameter to allow users to create // stencil etc, this will involve a Sarekt non vulkan enum in // buffers_and_images. let image_view = self . create_image_view ( image , format . into ( ) , vk :: ImageAspectFlags :: COLOR , mip_levels , ) ? ; let sampler = self . create_sampler ( magnification_filter , minification_filter , address_u , address_v , address_w , mip_levels , ) ? ; Ok ( ResourceWithMemory :: Image ( ImageAndMemory { allocation : image_allocation , image_and_view : unsafe { ImageAndView :: new ( image , image_view ) } , sampler : Some ( sampler ) , } ) ) }
The procedure for loading an image in vulkan could use a staging image,
but its just as well we use a staging buffer, which is easier and [could even be faster](https://developer.nvidia.com/vulkan-memory-management)
TODO(issue#18) IMAGES MIPMAPPING
The procedure for loading an image in vulkan could use a staging image but its just as well we use a staging buffer which is easier and [ could even be faster ] ( https : // developer . nvidia . com / vulkan - memory - management ) TODO ( issue#18 ) IMAGES MIPMAPPING
&self
pixels
impl ImageData
magnification_filter
MagnificationMinificationFilter
minification_filter
MagnificationMinificationFilter
address_u
TextureAddressMode
address_v
TextureAddressMode
address_w
TextureAddressMode
mip_levels
u32
&self
pixels
impl ImageData
magnification_filter
MagnificationMinificationFilter
minification_filter
MagnificationMinificationFilter
address_u
TextureAddressMode
address_v
TextureAddressMode
address_w
TextureAddressMode
mip_levels
u32