mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 04:31: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,
|
||||
};
|
||||
|
||||
/// 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_FULL_SIZE: u64 = 20;
|
||||
const PATH_BBOX_SIZE: u64 = 24;
|
||||
|
@ -157,12 +185,49 @@ pub fn render_full(
|
|||
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(
|
||||
encoding: &Encoding,
|
||||
shaders: &FullShaders,
|
||||
width: u32,
|
||||
height: u32,
|
||||
) -> (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};
|
||||
let mut recording = Recording::default();
|
||||
let mut resources = ResourceCache::new();
|
||||
|
@ -196,10 +261,10 @@ pub fn render_encoding_full(
|
|||
height_in_tiles: new_height / 16,
|
||||
target_width: width,
|
||||
target_height: height,
|
||||
binning_size: ((1 << 20) / 4) - info_size,
|
||||
tiles_size: (1 << 24) / TILE_SIZE as u32,
|
||||
segments_size: (1 << 26) / SEGMENT_SIZE as u32,
|
||||
ptcl_size: (1 << 25) / 4,
|
||||
binning_size: self.binning_info_size - info_size,
|
||||
tiles_size: self.tiles_size,
|
||||
segments_size: self.segments_size,
|
||||
ptcl_size: self.ptcl_size,
|
||||
layout: packed.layout,
|
||||
};
|
||||
// println!("{:?}", config);
|
||||
|
@ -274,7 +339,8 @@ pub fn render_encoding_full(
|
|||
recording.free_resource(reduced_scan);
|
||||
}
|
||||
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(
|
||||
shaders.bbox_clear,
|
||||
(drawobj_wgs, 1, 1),
|
||||
|
@ -319,7 +385,8 @@ pub fn render_encoding_full(
|
|||
],
|
||||
);
|
||||
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(
|
||||
(n_clip / shaders::CLIP_REDUCE_WG) as u64 * CLIP_BIC_SIZE,
|
||||
"clip_bic_buf",
|
||||
|
@ -358,7 +425,8 @@ pub fn render_encoding_full(
|
|||
recording.free_resource(clip_inp_buf);
|
||||
recording.free_resource(clip_bic_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 width_in_bins = (config.width_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(bin_header_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);
|
||||
recording.dispatch(
|
||||
shaders.fine,
|
||||
(config.width_in_tiles, config.height_in_tiles, 1),
|
||||
[
|
||||
self.width_in_tiles = config.width_in_tiles;
|
||||
self.height_in_tiles = config.height_in_tiles;
|
||||
self.fine = Some(FineResources {
|
||||
config_buf,
|
||||
bump_buf,
|
||||
tile_buf,
|
||||
segments_buf,
|
||||
ResourceProxy::Image(out_image),
|
||||
ptcl_buf,
|
||||
gradient_image,
|
||||
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(tile_buf);
|
||||
recording.free_resource(segments_buf);
|
||||
recording.free_resource(ptcl_buf);
|
||||
recording.free_resource(gradient_image);
|
||||
recording.free_resource(info_bin_data_buf);
|
||||
(recording, ResourceProxy::Image(out_image))
|
||||
}
|
||||
recording.free_resource(fine.config_buf);
|
||||
recording.free_resource(fine.tile_buf);
|
||||
recording.free_resource(fine.segments_buf);
|
||||
recording.free_resource(fine.ptcl_buf);
|
||||
recording.free_resource(fine.gradient_image);
|
||||
recording.free_resource(fine.info_bin_data_buf);
|
||||
}
|
||||
|
||||
pub fn align_up(len: usize, alignment: u32) -> usize {
|
||||
len + (len.wrapping_neg() & (alignment as usize - 1))
|
||||
/// Get the output image.
|
||||
///
|
||||
/// 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