fast image operations
Diffstat (limited to 'src/wgpu_convert.rs')
| -rw-r--r-- | src/wgpu_convert.rs | 105 |
1 files changed, 0 insertions, 105 deletions
diff --git a/src/wgpu_convert.rs b/src/wgpu_convert.rs deleted file mode 100644 index 1c668ce..0000000 --- a/src/wgpu_convert.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::num::NonZeroU32; - -use wgpu::{util::*, *}; - -use crate::Image; - -impl<T, const N: usize> Image<T, N> { - /// Get the size as a [`wgpu::Extend3d`]. - pub fn wgpu_size(&self) -> Extent3d { - Extent3d { - width: self.width(), - height: self.height(), - depth_or_array_layers: 1, - } - } -} - -impl<T: AsRef<[u8]>> Image<T, 4> { - /// Upload this image to the gpu, returning a [`wgpu::Texture`]. - pub fn send(&self, dev: &Device, q: &Queue, usage: TextureUsages) -> Texture { - dev.create_texture_with_data( - &q, - &TextureDescriptor { - label: None, - size: self.wgpu_size(), - mip_level_count: 1, - sample_count: 1, - dimension: TextureDimension::D2, - format: TextureFormat::Rgba8Unorm, - view_formats: &[], - usage, - }, - util::TextureDataOrder::LayerMajor, - self.bytes(), - ) - } -} - -impl Image<Box<[u8]>, 4> { - /// Downloads a purportedly [`TextureFormat::Rgba8Unorm`] image from the gpu. - /// # Panics - /// - /// When a "error occurs while trying to async map a buffer". - pub fn download( - dev: &Device, - q: &Queue, - texture: &Texture, - (width, height): (NonZeroU32, NonZeroU32), - ) -> Self { - let mut encoder = dev.create_command_encoder(&CommandEncoderDescriptor { label: None }); - let texture_size = Extent3d { - width: width.get(), - height: height.get(), - depth_or_array_layers: 1, - }; - - let row = width.get() as usize * 4; - let pad = { - let padding = (256 - row % 256) % 256; - row + padding - }; - - let output_buffer = dev.create_buffer(&BufferDescriptor { - label: None, - size: pad as u64 * height.get() as u64, - usage: BufferUsages::COPY_DST | BufferUsages::MAP_READ, - mapped_at_creation: false, - }); - - encoder.copy_texture_to_buffer( - wgpu::ImageCopyTexture { - aspect: wgpu::TextureAspect::All, - texture, - mip_level: 0, - origin: wgpu::Origin3d::ZERO, - }, - wgpu::ImageCopyBuffer { - buffer: &output_buffer, - layout: wgpu::ImageDataLayout { - offset: 0, - bytes_per_row: Some(pad as u32), - rows_per_image: Some(height.get()), - }, - }, - texture_size, - ); - q.submit(Some(encoder.finish())); - - let buffer_slice = output_buffer.slice(..); - buffer_slice.map_async(wgpu::MapMode::Read, Result::unwrap); - - dev.poll(wgpu::Maintain::Wait); - - let mut out = crate::uninit::Image::<_, 4>::new(width, height); - for (padded, pixels) in buffer_slice - .get_mapped_range() - .chunks_exact(pad) - .zip(out.buf().chunks_exact_mut(row)) - { - ::core::mem::MaybeUninit::copy_from_slice(pixels, &padded[..row]); - } - - unsafe { out.assume_init().boxed() } - } -} |