Allow arbitrary output sizes (#206)

* Support basic resizing

* Fix resizing
This commit is contained in:
Daniel McNab 2022-11-23 17:34:04 +00:00
parent 98e0499b31
commit 0755e8bfaa
2 changed files with 59 additions and 11 deletions

View file

@ -20,6 +20,7 @@ use std::{fs::File, io::BufWriter};
use engine::Engine; use engine::Engine;
use render::next_multiple_of;
use wgpu::{Device, Limits, Queue}; use wgpu::{Device, Limits, Queue};
mod debug; mod debug;
@ -30,7 +31,7 @@ mod render;
mod shaders; mod shaders;
mod test_scene; mod test_scene;
async fn run() -> Result<(), Box<dyn std::error::Error>> { async fn run(dimensions: &Dimensions) -> Result<(), Box<dyn std::error::Error>> {
let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY); let instance = wgpu::Instance::new(wgpu::Backends::PRIMARY);
let adapter = instance.request_adapter(&Default::default()).await.unwrap(); let adapter = instance.request_adapter(&Default::default()).await.unwrap();
let features = adapter.features(); let features = adapter.features();
@ -47,7 +48,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
) )
.await?; .await?;
let mut engine = Engine::new(); let mut engine = Engine::new();
do_render(&device, &queue, &mut engine).await?; do_render(&device, &queue, &mut engine, dimensions).await?;
Ok(()) Ok(())
} }
@ -69,6 +70,7 @@ async fn do_render(
device: &Device, device: &Device,
queue: &Queue, queue: &Queue,
engine: &mut Engine, engine: &mut Engine,
dimensions: &Dimensions,
) -> Result<(), Box<dyn std::error::Error>> { ) -> Result<(), Box<dyn std::error::Error>> {
#[allow(unused)] #[allow(unused)]
let shaders = shaders::init_shaders(device, engine)?; let shaders = shaders::init_shaders(device, engine)?;
@ -76,7 +78,7 @@ async fn do_render(
let scene = test_scene::gen_test_scene(); let scene = test_scene::gen_test_scene();
//test_scene::dump_scene_info(&scene); //test_scene::dump_scene_info(&scene);
//let (recording, buf) = render::render(&scene, &shaders); //let (recording, buf) = render::render(&scene, &shaders);
let (recording, buf) = render::render_full(&scene, &full_shaders); let (recording, buf) = render::render_full(&scene, &full_shaders, dimensions);
let downloads = engine.run_recording(&device, &queue, &recording)?; let downloads = engine.run_recording(&device, &queue, &recording)?;
let mapped = downloads.map(); let mapped = downloads.map();
device.poll(wgpu::Maintain::Wait); device.poll(wgpu::Maintain::Wait);
@ -87,14 +89,43 @@ async fn do_render(
} else { } else {
let file = File::create("image.png")?; let file = File::create("image.png")?;
let w = BufWriter::new(file); let w = BufWriter::new(file);
let mut encoder = png::Encoder::new(w, 1024, 1024); let mut encoder = png::Encoder::new(w, dimensions.width, dimensions.height);
encoder.set_color(png::ColorType::Rgba); encoder.set_color(png::ColorType::Rgba);
let mut writer = encoder.write_header()?; let mut writer = encoder.write_header()?;
let expected_size = (dimensions.width * dimensions.height * 4) as usize;
let new_width = next_multiple_of(dimensions.width, 16) as usize;
if expected_size == buf.len() {
writer.write_image_data(&buf)?; writer.write_image_data(&buf)?;
} else {
let mut output = Vec::<u8>::with_capacity(expected_size * 4);
for height in 0..(dimensions.height as usize) {
output.extend_from_slice(
&buf[height * new_width * 4..][..dimensions.width as usize * 4],
);
}
writer.write_image_data(&output)?;
}
} }
Ok(()) Ok(())
} }
fn main() { pub struct Dimensions {
pollster::block_on(run()).unwrap(); width: u32,
height: u32,
}
fn main() {
let mut args = std::env::args();
args.next();
let width = args
.next()
.and_then(|it| it.parse::<u32>().ok())
.unwrap_or(1024);
let height = args
.next()
.and_then(|it| it.parse::<u32>().ok())
.unwrap_or(1024);
pollster::block_on(run(&Dimensions { width, height })).unwrap();
} }

View file

@ -6,6 +6,7 @@ use piet_scene::Scene;
use crate::{ use crate::{
engine::{BufProxy, Recording, ResourceProxy}, engine::{BufProxy, Recording, ResourceProxy},
shaders::{self, FullShaders, Shaders}, shaders::{self, FullShaders, Shaders},
Dimensions,
}; };
const TAG_MONOID_SIZE: u64 = 12; const TAG_MONOID_SIZE: u64 = 12;
@ -52,7 +53,14 @@ fn size_to_words(byte_size: usize) -> u32 {
(byte_size / std::mem::size_of::<u32>()) as u32 (byte_size / std::mem::size_of::<u32>()) as u32
} }
pub fn render(scene: &Scene, shaders: &Shaders) -> (Recording, BufProxy) { pub const fn next_multiple_of(val: u32, rhs: u32) -> u32 {
match val % rhs {
0 => val,
r => val + (rhs - r),
}
}
fn render(scene: &Scene, shaders: &Shaders) -> (Recording, BufProxy) {
let mut recording = Recording::default(); let mut recording = Recording::default();
let data = scene.data(); let data = scene.data();
let n_pathtag = data.tag_stream.len(); let n_pathtag = data.tag_stream.len();
@ -125,7 +133,11 @@ pub fn render(scene: &Scene, shaders: &Shaders) -> (Recording, BufProxy) {
(recording, out_buf) (recording, out_buf)
} }
pub fn render_full(scene: &Scene, shaders: &FullShaders) -> (Recording, BufProxy) { pub fn render_full(
scene: &Scene,
shaders: &FullShaders,
dimensions: &Dimensions,
) -> (Recording, BufProxy) {
let mut recording = Recording::default(); let mut recording = Recording::default();
let mut ramps = crate::ramp::RampCache::default(); let mut ramps = crate::ramp::RampCache::default();
let mut drawdata_patches: Vec<(usize, u32)> = vec![]; let mut drawdata_patches: Vec<(usize, u32)> = vec![];
@ -192,9 +204,14 @@ pub fn render_full(scene: &Scene, shaders: &FullShaders) -> (Recording, BufProxy
// TODO: calculate for real when we do rectangles // TODO: calculate for real when we do rectangles
let n_drawobj = n_path; let n_drawobj = n_path;
let n_clip = data.n_clip; let n_clip = data.n_clip;
let new_width = next_multiple_of(dimensions.width, 16);
let new_height = next_multiple_of(dimensions.width, 16);
let config = Config { let config = Config {
width_in_tiles: 64, // TODO: Replace with div_ceil once stable
height_in_tiles: 64, width_in_tiles: new_width / 16,
height_in_tiles: new_height / 16,
n_drawobj, n_drawobj,
n_path, n_path,
n_clip, n_clip,