mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
Fix handling of wgpu to hopefully be valid
This commit is contained in:
parent
d366151970
commit
3a63f00e7e
|
@ -15,3 +15,4 @@ wgpu = { workspace = true }
|
||||||
pollster = "0.2.5"
|
pollster = "0.2.5"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
png = "0.17.7"
|
png = "0.17.7"
|
||||||
|
futures-intrusive = "0.5.0"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
|
fs::File,
|
||||||
num::NonZeroU32,
|
num::NonZeroU32,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
@ -7,6 +8,7 @@ use anyhow::{anyhow, bail, Context, Result};
|
||||||
use clap::{CommandFactory, Parser};
|
use clap::{CommandFactory, Parser};
|
||||||
use scenes::{SceneParams, SceneSet, SimpleText};
|
use scenes::{SceneParams, SceneSet, SimpleText};
|
||||||
use vello::{
|
use vello::{
|
||||||
|
block_on_wgpu,
|
||||||
kurbo::{Affine, Vec2},
|
kurbo::{Affine, Vec2},
|
||||||
Scene, SceneBuilder, SceneFragment,
|
Scene, SceneBuilder, SceneFragment,
|
||||||
};
|
};
|
||||||
|
@ -156,14 +158,14 @@ async fn render(mut scenes: SceneSet, index: usize, args: &Args) -> Result<()> {
|
||||||
.render_to_texture(&device, &queue, &scene, &view, width, height)
|
.render_to_texture(&device, &queue, &scene, &view, width, height)
|
||||||
.or_else(|_| bail!("Got non-Send/Sync error from rendering"))?;
|
.or_else(|_| bail!("Got non-Send/Sync error from rendering"))?;
|
||||||
// (width * 4).next_multiple_of(256)
|
// (width * 4).next_multiple_of(256)
|
||||||
let padded_width = {
|
let padded_byte_width = {
|
||||||
let w = width as u32 * 4;
|
let w = width as u32 * 4;
|
||||||
match w % 256 {
|
match w % 256 {
|
||||||
0 => w,
|
0 => w,
|
||||||
r => w + (256 - r),
|
r => w + (256 - r),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let buffer_size = padded_width as u64 * height as u64;
|
let buffer_size = padded_byte_width as u64 * height as u64;
|
||||||
let buffer = device.create_buffer(&BufferDescriptor {
|
let buffer = device.create_buffer(&BufferDescriptor {
|
||||||
label: Some("val"),
|
label: Some("val"),
|
||||||
size: buffer_size,
|
size: buffer_size,
|
||||||
|
@ -179,7 +181,7 @@ async fn render(mut scenes: SceneSet, index: usize, args: &Args) -> Result<()> {
|
||||||
buffer: &buffer,
|
buffer: &buffer,
|
||||||
layout: wgpu::ImageDataLayout {
|
layout: wgpu::ImageDataLayout {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
bytes_per_row: NonZeroU32::new(padded_width),
|
bytes_per_row: NonZeroU32::new(padded_byte_width),
|
||||||
rows_per_image: None,
|
rows_per_image: None,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -187,22 +189,33 @@ async fn render(mut scenes: SceneSet, index: usize, args: &Args) -> Result<()> {
|
||||||
);
|
);
|
||||||
queue.submit([encoder.finish()]);
|
queue.submit([encoder.finish()]);
|
||||||
let buf_slice = buffer.slice(..);
|
let buf_slice = buffer.slice(..);
|
||||||
buf_slice.map_async(wgpu::MapMode::Read, |done| done.unwrap());
|
|
||||||
device.poll(wgpu::MaintainBase::Wait);
|
let (sender, receiver) = futures_intrusive::channel::shared::oneshot_channel();
|
||||||
|
buf_slice.map_async(wgpu::MapMode::Read, move |v| sender.send(v).unwrap());
|
||||||
|
if let Some(recv_result) = block_on_wgpu(&device, receiver.receive()) {
|
||||||
|
recv_result?;
|
||||||
|
} else {
|
||||||
|
bail!("channel was closed");
|
||||||
|
}
|
||||||
|
|
||||||
let data = buf_slice.get_mapped_range();
|
let data = buf_slice.get_mapped_range();
|
||||||
let mut result = Vec::<u8>::new();
|
let mut result_unpadded = Vec::<u8>::with_capacity((width * height * 4).try_into()?);
|
||||||
let mut encoder = png::Encoder::new(&mut result, padded_width / 4, height);
|
for row in 0..height {
|
||||||
encoder.set_color(png::ColorType::Rgba);
|
let start = (row * padded_byte_width).try_into()?;
|
||||||
encoder.set_depth(png::BitDepth::Eight);
|
result_unpadded.extend(&data[start..start + (width * 4) as usize]);
|
||||||
let mut writer = encoder.write_header()?;
|
}
|
||||||
writer.write_image_data(&data)?;
|
|
||||||
writer.finish()?;
|
|
||||||
let out_path = args
|
let out_path = args
|
||||||
.out_directory
|
.out_directory
|
||||||
.join(&example_scene.config.name)
|
.join(&example_scene.config.name)
|
||||||
.with_extension("png");
|
.with_extension("png");
|
||||||
std::fs::write(&out_path, result)?;
|
let mut file = File::create(&out_path)?;
|
||||||
println!("Wrote result to {out_path:?}");
|
let mut encoder = png::Encoder::new(&mut file, width, height);
|
||||||
|
encoder.set_color(png::ColorType::Rgba);
|
||||||
|
encoder.set_depth(png::BitDepth::Eight);
|
||||||
|
let mut writer = encoder.write_header()?;
|
||||||
|
writer.write_image_data(&result_unpadded)?;
|
||||||
|
writer.finish()?;
|
||||||
|
println!("Wrote result ({width}x{height}) to {out_path:?}");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue