Compare commits
7 Commits
7b5571344e
...
690048cbef
| Author | SHA1 | Date | |
|---|---|---|---|
| 690048cbef | |||
| fcc22b24cd | |||
| 90c4e15ad1 | |||
| 38317de40d | |||
| 92c8f1980c | |||
| 5d5f3c7244 | |||
| 051482e7fe |
@ -13,7 +13,7 @@ steps:
|
||||
commands:
|
||||
- sccache -s
|
||||
- apt-get update && apt-get install -y libgoogle-perftools-dev
|
||||
- (cd rtiow && cargo build --verbose --all)
|
||||
- (cd rtiow && ./build_all_features.sh)
|
||||
- (cd rtiow && cargo test --verbose --all)
|
||||
- sccache -s
|
||||
|
||||
|
||||
6
rtiow/build_all_features.sh
Executable file
6
rtiow/build_all_features.sh
Executable file
@ -0,0 +1,6 @@
|
||||
set -e
|
||||
export RUSTFLAGS="-D warnings"
|
||||
cargo build
|
||||
cargo build --features=prom
|
||||
cargo build --features=profile
|
||||
cargo build --features=prom,profile
|
||||
@ -153,7 +153,7 @@ fn render_noise(noise_params: NoiseParams) -> image::GrayImage {
|
||||
const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
|
||||
let rng: &mut XorShiftRng = &mut SeedableRng::from_seed(SEED);
|
||||
let mut img = image::GrayImage::new(noise_params.width, noise_params.height);
|
||||
let tex: NoiseTexture<Box<noise::NoiseSource>> = match noise_params.noise_source {
|
||||
let tex: NoiseTexture<Box<dyn noise::NoiseSource>> = match noise_params.noise_source {
|
||||
NoiseSource::Perlin => {
|
||||
NoiseTexture::new(Box::new(Perlin::new(rng)), noise_params.noise_type)
|
||||
}
|
||||
|
||||
@ -8,13 +8,13 @@ extern crate rtiow;
|
||||
extern crate stderrlog;
|
||||
extern crate structopt;
|
||||
#[macro_use]
|
||||
#[cfg(feature = "prom")]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
#[cfg(feature = "prom")]
|
||||
extern crate prometheus;
|
||||
|
||||
use std::fs;
|
||||
use std::time::Instant;
|
||||
|
||||
use chrono::DateTime;
|
||||
use chrono::Utc;
|
||||
@ -46,7 +46,7 @@ fn push_metrics(_push_gateway_addr: &str, _instance: String, start_time: &DateTi
|
||||
|
||||
#[cfg(feature = "prom")]
|
||||
fn push_metrics(push_gateway_addr: &str, instance: String, start_time: &DateTime<Utc>) {
|
||||
let runtime = start_instant.elapsed();
|
||||
let runtime = (Utc::now() - *start_time).to_std().unwrap();
|
||||
info!(
|
||||
"Render time {}.{} seconds",
|
||||
runtime.as_secs(),
|
||||
@ -88,8 +88,10 @@ fn push_metrics(push_gateway_addr: &str, instance: String, start_time: &DateTime
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "profile"))]
|
||||
struct MockTimer;
|
||||
|
||||
#[cfg(not(feature = "profile"))]
|
||||
impl MockTimer {
|
||||
fn start<T: Into<Vec<u8>>>(&self, _: T) -> Result<(), ()> {
|
||||
Ok(())
|
||||
@ -99,8 +101,10 @@ impl MockTimer {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "profile"))]
|
||||
struct MockProfiler;
|
||||
|
||||
#[cfg(not(feature = "profile"))]
|
||||
impl MockProfiler {
|
||||
fn lock(&self) -> Option<MockTimer> {
|
||||
Some(MockTimer {})
|
||||
@ -117,7 +121,6 @@ fn main() -> Result<(), std::io::Error> {
|
||||
.init()
|
||||
.unwrap();
|
||||
let start_time: DateTime<Utc> = Utc::now();
|
||||
let start_instant = Instant::now();
|
||||
let opt = Opt::from_args();
|
||||
let scene = opt.model.scene(&opt);
|
||||
fs::create_dir_all(&opt.output)?;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#![allow(dead_code)]
|
||||
#![doc(html_root_url = "https://docs.rs/human_format")]
|
||||
|
||||
//! From https://raw.githubusercontent.com/BobGneu/human-format-rs/master/src/lib.rs
|
||||
@ -72,7 +73,7 @@ impl Formatter {
|
||||
Formatter {
|
||||
decimals: 2,
|
||||
separator: " ".to_owned(),
|
||||
scales: Scales::SI(),
|
||||
scales: Scales::si(),
|
||||
forced_units: "".to_owned(),
|
||||
forced_suffix: "".to_owned(),
|
||||
}
|
||||
@ -151,11 +152,11 @@ impl Formatter {
|
||||
impl Scales {
|
||||
/// Instantiates a new `Scales` with SI keys
|
||||
pub fn new() -> Self {
|
||||
Scales::SI()
|
||||
Scales::si()
|
||||
}
|
||||
|
||||
/// Instantiates a new `Scales` with SI keys
|
||||
pub fn SI() -> Self {
|
||||
pub fn si() -> Self {
|
||||
Scales {
|
||||
base: 1000,
|
||||
suffixes: vec![
|
||||
@ -173,7 +174,7 @@ impl Scales {
|
||||
}
|
||||
|
||||
/// Instantiates a new `Scales` with Binary keys
|
||||
pub fn Binary() -> Self {
|
||||
pub fn binary() -> Self {
|
||||
Scales {
|
||||
base: 1000,
|
||||
suffixes: vec![
|
||||
@ -211,8 +212,6 @@ impl Scales {
|
||||
}
|
||||
|
||||
fn get_magnitude_multipler(&self, value: &str) -> f64 {
|
||||
let ndx = 0;
|
||||
|
||||
for ndx in 0..self.suffixes.len() {
|
||||
if value == self.suffixes[ndx] {
|
||||
return self.base.pow(ndx as u32) as f64;
|
||||
|
||||
@ -31,7 +31,5 @@ extern crate structopt;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
#[macro_use]
|
||||
#[cfg(feature = "prom")]
|
||||
extern crate prometheus;
|
||||
|
||||
@ -15,6 +15,8 @@ use std::time;
|
||||
|
||||
use image;
|
||||
use image::RgbImage;
|
||||
#[cfg(feature = "prom")]
|
||||
use lazy_static::lazy_static;
|
||||
use num_cpus;
|
||||
use rand;
|
||||
use rand::Rng;
|
||||
@ -36,7 +38,9 @@ lazy_static! {
|
||||
register_counter_vec!("rays", "Number of rays fired", &["level"]).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "prom"))]
|
||||
struct MockPrometheus;
|
||||
#[cfg(not(feature = "prom"))]
|
||||
impl MockPrometheus {
|
||||
fn with_label_values(&self, _: &[&str]) -> &MockPrometheus {
|
||||
self
|
||||
@ -146,9 +150,12 @@ pub struct Opt {
|
||||
/// Sub-samples per pixel
|
||||
#[structopt(short = "s", long = "subsample", default_value = "8")]
|
||||
pub subsamples: usize,
|
||||
/// Use adaptive subsampling
|
||||
#[structopt(long = "adaptive")]
|
||||
pub adaptive_subsampling: bool,
|
||||
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box",
|
||||
/// "cornell_smoke", "perlin_debug", "final"
|
||||
#[structopt(long = "model", default_value = "perlin_debug")]
|
||||
#[structopt(long = "model", default_value = "book")]
|
||||
pub model: Model,
|
||||
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
|
||||
#[structopt(long = "pprof", parse(from_os_str))]
|
||||
@ -180,6 +187,8 @@ pub struct Scene {
|
||||
pub world: Box<dyn Hit>,
|
||||
pub camera: Camera,
|
||||
pub subsamples: usize,
|
||||
/// overrides subsamples setting.
|
||||
pub adaptive_subsampling: bool,
|
||||
pub num_threads: Option<usize>,
|
||||
pub width: usize,
|
||||
pub height: usize,
|
||||
@ -214,6 +223,7 @@ impl Default for Scene {
|
||||
)),
|
||||
camera,
|
||||
subsamples: 0,
|
||||
adaptive_subsampling: false,
|
||||
num_threads: None,
|
||||
width: 0,
|
||||
height: 0,
|
||||
@ -288,26 +298,22 @@ enum Request {
|
||||
}
|
||||
|
||||
enum Response {
|
||||
Pixel {
|
||||
x: usize,
|
||||
y: usize,
|
||||
pixel: Vec3,
|
||||
},
|
||||
Line {
|
||||
width: usize,
|
||||
y: usize,
|
||||
pixels: Vec<Vec3>,
|
||||
},
|
||||
Pixel { x: usize, y: usize, pixel: Vec3 },
|
||||
Line { y: usize, pixels: Vec<Vec3> },
|
||||
}
|
||||
|
||||
static PIXEL_COUNT: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
fn render_pixel(scene: &Scene, x: usize, y: usize) -> Vec3 {
|
||||
let mut pixel: Vec3 = Default::default();
|
||||
for _ in 0..scene.subsamples {
|
||||
pixel = pixel + trace_pixel(x, y, scene);
|
||||
}
|
||||
pixel = pixel / scene.subsamples as f32;
|
||||
let pixel = if scene.adaptive_subsampling {
|
||||
Default::default()
|
||||
} else {
|
||||
for _ in 0..scene.subsamples {
|
||||
pixel = pixel + trace_pixel(x, y, scene);
|
||||
}
|
||||
pixel / scene.subsamples as f32
|
||||
};
|
||||
// Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2 or
|
||||
// sqrt.
|
||||
PIXEL_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
@ -331,12 +337,16 @@ fn render_worker(
|
||||
Request::Line { width, y } => {
|
||||
trace!("tid {} width {} y {}", tid, width, y);
|
||||
let pixels = (0..width).map(|x| render_pixel(scene, x, y)).collect();
|
||||
output_chan.send(Response::Line { width, y, pixels });
|
||||
output_chan
|
||||
.send(Response::Line { y, pixels })
|
||||
.expect("failed to send pixel response");
|
||||
}
|
||||
Request::Pixel { x, y } => {
|
||||
trace!("tid {} x {} y {}", tid, x, y);
|
||||
let pixel = render_pixel(scene, x, y);
|
||||
output_chan.send(Response::Pixel { x, y, pixel });
|
||||
output_chan
|
||||
.send(Response::Pixel { x, y, pixel })
|
||||
.expect("failed to send line response");
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -351,6 +361,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
|
||||
let scene = Arc::new(scene);
|
||||
let pixel_req_rx = Arc::new(Mutex::new(pixel_req_rx));
|
||||
info!("Creating {} render threads", num_threads);
|
||||
info!("Adaptive subsampling: {}", scene.adaptive_subsampling);
|
||||
for i in 0..num_threads {
|
||||
let s = sync::Arc::clone(&scene);
|
||||
let pixel_req_rx = pixel_req_rx.clone();
|
||||
@ -367,12 +378,16 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
|
||||
let batch_line_requests = true;
|
||||
if batch_line_requests {
|
||||
for y in 0..h {
|
||||
pixel_req_tx.send(Request::Line { width: w, y });
|
||||
pixel_req_tx
|
||||
.send(Request::Line { width: w, y })
|
||||
.expect("failed to send line request");
|
||||
}
|
||||
} else {
|
||||
for y in 0..h {
|
||||
for x in 0..w {
|
||||
pixel_req_tx.send(Request::Pixel { x, y });
|
||||
pixel_req_tx
|
||||
.send(Request::Pixel { x, y })
|
||||
.expect("failed to send pixel request");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -424,11 +439,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
|
||||
]),
|
||||
);
|
||||
}
|
||||
Response::Line {
|
||||
width: _,
|
||||
y,
|
||||
pixels,
|
||||
} => {
|
||||
Response::Line { y, pixels } => {
|
||||
for (x, pixel) in pixels.iter().enumerate() {
|
||||
let y_inv = scene.height - y - 1;
|
||||
img.put_pixel(
|
||||
|
||||
@ -51,6 +51,7 @@ pub fn new(opt: &Opt) -> Scene {
|
||||
camera,
|
||||
world,
|
||||
subsamples: opt.subsamples,
|
||||
adaptive_subsampling: opt.adaptive_subsampling,
|
||||
num_threads: opt.num_threads,
|
||||
width: opt.width,
|
||||
height: opt.height,
|
||||
|
||||
5
rtiow/watch_all_features.sh
Executable file
5
rtiow/watch_all_features.sh
Executable file
@ -0,0 +1,5 @@
|
||||
export RUSTFLAGS="-D warnings"
|
||||
cargo watch -x 'build' \
|
||||
-x 'build --features=prom' \
|
||||
-x 'build --features=profile' \
|
||||
-x 'build --features=prom,profile'
|
||||
Loading…
x
Reference in New Issue
Block a user