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