Fixed a bunch of problems that came up when running debug build.

The worst offender was an obvious and nasty bug in the bitstack
implementation.  Hooray for debug asserts!
This commit is contained in:
Nathan Vegdahl 2017-04-14 21:37:29 -07:00
parent 44e3ee8b4b
commit 0296fd2d34
4 changed files with 29 additions and 14 deletions

View File

@ -18,8 +18,10 @@ impl BitStack128 {
/// Push a bit onto the top of the stack. /// Push a bit onto the top of the stack.
pub fn push(&mut self, value: bool) { pub fn push(&mut self, value: bool) {
debug_assert!((self.data.1 >> (size_of::<u64>() - 1)) == 0); // Verify no stack overflow // Verify no stack overflow
self.data.1 = (self.data.1 << 1) | (self.data.0 >> (size_of::<u64>() - 1)); debug_assert!((self.data.1 >> ((size_of::<u64>() * 8) - 1)) == 0);
self.data.1 = (self.data.1 << 1) | (self.data.0 >> ((size_of::<u64>() * 8) - 1));
self.data.0 <<= 1; self.data.0 <<= 1;
self.data.0 |= value as u64; self.data.0 |= value as u64;
} }
@ -35,12 +37,12 @@ impl BitStack128 {
/// bits are non-zero this will produce incorrect results. /// bits are non-zero this will produce incorrect results.
pub fn push_n(&mut self, value: u8, count: u8) { pub fn push_n(&mut self, value: u8, count: u8) {
// Verify no bitstack overflow // Verify no bitstack overflow
debug_assert!((self.data.1 >> (size_of::<u64>() - count as usize)) == 0); debug_assert!((self.data.1 >> ((size_of::<u64>() * 8) - count as usize)) == 0);
// Verify no bits outside of the n-bit range // Verify no bits outside of the n-bit range
debug_assert!(value & (!((1 << count) - 1)) == 0); debug_assert!(value & (!((1 << count) - 1)) == 0);
self.data.1 = (self.data.1 << count as usize) | self.data.1 = (self.data.1 << count as usize) |
(self.data.0 >> (size_of::<u64>() - count as usize)); (self.data.0 >> ((size_of::<u64>() * 8) - count as usize));
self.data.0 <<= count as u64; self.data.0 <<= count as u64;
self.data.0 |= value as u64; self.data.0 |= value as u64;
} }
@ -48,7 +50,7 @@ impl BitStack128 {
/// Pop the top bit off the stack. /// Pop the top bit off the stack.
pub fn pop(&mut self) -> bool { pub fn pop(&mut self) -> bool {
let b = (self.data.0 & 1) != 0; let b = (self.data.0 & 1) != 0;
self.data.0 = (self.data.0 >> 1) | (self.data.1 << (size_of::<u64>() - 1)); self.data.0 = (self.data.0 >> 1) | (self.data.1 << ((size_of::<u64>() * 8) - 1));
self.data.1 >>= 1; self.data.1 >>= 1;
return b; return b;
} }
@ -57,10 +59,10 @@ impl BitStack128 {
/// an integer, with the top bit in the least significant digit, /// an integer, with the top bit in the least significant digit,
/// and the rest following in order from there. /// and the rest following in order from there.
pub fn pop_n(&mut self, n: usize) -> u64 { pub fn pop_n(&mut self, n: usize) -> u64 {
debug_assert!(n < size_of::<BitStack128>()); // Can't pop more than we have debug_assert!(n < (size_of::<BitStack128>() * 8)); // Can't pop more than we have
debug_assert!(n < size_of::<u64>()); // Can't pop more than the return type can hold debug_assert!(n < (size_of::<u64>() * 8)); // Can't pop more than the return type can hold
let b = self.data.0 & ((1 << n) - 1); let b = self.data.0 & ((1 << n) - 1);
self.data.0 = (self.data.0 >> n) | (self.data.1 << (size_of::<u64>() - n)); self.data.0 = (self.data.0 >> n) | (self.data.1 << ((size_of::<u64>() * 8) - n));
self.data.1 >>= n; self.data.1 >>= n;
return b; return b;
} }
@ -74,8 +76,11 @@ impl BitStack128 {
/// are returned as an integer, with the top bit in the least /// are returned as an integer, with the top bit in the least
/// significant digit, and the rest following in order from there. /// significant digit, and the rest following in order from there.
pub fn peek_n(&self, n: usize) -> u64 { pub fn peek_n(&self, n: usize) -> u64 {
debug_assert!(n < size_of::<BitStack128>()); // Can't return more than we have // Can't return more than we have
debug_assert!(n < size_of::<u64>()); // Can't return more than the return type can hold debug_assert!(n < (size_of::<BitStack128>() * 8));
// Can't return more than the return type can hold
debug_assert!(n < (size_of::<u64>() * 8));
self.data.0 & ((1 << n) - 1) self.data.0 & ((1 << n) - 1)
} }
} }

View File

@ -202,8 +202,16 @@ impl<'a> Renderer<'a> {
let x = bx as usize * bucket_w; let x = bx as usize * bucket_w;
let y = by as usize * bucket_h; let y = by as usize * bucket_h;
let w = min(bucket_w, img_width - x); let w = if img_width >= x {
let h = min(bucket_h, img_height - y); min(bucket_w, img_width - x)
} else {
bucket_w
};
let h = if img_height >= y {
min(bucket_h, img_height - y)
} else {
bucket_h
};
if x < img_width && y < img_height && w > 0 && h > 0 { if x < img_width && y < img_height && w > 0 && h > 0 {
job_queue.push(BucketJob { job_queue.push(BucketJob {
x: x as u32, x: x as u32,

View File

@ -342,7 +342,7 @@ pub struct GTRClosure {
col: XYZ, col: XYZ,
roughness: f32, roughness: f32,
tail_shape: f32, tail_shape: f32,
fresnel: f32, fresnel: f32, // [0.0, 1.0] determines how much fresnel reflection comes into play
normalization_factor: f32, normalization_factor: f32,
} }
@ -372,6 +372,8 @@ impl GTRClosure {
// Makes sure values are in a valid range // Makes sure values are in a valid range
fn validate(&mut self) { fn validate(&mut self) {
debug_assert!(self.fresnel >= 0.0 && self.fresnel <= 1.0);
// Clamp values to valid ranges // Clamp values to valid ranges
self.roughness = clamp(self.roughness, 0.0, 0.9999); self.roughness = clamp(self.roughness, 0.0, 0.9999);
self.tail_shape = (0.0001f32).max(self.tail_shape); self.tail_shape = (0.0001f32).max(self.tail_shape);

View File

@ -115,7 +115,7 @@ impl<'a> Surface for TriangleMesh<'a> {
0.8), 0.8),
0.1, 0.1,
2.0, 2.0,
1.2)), 1.0)),
}; };
r.max_t = t; r.max_t = t;
} }