From 934633f77e80b26d5900b1b620ec97fbed8f3653 Mon Sep 17 00:00:00 2001 From: Schell Carl Scivally Date: Sat, 23 Dec 2023 08:29:55 +1300 Subject: [PATCH] added criterion benchmark and ported scene_parent_sanity test --- crates/renderling/Cargo.toml | 2 +- crates/renderling/benches/benchmarks.rs | 49 ++++- crates/renderling/src/lib.rs | 242 +++++++++++------------- 3 files changed, 154 insertions(+), 139 deletions(-) diff --git a/crates/renderling/Cargo.toml b/crates/renderling/Cargo.toml index 5028f99e..e9bbe260 100644 --- a/crates/renderling/Cargo.toml +++ b/crates/renderling/Cargo.toml @@ -43,7 +43,7 @@ wgpu = { workspace = true, features = ["spirv"] } features = ["gltf", "text", "raw-window-handle", "winit"] [dev-dependencies] -criterion = "0.4" +criterion = { version = "0.4", features = ["html_reports"] } ctor = "0.2.2" env_logger = "0.10.0" icosahedron = "0.1" diff --git a/crates/renderling/benches/benchmarks.rs b/crates/renderling/benches/benchmarks.rs index 5fa1265f..916b79c3 100644 --- a/crates/renderling/benches/benchmarks.rs +++ b/crates/renderling/benches/benchmarks.rs @@ -1,8 +1,51 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; +use renderling::{GltfLoader, Renderling}; -fn renderling_benchmark(c: &mut Criterion) { - c.bench_function("renderling_stub", |b| b.iter(|| black_box(1 + 1))); +fn load_damaged_helmet(c: &mut Criterion) { + //let _ = env_logger::builder() + // .is_test(true) + // .filter_level(log::LevelFilter::Trace) + // .filter_module("renderling", log::LevelFilter::Trace) + // .filter_module("dagga", log::LevelFilter::Warn) + // .filter_module("broomdog", log::LevelFilter::Warn) + // .filter_module("naga", log::LevelFilter::Warn) + // .filter_module("wgpu", log::LevelFilter::Warn) + // .filter_module("wgpu_hal", log::LevelFilter::Warn) + // .try_init(); + + let (document, buffers, images) = gltf::import("../../gltf/DamagedHelmet.glb").unwrap(); + + let mut group = c.benchmark_group("load_damaged_helmet"); + group.sample_size(20); + + println!("{}", std::env::current_dir().unwrap().display()); + + let r = Renderling::headless(100, 100); + group.bench_function("legacy", |b| { + b.iter(|| { + let mut builder = r.new_scene(); + let loader = GltfLoader::load( + &mut builder, + document.clone(), + buffers.clone(), + images.clone(), + ); + let scene = builder.build().unwrap(); + black_box((loader, scene)) + }) + }); + + let r = Renderling::headless(100, 100); + group.bench_function("gltf", |b| { + b.iter(|| { + let stage = r.new_stage(); + let gpu_doc = stage + .load_gltf_document(&document, buffers.clone(), images.clone()) + .unwrap(); + black_box(gpu_doc) + }) + }); } -criterion_group!(benches, renderling_benchmark); +criterion_group!(benches, load_damaged_helmet); criterion_main!(benches); diff --git a/crates/renderling/src/lib.rs b/crates/renderling/src/lib.rs index 65017afb..aac94b88 100644 --- a/crates/renderling/src/lib.rs +++ b/crates/renderling/src/lib.rs @@ -19,11 +19,9 @@ //! - [ ] light tiling //! - [ ] occlusion culling //! - [x] physically based shading -//! - [x] user interface "colored text" shading (uses opacity glyphs in an //! atlas) -//! - [x] no shading -//! - [ ] gltf support -//! - [ ] scenes, nodes +//! - [x] gltf support +//! - [x] scenes, nodes //! - [x] cameras //! - [x] meshes //! - [x] materials @@ -261,7 +259,7 @@ mod test { use pretty_assertions::assert_eq; use renderling_shader::{ gltf as gl, - stage::{gltf_vertex, light::*, Camera, GpuEntity, RenderUnit, Transform, Vertex}, + stage::{light::*, Camera, RenderUnit, Transform, Vertex}, }; #[test] @@ -876,149 +874,123 @@ mod test { fn scene_parent_sanity() { let mut r = Renderling::headless(100, 100); r.set_background_color(Vec4::splat(0.0)); + let stage = r.new_stage(); + stage.configure_graph(&mut r, true); let (projection, view) = camera::default_ortho2d(100.0, 100.0); - let mut builder = r.new_scene().with_camera(projection, view); + let camera = stage.append(&Camera::new(projection, view)); let size = 1.0; - let root = builder.new_entity().with_scale([25.0, 25.0, 1.0]).build(); - let cyan_tri = builder - .new_entity() - .with_meshlet(vec![ - Vertex { - position: Vec4::new(0.0, 0.0, 0.0, 0.0), - color: Vec4::new(0.0, 1.0, 1.0, 1.0), - ..Default::default() - }, - Vertex { - position: Vec4::new(size, size, 0.0, 0.0), - color: Vec4::new(0.0, 1.0, 1.0, 1.0), - ..Default::default() - }, - Vertex { - position: Vec4::new(size, 0.0, 0.0, 0.0), - color: Vec4::new(0.0, 1.0, 1.0, 1.0), - ..Default::default() - }, - ]) - .with_position([1.0, 1.0, 0.0]) - .with_parent(root) - .build(); - let yellow_tri = builder // - .new_entity() - .with_meshlet(vec![ - Vertex { - position: Vec4::new(0.0, 0.0, 0.0, 0.0), - color: Vec4::new(1.0, 1.0, 0.0, 1.0), - ..Default::default() - }, - Vertex { - position: Vec4::new(size, size, 0.0, 0.0), - color: Vec4::new(1.0, 1.0, 0.0, 1.0), - ..Default::default() - }, - Vertex { - position: Vec4::new(size, 0.0, 0.0, 0.0), - color: Vec4::new(1.0, 1.0, 0.0, 1.0), - ..Default::default() - }, - ]) - .with_position([1.0, 1.0, 0.0]) - .with_parent(&cyan_tri) - .build(); - let _red_tri = builder - .new_entity() - .with_meshlet(vec![ - Vertex { - position: Vec4::new(0.0, 0.0, 0.0, 0.0), - color: Vec4::new(1.0, 0.0, 0.0, 1.0), - ..Default::default() - }, - Vertex { - position: Vec4::new(size, size, 0.0, 0.0), - color: Vec4::new(1.0, 0.0, 0.0, 1.0), - ..Default::default() - }, - Vertex { - position: Vec4::new(size, 0.0, 0.0, 0.0), - color: Vec4::new(1.0, 0.0, 0.0, 1.0), - ..Default::default() - }, - ]) - .with_position([1.0, 1.0, 0.0]) - .with_parent(&yellow_tri) - .build(); + let cyan_material = stage.append(&PbrMaterial { + albedo_factor: Vec4::new(0.0, 1.0, 1.0, 1.0), + lighting_model: LightingModel::NO_LIGHTING, + ..Default::default() + }); + let yellow_material = stage.append(&PbrMaterial { + albedo_factor: Vec4::new(1.0, 1.0, 0.0, 1.0), + lighting_model: LightingModel::NO_LIGHTING, + ..Default::default() + }); + let red_material = stage.append(&PbrMaterial { + albedo_factor: Vec4::new(1.0, 0.0, 0.0, 1.0), + lighting_model: LightingModel::NO_LIGHTING, + ..Default::default() + }); - assert_eq!( - vec![ - GpuEntity { - id: Id::new(0), - position: Vec4::new(0.0, 0.0, 0.0, 0.0), - scale: Vec4::new(25.0, 25.0, 1.0, 1.0), + let cyan_primitive = stage.new_primitive( + [ + Vertex::default().with_position([0.0, 0.0, 0.0]), + Vertex::default().with_position([size, size, 0.0]), + Vertex::default().with_position([size, 0.0, 0.0]), + ], + [], + cyan_material, + ); + let yellow_primitive = { + let mut p = cyan_primitive; + p.material = yellow_material; + p + }; + let red_primitive = { + let mut p = cyan_primitive; + p.material = red_material; + p + }; + + let root_node = stage.allocate::(); + let cyan_node = stage.allocate::(); + let yellow_node = stage.allocate::(); + let red_node = stage.allocate::(); + + // Write the nodes now that we have references to them all + stage + .write( + root_node, + &gl::GltfNode { + children: stage.append_array(&[cyan_node]), + scale: Vec3::new(25.0, 25.0, 1.0), ..Default::default() }, - GpuEntity { - id: Id::new(1), - parent: Id::new(0), - position: Vec4::new(1.0, 1.0, 0.0, 0.0), - scale: Vec4::new(1.0, 1.0, 1.0, 1.0), - mesh_first_vertex: 0, - mesh_vertex_count: 3, + ) + .unwrap(); + stage + .write( + cyan_node, + &gl::GltfNode { + mesh: stage.append(&gl::GltfMesh { + primitives: stage.append_array(&[cyan_primitive]), + ..Default::default() + }), + children: stage.append_array(&[yellow_node]), + translation: Vec3::new(1.0, 1.0, 0.0), ..Default::default() }, - GpuEntity { - id: Id::new(2), - parent: Id::new(1), - position: Vec4::new(1.0, 1.0, 0.0, 0.0), - scale: Vec4::new(1.0, 1.0, 1.0, 1.0), - mesh_first_vertex: 3, - mesh_vertex_count: 3, + ) + .unwrap(); + stage + .write( + yellow_node, + &gl::GltfNode { + mesh: stage.append(&gl::GltfMesh { + primitives: stage.append_array(&[yellow_primitive]), + ..Default::default() + }), + children: stage.append_array(&[red_node]), + translation: Vec3::new(1.0, 1.0, 0.0), ..Default::default() }, - GpuEntity { - id: Id::new(3), - parent: Id::new(2), - position: Vec4::new(1.0, 1.0, 0.0, 0.0), - scale: Vec4::new(1.0, 1.0, 1.0, 1.0), - mesh_first_vertex: 6, - mesh_vertex_count: 3, + ) + .unwrap(); + stage + .write( + red_node, + &gl::GltfNode { + mesh: stage.append(&gl::GltfMesh { + primitives: stage.append_array(&[red_primitive]), + ..Default::default() + }), + translation: Vec3::new(1.0, 1.0, 0.0), ..Default::default() - } - ], - builder.entities - ); - let tfrm = yellow_tri.get_world_transform(&builder.entities); - assert_eq!( - ( - Vec3::new(50.0, 50.0, 0.0), - Quat::IDENTITY, - Vec3::new(25.0, 25.0, 1.0), - ), - tfrm - ); - // while we're at it let's also check that skinning doesn't affect - // entities/vertices that aren't skins - let vertex = &builder.vertices[yellow_tri.mesh_first_vertex as usize]; - let skin_matrix = vertex.get_skin_matrix(&yellow_tri.skin_joint_ids, &builder.entities); - assert_eq!(Mat4::IDENTITY, skin_matrix); + }, + ) + .unwrap(); - let entities = builder.entities.clone(); - let scene = builder.build().unwrap(); - r.setup_render_graph(RenderGraphConfig { - scene: Some(scene), - with_screen_capture: true, - with_bloom: false, + let _cyan_unit = stage.draw_unit(&RenderUnit { + camera, + vertex_count: 3, + node_path: stage.append_array(&[root_node, cyan_node]), + ..Default::default() + }); + let _yellow_unit = stage.draw_unit(&RenderUnit { + camera, + vertex_count: 3, + node_path: stage.append_array(&[root_node, cyan_node, yellow_node]), + ..Default::default() + }); + let _red_unit = stage.draw_unit(&RenderUnit { + camera, + vertex_count: 3, + node_path: stage.append_array(&[root_node, cyan_node, yellow_node, red_node]), ..Default::default() }); - - let gpu_entities = futures_lite::future::block_on( - r.graph - .get_resource::() - .unwrap() - .unwrap() - .entities - .read_gpu(r.get_device(), r.get_queue(), 0, entities.len()), - ) - .unwrap(); - assert_eq!(entities, gpu_entities); let img = r.render_image().unwrap(); img_diff::assert_img_eq("scene_parent_sanity.png", img);