mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
Create Render struct
Separate coarse and fine stages as separate methods of Render struct.
This commit is contained in:
parent
e47c5777cc
commit
17907893af
137
src/render.rs
137
src/render.rs
|
@ -9,6 +9,34 @@ use crate::{
|
||||||
Scene,
|
Scene,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// State for a render in progress.
|
||||||
|
pub struct Render {
|
||||||
|
/// Size of binning and info combined buffer in u32 units
|
||||||
|
binning_info_size: u32,
|
||||||
|
/// Size of tiles buf in tiles
|
||||||
|
tiles_size: u32,
|
||||||
|
/// Size of segments buf in segments
|
||||||
|
segments_size: u32,
|
||||||
|
/// Size of per-tile command list in u32 units
|
||||||
|
ptcl_size: u32,
|
||||||
|
width_in_tiles: u32,
|
||||||
|
height_in_tiles: u32,
|
||||||
|
fine: Option<FineResources>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resources produced by pipeline, needed for fine rasterization.
|
||||||
|
struct FineResources {
|
||||||
|
config_buf: ResourceProxy,
|
||||||
|
bump_buf: ResourceProxy,
|
||||||
|
tile_buf: ResourceProxy,
|
||||||
|
segments_buf: ResourceProxy,
|
||||||
|
ptcl_buf: ResourceProxy,
|
||||||
|
gradient_image: ResourceProxy,
|
||||||
|
info_bin_data_buf: ResourceProxy,
|
||||||
|
|
||||||
|
out_image: ImageProxy,
|
||||||
|
}
|
||||||
|
|
||||||
const TAG_MONOID_SIZE: u64 = 12;
|
const TAG_MONOID_SIZE: u64 = 12;
|
||||||
const TAG_MONOID_FULL_SIZE: u64 = 20;
|
const TAG_MONOID_FULL_SIZE: u64 = 20;
|
||||||
const PATH_BBOX_SIZE: u64 = 24;
|
const PATH_BBOX_SIZE: u64 = 24;
|
||||||
|
@ -157,12 +185,49 @@ pub fn render_full(
|
||||||
render_encoding_full(scene.data(), shaders, width, height)
|
render_encoding_full(scene.data(), shaders, width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a single recording with both coarse and fine render stages.
|
||||||
|
///
|
||||||
|
/// This function is not recommended when the scene can be complex, as it does not
|
||||||
|
/// implement robust dynamic memory.
|
||||||
pub fn render_encoding_full(
|
pub fn render_encoding_full(
|
||||||
encoding: &Encoding,
|
encoding: &Encoding,
|
||||||
shaders: &FullShaders,
|
shaders: &FullShaders,
|
||||||
width: u32,
|
width: u32,
|
||||||
height: u32,
|
height: u32,
|
||||||
) -> (Recording, ResourceProxy) {
|
) -> (Recording, ResourceProxy) {
|
||||||
|
let mut render = Render::new();
|
||||||
|
let mut recording = render.render_encoding_coarse(encoding, shaders, width, height);
|
||||||
|
let out_image = render.out_image();
|
||||||
|
render.record_fine(shaders, &mut recording);
|
||||||
|
(recording, out_image.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn align_up(len: usize, alignment: u32) -> usize {
|
||||||
|
len + (len.wrapping_neg() & (alignment as usize - 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
// These sizes are adequate for paris-30k but should probably be dialed down.
|
||||||
|
Render {
|
||||||
|
binning_info_size: (1 << 20) / 4,
|
||||||
|
tiles_size: (1 << 24) / TILE_SIZE as u32,
|
||||||
|
segments_size: (1 << 26) / SEGMENT_SIZE as u32,
|
||||||
|
ptcl_size: (1 << 25) / 4 as u32,
|
||||||
|
width_in_tiles: 0,
|
||||||
|
height_in_tiles: 0,
|
||||||
|
fine: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prepare a recording for the coarse rasterization phase.
|
||||||
|
pub fn render_encoding_coarse(
|
||||||
|
&mut self,
|
||||||
|
encoding: &Encoding,
|
||||||
|
shaders: &FullShaders,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Recording {
|
||||||
use crate::encoding::{resource::ResourceCache, PackedEncoding};
|
use crate::encoding::{resource::ResourceCache, PackedEncoding};
|
||||||
let mut recording = Recording::default();
|
let mut recording = Recording::default();
|
||||||
let mut resources = ResourceCache::new();
|
let mut resources = ResourceCache::new();
|
||||||
|
@ -196,10 +261,10 @@ pub fn render_encoding_full(
|
||||||
height_in_tiles: new_height / 16,
|
height_in_tiles: new_height / 16,
|
||||||
target_width: width,
|
target_width: width,
|
||||||
target_height: height,
|
target_height: height,
|
||||||
binning_size: ((1 << 20) / 4) - info_size,
|
binning_size: self.binning_info_size - info_size,
|
||||||
tiles_size: (1 << 24) / TILE_SIZE as u32,
|
tiles_size: self.tiles_size,
|
||||||
segments_size: (1 << 26) / SEGMENT_SIZE as u32,
|
segments_size: self.segments_size,
|
||||||
ptcl_size: (1 << 25) / 4,
|
ptcl_size: self.ptcl_size,
|
||||||
layout: packed.layout,
|
layout: packed.layout,
|
||||||
};
|
};
|
||||||
// println!("{:?}", config);
|
// println!("{:?}", config);
|
||||||
|
@ -274,7 +339,8 @@ pub fn render_encoding_full(
|
||||||
recording.free_resource(reduced_scan);
|
recording.free_resource(reduced_scan);
|
||||||
}
|
}
|
||||||
let drawobj_wgs = (n_drawobj + shaders::PATH_BBOX_WG - 1) / shaders::PATH_BBOX_WG;
|
let drawobj_wgs = (n_drawobj + shaders::PATH_BBOX_WG - 1) / shaders::PATH_BBOX_WG;
|
||||||
let path_bbox_buf = ResourceProxy::new_buf(n_paths as u64 * PATH_BBOX_SIZE, "path_bbox_buf");
|
let path_bbox_buf =
|
||||||
|
ResourceProxy::new_buf(n_paths as u64 * PATH_BBOX_SIZE, "path_bbox_buf");
|
||||||
recording.dispatch(
|
recording.dispatch(
|
||||||
shaders.bbox_clear,
|
shaders.bbox_clear,
|
||||||
(drawobj_wgs, 1, 1),
|
(drawobj_wgs, 1, 1),
|
||||||
|
@ -319,7 +385,8 @@ pub fn render_encoding_full(
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
recording.free_resource(draw_reduced_buf);
|
recording.free_resource(draw_reduced_buf);
|
||||||
let clip_el_buf = ResourceProxy::new_buf(encoding.n_clips as u64 * CLIP_EL_SIZE, "clip_el_buf");
|
let clip_el_buf =
|
||||||
|
ResourceProxy::new_buf(encoding.n_clips as u64 * CLIP_EL_SIZE, "clip_el_buf");
|
||||||
let clip_bic_buf = ResourceProxy::new_buf(
|
let clip_bic_buf = ResourceProxy::new_buf(
|
||||||
(n_clip / shaders::CLIP_REDUCE_WG) as u64 * CLIP_BIC_SIZE,
|
(n_clip / shaders::CLIP_REDUCE_WG) as u64 * CLIP_BIC_SIZE,
|
||||||
"clip_bic_buf",
|
"clip_bic_buf",
|
||||||
|
@ -358,7 +425,8 @@ pub fn render_encoding_full(
|
||||||
recording.free_resource(clip_inp_buf);
|
recording.free_resource(clip_inp_buf);
|
||||||
recording.free_resource(clip_bic_buf);
|
recording.free_resource(clip_bic_buf);
|
||||||
recording.free_resource(clip_el_buf);
|
recording.free_resource(clip_el_buf);
|
||||||
let draw_bbox_buf = ResourceProxy::new_buf(n_paths as u64 * DRAW_BBOX_SIZE, "draw_bbox_buf");
|
let draw_bbox_buf =
|
||||||
|
ResourceProxy::new_buf(n_paths as u64 * DRAW_BBOX_SIZE, "draw_bbox_buf");
|
||||||
let bump_buf = BufProxy::new(BUMP_SIZE, "bump_buf");
|
let bump_buf = BufProxy::new(BUMP_SIZE, "bump_buf");
|
||||||
let width_in_bins = (config.width_in_tiles + 15) / 16;
|
let width_in_bins = (config.width_in_tiles + 15) / 16;
|
||||||
let height_in_bins = (config.height_in_tiles + 15) / 16;
|
let height_in_bins = (config.height_in_tiles + 15) / 16;
|
||||||
|
@ -443,31 +511,52 @@ pub fn render_encoding_full(
|
||||||
recording.free_resource(draw_monoid_buf);
|
recording.free_resource(draw_monoid_buf);
|
||||||
recording.free_resource(bin_header_buf);
|
recording.free_resource(bin_header_buf);
|
||||||
recording.free_resource(path_buf);
|
recording.free_resource(path_buf);
|
||||||
// TODO: bump_buf is special
|
|
||||||
recording.free_resource(bump_buf);
|
|
||||||
let out_image = ImageProxy::new(width, height, ImageFormat::Rgba8);
|
let out_image = ImageProxy::new(width, height, ImageFormat::Rgba8);
|
||||||
recording.dispatch(
|
self.width_in_tiles = config.width_in_tiles;
|
||||||
shaders.fine,
|
self.height_in_tiles = config.height_in_tiles;
|
||||||
(config.width_in_tiles, config.height_in_tiles, 1),
|
self.fine = Some(FineResources {
|
||||||
[
|
|
||||||
config_buf,
|
config_buf,
|
||||||
|
bump_buf,
|
||||||
tile_buf,
|
tile_buf,
|
||||||
segments_buf,
|
segments_buf,
|
||||||
ResourceProxy::Image(out_image),
|
|
||||||
ptcl_buf,
|
ptcl_buf,
|
||||||
gradient_image,
|
gradient_image,
|
||||||
info_bin_data_buf,
|
info_bin_data_buf,
|
||||||
|
out_image,
|
||||||
|
});
|
||||||
|
recording
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run fine rasterization assuming the coarse phase succeeded.
|
||||||
|
pub fn record_fine(&mut self, shaders: &FullShaders, recording: &mut Recording) {
|
||||||
|
let fine = self.fine.take().unwrap();
|
||||||
|
recording.free_resource(fine.bump_buf);
|
||||||
|
recording.dispatch(
|
||||||
|
shaders.fine,
|
||||||
|
(self.width_in_tiles, self.height_in_tiles, 1),
|
||||||
|
[
|
||||||
|
fine.config_buf,
|
||||||
|
fine.tile_buf,
|
||||||
|
fine.segments_buf,
|
||||||
|
ResourceProxy::Image(fine.out_image),
|
||||||
|
fine.ptcl_buf,
|
||||||
|
fine.gradient_image,
|
||||||
|
fine.info_bin_data_buf,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
recording.free_resource(config_buf);
|
recording.free_resource(fine.config_buf);
|
||||||
recording.free_resource(tile_buf);
|
recording.free_resource(fine.tile_buf);
|
||||||
recording.free_resource(segments_buf);
|
recording.free_resource(fine.segments_buf);
|
||||||
recording.free_resource(ptcl_buf);
|
recording.free_resource(fine.ptcl_buf);
|
||||||
recording.free_resource(gradient_image);
|
recording.free_resource(fine.gradient_image);
|
||||||
recording.free_resource(info_bin_data_buf);
|
recording.free_resource(fine.info_bin_data_buf);
|
||||||
(recording, ResourceProxy::Image(out_image))
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub fn align_up(len: usize, alignment: u32) -> usize {
|
/// Get the output image.
|
||||||
len + (len.wrapping_neg() & (alignment as usize - 1))
|
///
|
||||||
|
/// This is going away, as the caller will add the output image to the bind
|
||||||
|
/// map.
|
||||||
|
pub fn out_image(&self) -> ImageProxy {
|
||||||
|
self.fine.as_ref().unwrap().out_image
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue