mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-09 20:31:29 +11:00
Support click and drag for svgs, as well as scene fragment caching (#244)
* Support caching the image, and click and drag motion * Remove debug print * Clean up examples to have command line parsing * Address review comments
This commit is contained in:
parent
02d8b28439
commit
eec111c633
148
Cargo.lock
generated
148
Cargo.lock
generated
|
@ -1014,6 +1014,43 @@ dependencies = [
|
|||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa91278560fc226a5d9d736cc21e485ff9aad47d26b8ffe1f54cba868b684b9f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
|
||||
dependencies = [
|
||||
"heck 0.4.0",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.49"
|
||||
|
@ -1422,6 +1459,27 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "euclid"
|
||||
version = "0.22.7"
|
||||
|
@ -1818,6 +1876,21 @@ dependencies = [
|
|||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
|
@ -1925,6 +1998,28 @@ dependencies = [
|
|||
"mach",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dfb6c8100ccc63462345b67d1bbc3679177c75ee4bf59bf29c8b1d110b8189"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
|
@ -2064,6 +2159,12 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
|
@ -2480,6 +2581,12 @@ version = "1.16.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
version = "0.1.1"
|
||||
|
@ -2617,6 +2724,30 @@ dependencies = [
|
|||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
|
@ -2785,6 +2916,20 @@ dependencies = [
|
|||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4feacf7db682c6c329c4ede12649cd36ecab0f3be5b7d74e6a20304725db4549"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
|
@ -3378,7 +3523,7 @@ version = "0.19.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"heck 0.3.3",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
|
@ -4038,6 +4183,7 @@ dependencies = [
|
|||
name = "with_winit"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
"pollster",
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[package]
|
||||
name = "with_winit"
|
||||
description = "An example using vello to render to a winit window"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
publish = false
|
||||
|
@ -13,6 +14,7 @@ winit = "0.27.5"
|
|||
pollster = "0.2.5"
|
||||
# for picosvg
|
||||
roxmltree = "0.13"
|
||||
clap = { version = "4.1.0", features = ["derive"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
console_error_panic_hook = "0.1.7"
|
||||
|
|
|
@ -18,10 +18,35 @@ mod pico_svg;
|
|||
mod simple_text;
|
||||
mod test_scene;
|
||||
|
||||
use vello::{util::RenderContext, Renderer, Scene, SceneBuilder};
|
||||
use std::{borrow::Cow, path::PathBuf};
|
||||
|
||||
use clap::Parser;
|
||||
use vello::{
|
||||
kurbo::{Affine, Vec2},
|
||||
util::RenderContext,
|
||||
Renderer, Scene, SceneBuilder,
|
||||
};
|
||||
use winit::{event_loop::EventLoop, window::Window};
|
||||
|
||||
async fn run(event_loop: EventLoop<()>, window: Window) {
|
||||
#[derive(Parser, Debug)]
|
||||
#[command(about, long_about = None)]
|
||||
struct Args {
|
||||
/// Path to the svg file to render. If not set, the GhostScript Tiger will be rendered
|
||||
#[arg(long)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
svg: Option<PathBuf>,
|
||||
/// When rendering an svg, what scale to use
|
||||
#[arg(long)]
|
||||
scale: Option<f64>,
|
||||
/// Which scene (index) to start on
|
||||
/// Switch between scenes with left and right arrow keys
|
||||
#[arg(long)]
|
||||
scene: Option<i32>,
|
||||
}
|
||||
|
||||
const TIGER: &'static str = include_str!("../../assets/Ghostscript_Tiger.svg");
|
||||
|
||||
async fn run(event_loop: EventLoop<()>, window: Window, args: Args) {
|
||||
use winit::{event::*, event_loop::ControlFlow};
|
||||
let mut render_cx = RenderContext::new().unwrap();
|
||||
let size = window.inner_size();
|
||||
|
@ -32,8 +57,42 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
|||
let mut renderer = Renderer::new(&device_handle.device).unwrap();
|
||||
let mut simple_text = simple_text::SimpleText::new();
|
||||
let mut current_frame = 0usize;
|
||||
let mut scene_ix = 0usize;
|
||||
let mut scene = Scene::new();
|
||||
let mut cached_svg_scene = None;
|
||||
let mut drag = Vec2::default();
|
||||
let mut scale = 1f64;
|
||||
let mut mouse_down = false;
|
||||
let mut prior_position = None;
|
||||
let mut svg_static_scale = 1.0;
|
||||
// We allow looping left and right through the scenes, so use a signed index
|
||||
let mut scene_ix: i32 = 0;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let svg_string: Cow<'static, str> = match args.svg {
|
||||
Some(path) => {
|
||||
// If an svg file has been specified, show that by default
|
||||
scene_ix = 2;
|
||||
let start = std::time::Instant::now();
|
||||
eprintln!("Reading svg from {path:?}");
|
||||
let svg = std::fs::read_to_string(path)
|
||||
.expect("Provided path did not point to a file which could be read")
|
||||
.into();
|
||||
eprintln!("Finished reading svg, took {:?}", start.elapsed());
|
||||
svg
|
||||
}
|
||||
None => {
|
||||
svg_static_scale = 6.0;
|
||||
TIGER.into()
|
||||
}
|
||||
};
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let svg_string: Cow<'static, str> = TIGER.into();
|
||||
// These are set after choosing the svg, as they overwrite the defaults specified there
|
||||
if let Some(set_scene) = args.scene {
|
||||
scene_ix = set_scene;
|
||||
}
|
||||
if let Some(set_scale) = args.scale {
|
||||
svg_static_scale = set_scale;
|
||||
}
|
||||
event_loop.run(move |event, _, control_flow| match event {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
|
@ -45,6 +104,9 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
|||
match input.virtual_keycode {
|
||||
Some(VirtualKeyCode::Left) => scene_ix = scene_ix.saturating_sub(1),
|
||||
Some(VirtualKeyCode::Right) => scene_ix = scene_ix.saturating_add(1),
|
||||
Some(VirtualKeyCode::Escape) => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -53,6 +115,33 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
|||
render_cx.resize_surface(&mut surface, size.width, size.height);
|
||||
window.request_redraw();
|
||||
}
|
||||
WindowEvent::MouseInput { state, button, .. } => {
|
||||
if button == &MouseButton::Left {
|
||||
mouse_down = state == &ElementState::Pressed;
|
||||
}
|
||||
}
|
||||
WindowEvent::MouseWheel { delta, .. } => {
|
||||
if let MouseScrollDelta::PixelDelta(delta) = delta {
|
||||
scale += delta.y * 0.1;
|
||||
scale = scale.clamp(0.1, 10.0);
|
||||
}
|
||||
if let MouseScrollDelta::LineDelta(_, y) = delta {
|
||||
scale += *y as f64 * 0.1;
|
||||
scale = scale.clamp(0.1, 10.0);
|
||||
}
|
||||
}
|
||||
WindowEvent::CursorLeft { .. } => {
|
||||
prior_position = None;
|
||||
}
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
let position = Vec2::new(position.x, position.y);
|
||||
if mouse_down {
|
||||
if let Some(prior) = prior_position {
|
||||
drag += (position - prior) * (1.0 / scale);
|
||||
}
|
||||
}
|
||||
prior_position = Some(position);
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
Event::MainEventsCleared => {
|
||||
|
@ -64,14 +153,28 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
|||
let height = surface.config.height;
|
||||
let device_handle = &render_cx.devices[surface.dev_id];
|
||||
let mut builder = SceneBuilder::for_scene(&mut scene);
|
||||
const N_SCENES: usize = 6;
|
||||
match scene_ix % N_SCENES {
|
||||
|
||||
const N_SCENES: i32 = 6;
|
||||
// Allow looping forever
|
||||
scene_ix = scene_ix.rem_euclid(N_SCENES);
|
||||
// Remainder operation allows negative results, which isn't the right semantics
|
||||
match scene_ix {
|
||||
0 => test_scene::render_anim_frame(&mut builder, &mut simple_text, current_frame),
|
||||
1 => test_scene::render_blend_grid(&mut builder),
|
||||
2 => test_scene::render_tiger(&mut builder),
|
||||
2 => {
|
||||
let transform = Affine::scale(scale) * Affine::translate(drag);
|
||||
test_scene::render_svg_scene(
|
||||
&mut builder,
|
||||
&mut cached_svg_scene,
|
||||
transform,
|
||||
&svg_string,
|
||||
svg_static_scale,
|
||||
)
|
||||
}
|
||||
3 => test_scene::render_brush_transform(&mut builder, current_frame),
|
||||
4 => test_scene::render_funky_paths(&mut builder),
|
||||
_ => test_scene::render_scene(&mut builder),
|
||||
5 => test_scene::render_scene(&mut builder),
|
||||
_ => unreachable!("N_SCENES is too large"),
|
||||
}
|
||||
builder.finish();
|
||||
let surface_texture = surface
|
||||
|
@ -96,6 +199,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let args = Args::parse();
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
{
|
||||
use winit::{dpi::LogicalSize, window::WindowBuilder};
|
||||
|
@ -103,9 +207,10 @@ fn main() {
|
|||
let window = WindowBuilder::new()
|
||||
.with_inner_size(LogicalSize::new(1044, 800))
|
||||
.with_resizable(true)
|
||||
.with_title("Vello demo")
|
||||
.build(&event_loop)
|
||||
.unwrap();
|
||||
pollster::block_on(run(event_loop, window));
|
||||
pollster::block_on(run(event_loop, window, args));
|
||||
}
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use crate::pico_svg::PicoSvg;
|
||||
use crate::simple_text::SimpleText;
|
||||
use vello::kurbo::{Affine, BezPath, Ellipse, PathEl, Point, Rect};
|
||||
|
@ -45,10 +47,6 @@ pub fn render_funky_paths(sb: &mut SceneBuilder) {
|
|||
);
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
const N_CIRCLES: usize = 0;
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg) {
|
||||
use crate::pico_svg::*;
|
||||
for item in &svg.items {
|
||||
|
@ -75,13 +73,25 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg) {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn render_tiger(sb: &mut SceneBuilder) {
|
||||
pub fn render_svg_scene(
|
||||
sb: &mut SceneBuilder,
|
||||
scene: &mut Option<SceneFragment>,
|
||||
xform: Affine,
|
||||
svg: &str,
|
||||
scale: f64,
|
||||
) {
|
||||
let scene_frag = scene.get_or_insert_with(|| {
|
||||
use super::pico_svg::*;
|
||||
let xml_str =
|
||||
std::str::from_utf8(include_bytes!("../../assets/Ghostscript_Tiger.svg")).unwrap();
|
||||
let svg = PicoSvg::load(xml_str, 6.0).unwrap();
|
||||
render_svg(sb, &svg);
|
||||
let start = Instant::now();
|
||||
eprintln!("Starting to parse svg");
|
||||
let svg = PicoSvg::load(svg, scale).unwrap();
|
||||
eprintln!("Parsing svg took {:?}", start.elapsed());
|
||||
let mut new_scene = SceneFragment::new();
|
||||
let mut builder = SceneBuilder::for_fragment(&mut new_scene);
|
||||
render_svg(&mut builder, &svg);
|
||||
new_scene
|
||||
});
|
||||
sb.append(&scene_frag, Some(xform));
|
||||
}
|
||||
|
||||
pub fn render_scene(sb: &mut SceneBuilder) {
|
||||
|
@ -91,7 +101,6 @@ pub fn render_scene(sb: &mut SceneBuilder) {
|
|||
//render_tiger(sb, false);
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn render_cardioid(sb: &mut SceneBuilder) {
|
||||
let n = 601;
|
||||
let dth = std::f64::consts::PI * 2.0 / (n as f64);
|
||||
|
@ -113,13 +122,12 @@ fn render_cardioid(sb: &mut SceneBuilder) {
|
|||
sb.stroke(
|
||||
&Stroke::new(2.0),
|
||||
Affine::IDENTITY,
|
||||
Color::rgb8(0, 0, 0),
|
||||
Color::rgb8(0, 0, 255),
|
||||
None,
|
||||
&path,
|
||||
);
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn render_clip_test(sb: &mut SceneBuilder) {
|
||||
const N: usize = 16;
|
||||
const X0: f64 = 50.0;
|
||||
|
@ -145,7 +153,7 @@ fn render_clip_test(sb: &mut SceneBuilder) {
|
|||
sb.fill(
|
||||
Fill::NonZero,
|
||||
Affine::IDENTITY,
|
||||
&Brush::Solid(Color::rgb8(0, 0, 0)),
|
||||
&Brush::Solid(Color::rgb8(0, 255, 0)),
|
||||
None,
|
||||
&rect,
|
||||
);
|
||||
|
@ -154,7 +162,6 @@ fn render_clip_test(sb: &mut SceneBuilder) {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn render_alpha_test(sb: &mut SceneBuilder) {
|
||||
// Alpha compositing tests.
|
||||
sb.fill(
|
||||
|
@ -187,7 +194,6 @@ fn render_alpha_test(sb: &mut SceneBuilder) {
|
|||
sb.pop_layer();
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn render_blend_grid(sb: &mut SceneBuilder) {
|
||||
const BLEND_MODES: &[Mix] = &[
|
||||
Mix::Normal,
|
||||
|
@ -216,7 +222,6 @@ pub fn render_blend_grid(sb: &mut SceneBuilder) {
|
|||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affine) {
|
||||
// Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
|
||||
let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.));
|
||||
|
@ -260,7 +265,6 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
|
|||
sb.pop_layer();
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn blend_square(blend: BlendMode) -> SceneFragment {
|
||||
let mut fragment = SceneFragment::default();
|
||||
let mut sb = SceneBuilder::for_fragment(&mut fragment);
|
||||
|
@ -269,7 +273,6 @@ fn blend_square(blend: BlendMode) -> SceneFragment {
|
|||
fragment
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn render_anim_frame(sb: &mut SceneBuilder, text: &mut SimpleText, i: usize) {
|
||||
use PathEl::*;
|
||||
let rect = Rect::from_origin_size(Point::new(0.0, 0.0), (1000.0, 1000.0));
|
||||
|
|
|
@ -330,7 +330,7 @@ pub fn render_encoding_full(
|
|||
// in storage rather than workgroup memory.
|
||||
let n_path_aligned = align_up(n_paths as usize, 256);
|
||||
let path_buf = ResourceProxy::new_buf(n_path_aligned as u64 * PATH_SIZE);
|
||||
let tile_buf = ResourceProxy::new_buf(1 << 20);
|
||||
let tile_buf = ResourceProxy::new_buf(1 << 24);
|
||||
let path_wgs = (n_paths + shaders::PATH_BBOX_WG - 1) / shaders::PATH_BBOX_WG;
|
||||
recording.dispatch(
|
||||
shaders.tile_alloc,
|
||||
|
|
Loading…
Reference in a new issue