From 8b14e46bc15fe687a1d47eefab9f3f633a8cd15a Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Sat, 22 Apr 2017 10:31:27 -0700 Subject: [PATCH] Added more detailed render stats. --- src/main.rs | 15 ++++++++++++-- src/renderer.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/main.rs b/src/main.rs index bff1545..dbdd91b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -179,8 +179,19 @@ fn main() { println!("\tBuilt scene in {:.3}s", t.tick()); println!("Rendering scene with {} threads...", thread_count); - let mut image = r.render(max_samples_per_bucket, thread_count); - println!("\tRendered scene in {:.3}s", t.tick()); + let (mut image, rstats) = r.render(max_samples_per_bucket, thread_count); + // Print render stats + { + let rtime = t.tick(); + let ntime = rtime as f64 / rstats.total_time; + println!("\tRendered scene in {:.3}s", rtime); + println!("\t\tTrace: {:.3}s", ntime * rstats.trace_time); + println!("\t\tRay generation: {:.3}s", + ntime * rstats.ray_generation_time); + println!("\t\tSample writing: {:.3}s", + ntime * rstats.sample_writing_time); + println!("\t\tTotal: {:.3}s", ntime * rstats.total_time); + } println!("Writing image to disk..."); if r.output_file.ends_with(".png") { diff --git a/src/renderer.rs b/src/renderer.rs index 3b373ff..cbbba60 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -18,6 +18,7 @@ use ray::Ray; use sampling::halton; use scene::Scene; use surface; +use timer::Timer; use tracer::Tracer; use transform_stack::TransformStack; @@ -31,8 +32,34 @@ pub struct Renderer<'a> { pub scene: Scene<'a>, } +#[derive(Debug, Copy, Clone)] +pub struct RenderStats { + pub trace_time: f64, + pub ray_generation_time: f64, + pub sample_writing_time: f64, + pub total_time: f64, +} + +impl RenderStats { + fn new() -> RenderStats { + RenderStats { + trace_time: 0.0, + ray_generation_time: 0.0, + sample_writing_time: 0.0, + total_time: 0.0, + } + } + + fn collect(&mut self, other: RenderStats) { + self.trace_time += other.trace_time; + self.ray_generation_time += other.ray_generation_time; + self.sample_writing_time += other.sample_writing_time; + self.total_time += other.total_time; + } +} + impl<'a> Renderer<'a> { - pub fn render(&self, max_samples_per_bucket: u32, thread_count: u32) -> Image { + pub fn render(&self, max_samples_per_bucket: u32, thread_count: u32) -> (Image, RenderStats) { let mut tpool = Pool::new(thread_count); let image = Image::new(self.resolution.0, self.resolution.1); @@ -40,6 +67,8 @@ impl<'a> Renderer<'a> { let all_jobs_queued = RwLock::new(false); + let collective_stats = RwLock::new(RenderStats::new()); + // Pre-calculate some useful values related to the image plane let cmpx = 1.0 / self.resolution.0 as f32; let cmpy = 1.0 / self.resolution.1 as f32; @@ -65,13 +94,18 @@ impl<'a> Renderer<'a> { let jq = &job_queue; let ajq = &all_jobs_queued; let img = ℑ + let cstats = &collective_stats; scope.execute(move || { + let mut stats = RenderStats::new(); + let mut timer = Timer::new(); + let mut total_timer = Timer::new(); + let mut paths = Vec::new(); let mut rays = Vec::new(); let mut tracer = Tracer::from_assembly(&self.scene.root); let mut xform_stack = TransformStack::new(); - loop { + 'render_loop: loop { paths.clear(); rays.clear(); @@ -83,11 +117,12 @@ impl<'a> Renderer<'a> { break; } else { if *ajq.read().unwrap() == true { - return; + break 'render_loop; } } } + timer.tick(); // Generate light paths and initial rays for y in bucket.y..(bucket.y + bucket.h) { for x in bucket.x..(bucket.x + bucket.w) { @@ -124,18 +159,21 @@ impl<'a> Renderer<'a> { } } } + stats.ray_generation_time += timer.tick() as f64; // Trace the paths! let mut pi = paths.len(); while pi > 0 { // Test rays against scene let isects = tracer.trace(&rays); + stats.trace_time += timer.tick() as f64; // Determine next rays to shoot based on result pi = partition_pair(&mut paths[..pi], &mut rays[..pi], |i, path, ray| { path.next(&mut xform_stack, &self.scene, &isects[i], &mut *ray) }); + stats.ray_generation_time += timer.tick() as f64; } // Calculate color based on ray hits and save to image @@ -148,6 +186,7 @@ impl<'a> Renderer<'a> { col += XYZ::from_spectral_sample(&path.color) / self.spp as f32; img_bucket.set(path.pixel_co.0, path.pixel_co.1, col); } + stats.sample_writing_time += timer.tick() as f64; } // Print render progress @@ -169,6 +208,11 @@ impl<'a> Renderer<'a> { } } } + + stats.total_time += total_timer.tick() as f64; + + // Collect stats + cstats.write().unwrap().collect(stats); }); } @@ -229,8 +273,8 @@ impl<'a> Renderer<'a> { // Clear percentage progress print print!("\r \r"); - // Return the rendered image - return image; + // Return the rendered image and stats + return (image, *collective_stats.read().unwrap()); } }