From 306f96164784a8cbf405e72fa4364d6523366e95 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Mon, 5 May 2025 15:09:54 +0200 Subject: old dir --- old/vgcodec/src/export.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 old/vgcodec/src/export.rs (limited to 'old/vgcodec/src/export.rs') diff --git a/old/vgcodec/src/export.rs b/old/vgcodec/src/export.rs new file mode 100644 index 0000000..e020c5d --- /dev/null +++ b/old/vgcodec/src/export.rs @@ -0,0 +1,83 @@ +use crate::app::App; +use image::RgbaImage; +use std::{num::NonZeroU32, sync::Arc}; +use wgpu::{ + Buffer, Extent3d, ImageCopyBuffer, ImageCopyTexture, ImageDataLayout, Origin3d, Texture, +}; + +pub struct Exporter { + app: Arc, + size: Extent3d, + + padded_bytes_per_row: u32, + export_buffer: Buffer, +} + +impl Exporter { + pub fn new(app: &Arc, size: Extent3d) -> Self { + let App { device, .. } = app.as_ref(); + + let bytes_per_pixel = std::mem::size_of::() as u32; + let unpadded_bytes_per_row = size.width * bytes_per_pixel; + let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT; + let padded_bytes_per_row_padding = (align - unpadded_bytes_per_row % align) % align; + let padded_bytes_per_row = unpadded_bytes_per_row + padded_bytes_per_row_padding; + + let export_buffer_size = (padded_bytes_per_row * size.height) as u64; + let export_buffer = device.create_buffer(&wgpu::BufferDescriptor { + label: None, + size: export_buffer_size, + usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + Self { + padded_bytes_per_row, + app: app.clone(), + size, + export_buffer, + } + } + pub async fn run(&self, texture: &Texture, save_path: &str) { + let App { device, queue, .. } = self.app.as_ref(); + + let mut encoder = + device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + + encoder.copy_texture_to_buffer( + ImageCopyTexture { + texture, + aspect: wgpu::TextureAspect::All, + mip_level: 0, + origin: Origin3d::ZERO, + }, + ImageCopyBuffer { + buffer: &self.export_buffer, + layout: ImageDataLayout { + offset: 0, + bytes_per_row: Some(NonZeroU32::new(self.padded_bytes_per_row).unwrap()), + rows_per_image: None, + }, + }, + self.size, + ); + + queue.submit(Some(encoder.finish())); + + let buffer_slice = self.export_buffer.slice(..); + let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel(); + buffer_slice.map_async(wgpu::MapMode::Read, move |v| { + sender.send(v.unwrap()).unwrap() + }); + device.poll(wgpu::Maintain::Wait); + receiver.receive().await; + + let data = buffer_slice.get_mapped_range(); + let result: Vec = bytemuck::cast_slice(&data).to_vec(); + let image = RgbaImage::from_raw(self.size.width, self.size.height, result).unwrap(); + image.save(save_path).unwrap(); + + drop(data); + self.export_buffer.unmap(); + } +} -- cgit v1.2.3-70-g09d2