Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial commit of texture cache. #120

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ SET ( PBRT_CORE_SOURCE
src/core/filter.cpp
src/core/floatfile.cpp
src/core/geometry.cpp
src/core/image.cpp
src/core/imageio.cpp
src/core/integrator.cpp
src/core/interaction.cpp
Expand All @@ -169,6 +170,7 @@ SET ( PBRT_CORE_SOURCE
src/core/medium.cpp
src/core/memory.cpp
src/core/microfacet.cpp
src/core/mipmap.cpp
src/core/parallel.cpp
src/core/paramset.cpp
src/core/parser.cpp
Expand All @@ -183,6 +185,7 @@ SET ( PBRT_CORE_SOURCE
src/core/sobolmatrices.cpp
src/core/spectrum.cpp
src/core/stats.cpp
src/core/texcache.cpp
src/core/texture.cpp
src/core/transform.cpp
)
Expand Down
31 changes: 10 additions & 21 deletions src/cameras/realistic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
#include "sampler.h"
#include "sampling.h"
#include "floatfile.h"
#include "imageio.h"
#include "image.h"
#include "reflection.h"
#include "stats.h"
#include "lowdiscrepancy.h"
Expand Down Expand Up @@ -545,8 +545,7 @@ void RealisticCamera::RenderExitPupil(Float sx, Float sy,
Point3f pFilm(sx, sy, 0);

const int nSamples = 2048;
Float *image = new Float[3 * nSamples * nSamples];
Float *imagep = image;
Image image(PixelFormat::Y32, {nSamples, nSamples});

for (int y = 0; y < nSamples; ++y) {
Float fy = (Float)y / (Float)(nSamples - 1);
Expand All @@ -557,27 +556,17 @@ void RealisticCamera::RenderExitPupil(Float sx, Float sy,

Point3f pRear(lx, ly, LensRearZ());

if (lx * lx + ly * ly > RearElementRadius() * RearElementRadius()) {
*imagep++ = 1;
*imagep++ = 1;
*imagep++ = 1;
} else if (TraceLensesFromFilm(Ray(pFilm, pRear - pFilm),
nullptr)) {
*imagep++ = 0.5f;
*imagep++ = 0.5f;
*imagep++ = 0.5f;
} else {
*imagep++ = 0.f;
*imagep++ = 0.f;
*imagep++ = 0.f;
}
if (lx * lx + ly * ly > RearElementRadius() * RearElementRadius())
image.SetY({x, y}, 1.);
else if (TraceLensesFromFilm(Ray(pFilm, pRear - pFilm),
nullptr))
image.SetY({x, y}, 0.5);
else
image.SetY({x, y}, 0.);
}
}

WriteImage(filename, image,
Bounds2i(Point2i(0, 0), Point2i(nSamples, nSamples)),
Point2i(nSamples, nSamples));
delete[] image;
image.Write(filename);
}

Point3f RealisticCamera::SampleExitPupil(const Point2f &pFilm,
Expand Down
11 changes: 9 additions & 2 deletions src/core/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "film.h"
#include "medium.h"
#include "stats.h"
#include "texcache.h"

// API Additional Headers
#include "accelerators/bvh.h"
Expand Down Expand Up @@ -1384,6 +1385,12 @@ void pbrtWorldEnd() {

if (scene && integrator) integrator->Render(*scene);

// FIXME: yuck
if (CachedTexelProvider::textureCache) {
delete CachedTexelProvider::textureCache;
CachedTexelProvider::textureCache = nullptr;
}

MergeWorkerThreadStats();
ReportThreadStats();
if (!PbrtOptions.quiet) {
Expand All @@ -1406,8 +1413,8 @@ void pbrtWorldEnd() {
activeTransformBits = AllTransformsBits;
namedCoordinateSystems.erase(namedCoordinateSystems.begin(),
namedCoordinateSystems.end());
ImageTexture<Float, Float>::ClearCache();
ImageTexture<RGBSpectrum, Spectrum>::ClearCache();
ImageTexture<Float>::ClearCache();
ImageTexture<Spectrum>::ClearCache();
}

Scene *RenderOptions::MakeScene() {
Expand Down
36 changes: 14 additions & 22 deletions src/core/film.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "paramset.h"
#include "imageio.h"
#include "stats.h"
#include "image.h"

namespace pbrt {

Expand Down Expand Up @@ -169,44 +170,35 @@ void Film::WriteImage(Float splatScale) {
// Convert image to RGB and compute final pixel values
LOG(INFO) <<
"Converting image to RGB and computing final weighted pixel values";
std::unique_ptr<Float[]> rgb(new Float[3 * croppedPixelBounds.Area()]);
int offset = 0;
Image rgb32(PixelFormat::RGB32, Point2i(croppedPixelBounds.Diagonal()));
for (Point2i p : croppedPixelBounds) {
// Convert pixel XYZ color to RGB
Pixel &pixel = GetPixel(p);
XYZToRGB(pixel.xyz, &rgb[3 * offset]);

std::array<Float, 3> xyz = { Float(0), Float(0), Float(0) };
// Normalize pixel with weight sum
Float filterWeightSum = pixel.filterWeightSum;
if (filterWeightSum != 0) {
Float invWt = (Float)1 / filterWeightSum;
rgb[3 * offset] = std::max((Float)0, rgb[3 * offset] * invWt);
rgb[3 * offset + 1] =
std::max((Float)0, rgb[3 * offset + 1] * invWt);
rgb[3 * offset + 2] =
std::max((Float)0, rgb[3 * offset + 2] * invWt);
for (int c = 0; c < 3; ++c)
xyz[c] = pixel.xyz[c] * invWt;
}

// Add splat value at pixel
Float splatRGB[3];
Float splatXYZ[3] = {pixel.splatXYZ[0], pixel.splatXYZ[1],
pixel.splatXYZ[2]};
XYZToRGB(splatXYZ, splatRGB);
rgb[3 * offset] += splatScale * splatRGB[0];
rgb[3 * offset + 1] += splatScale * splatRGB[1];
rgb[3 * offset + 2] += splatScale * splatRGB[2];
for (int c = 0; c < 3; ++c)
xyz[c] += splatScale * pixel.splatXYZ[c];

// Scale pixel value by _scale_
rgb[3 * offset] *= scale;
rgb[3 * offset + 1] *= scale;
rgb[3 * offset + 2] *= scale;
++offset;
for (int c = 0; c < 3; ++c)
xyz[c] *= scale;

Point2i pOffset(p.x - croppedPixelBounds.pMin.x,
p.y - croppedPixelBounds.pMin.y);
rgb32.SetSpectrum(pOffset, Spectrum::FromXYZ(&xyz[0]));
}

// Write RGB image
LOG(INFO) << "Writing image " << filename << " with bounds " <<
croppedPixelBounds;
pbrt::WriteImage(filename, &rgb[0], croppedPixelBounds, fullResolution);
rgb32.Write(filename, croppedPixelBounds, fullResolution);
}

Film *CreateFilm(const ParamSet &params, std::unique_ptr<Filter> filter) {
Expand Down
194 changes: 194 additions & 0 deletions src/core/fp16.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@

/*
pbrt source code is Copyright(c) 1998-2016
Matt Pharr, Greg Humphreys, and Wenzel Jakob.

This file is part of pbrt.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/


#ifndef PBRT_CORE_HALF_H
#define PBRT_CORE_HALF_H

#include "pbrt.h"
#include <stdint.h>

namespace pbrt {

// TODO: define a small Half struct/class?

#ifdef PBRT_HAVE_BINARY_CONSTANTS
static const int kHalfExponentMask = 0b0111110000000000;
static const int kHalfSignificandMask = 0b1111111111;
static const int kHalfNegativeZero = 0b1000000000000000;
static const int kHalfPositiveZero = 0;
// Exponent all 1s, significand zero
static const int kHalfNegativeInfinity = 0b1111110000000000;
static const int kHalfPositiveInfinity = 0b0111110000000000;
#else
static const int kHalfExponentMask = 0x7c00;
static const int kHalfSignificandMask = 0x3ff;
static const int kHalfNegativeZero = 0x8000;
static const int kHalfPositiveZero = 0;
// Exponent all 1s, significand zero
static const int kHalfNegativeInfinity = 0xfc00;
static const int kHalfPositiveInfinity = 0x7c00;
#endif

inline bool HalfIsInf(uint16_t h) {
return h == kHalfPositiveInfinity || h == kHalfNegativeInfinity;
}

// -1, 1
inline int HalfSign(uint16_t h) { return (h >> 15) ? -1 : 1; }

inline bool HalfIsNaN(uint16_t h) {
return ((h & kHalfExponentMask) == kHalfExponentMask &&
(h & kHalfSignificandMask) != 0);
}

inline uint16_t NextHalfUp(uint16_t v) {
if (HalfIsInf(v) && HalfSign(v) == 1) return v;
if (v == kHalfNegativeZero) v = kHalfPositiveZero;

// Advance _v_ to next higher float
if (HalfSign(v) >= 0)
++v;
else
--v;
return v;
}

inline uint16_t NextHalfDown(uint16_t v) {
if (HalfIsInf(v) && HalfSign(v) == -1) return v;
if (v == kHalfPositiveZero) v = kHalfNegativeZero;
if (v > 0)
--v;
else
++v;
return v;
}

// TODO: these should live in maybe a new core/fp.h file (that also
// picks up a bunch of other stuff...)
// TODO: support for non-AVX systems, check CPUID stuff, etc..

// https://gist.github.com/rygorous/2156668
union FP32 {
uint32_t u;
float f;
struct {
unsigned int Mantissa : 23;
unsigned int Exponent : 8;
unsigned int Sign : 1;
};
};

union FP16 {
uint16_t u;
struct {
unsigned int Mantissa : 10;
unsigned int Exponent : 5;
unsigned int Sign : 1;
};
};

// Same, but rounding ties to nearest even instead of towards +inf
inline uint16_t FloatToHalf(float ff) {
FP32 f;
f.f = ff;
FP32 f32infty = {255 << 23};
FP32 f16max = {(127 + 16) << 23};
FP32 denorm_magic = {((127 - 15) + (23 - 10) + 1) << 23};
unsigned int sign_mask = 0x80000000u;
FP16 o = {0};

unsigned int sign = f.u & sign_mask;
f.u ^= sign;

// NOTE all the integer compares in this function can be safely
// compiled into signed compares since all operands are below
// 0x80000000. Important if you want fast straight SSE2 code
// (since there's no unsigned PCMPGTD).

if (f.u >= f16max.u) // result is Inf or NaN (all exponent bits set)
o.u = (f.u > f32infty.u) ? 0x7e00 : 0x7c00; // NaN->qNaN and Inf->Inf
else // (De)normalized number or zero
{
if (f.u < (113 << 23)) // resulting FP16 is subnormal or zero
{
// use a magic value to align our 10 mantissa bits at the bottom of
// the float. as long as FP addition is round-to-nearest-even this
// just works.
f.f += denorm_magic.f;

// and one integer subtract of the bias later, we have our final
// float!
o.u = f.u - denorm_magic.u;
} else {
unsigned int mant_odd = (f.u >> 13) & 1; // resulting mantissa is odd

// update exponent, rounding bias part 1
f.u += (uint32_t(15 - 127) << 23) + 0xfff;
// rounding bias part 2
f.u += mant_odd;
// take the bits!
o.u = f.u >> 13;
}
}

o.u |= sign >> 16;
return o.u;
}

inline float HalfToFloat(uint16_t hh) {
FP16 h;
h.u = hh;
static const FP32 magic = {113 << 23};
static const unsigned int shifted_exp = 0x7c00 << 13; // exponent mask after shift
FP32 o;

o.u = (h.u & 0x7fff) << 13; // exponent/mantissa bits
unsigned int exp = shifted_exp & o.u; // just the exponent
o.u += (127 - 15) << 23; // exponent adjust

// handle exponent special cases
if (exp == shifted_exp) // Inf/NaN?
o.u += (128 - 16) << 23; // extra exp adjust
else if (exp == 0) // Zero/Denormal?
{
o.u += 1 << 23; // extra exp adjust
o.f -= magic.f; // renormalize
}

o.u |= (h.u & 0x8000) << 16; // sign bit
return o.f;
}

} // namespace pbrt

#endif // PBRT_CORE_HALF_H
Loading