Support for canceling preprocess tasks -- fixes Bug #9

metadata
Wenzel Jakob 2010-09-14 01:45:24 +02:00
parent 59ff88d45a
commit 74f6e540e2
14 changed files with 110 additions and 31 deletions

View File

@ -41,7 +41,7 @@ public:
* which have been made available to all local and remote workers.
* The default implementation simply returns.
*/
virtual void preprocess(const Scene *scene, RenderQueue *queue,
virtual bool preprocess(const Scene *scene, RenderQueue *queue,
const RenderJob *job, int sceneResID, int cameraResID,
int samplerResID);

View File

@ -86,7 +86,7 @@ public:
* which have been made available to all local and remote workers.
* Returns true upon successful completion.
*/
void preprocess(RenderQueue *queue, const RenderJob *job,
bool preprocess(RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID);
/**

View File

@ -34,9 +34,12 @@ public:
* resource IDs of the associated scene, camera and sample generator,
* which have been made available to all local and remote workers.
*/
virtual void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
virtual bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) = 0;
/// Cancel any running pre-process tasks
virtual void cancel() = 0;
/// Return the list of shapes associated with this subsurface integrator
inline const std::vector<Shape *> getShapes() const { return m_shapes; }

View File

@ -87,9 +87,10 @@ public:
m_subIntegrator->configureSampler(sampler);
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
if (!SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
if (m_subIntegrator == NULL)
Log(EError, "No sub-integrator was specified!");
Sampler *sampler = static_cast<Sampler *>(Scheduler::getInstance()->getResource(samplerResID, 0));
@ -97,7 +98,8 @@ public:
if (sampler->getClass()->getName() != "IndependentSampler")
Log(EError, "The error-controlling integrator should only be "
"used in conjunction with the independent sampler");
m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
if (!m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
Vector2i filmSize = camera->getFilm()->getSize();
bool needsLensSample = camera->needsLensSample();
@ -122,6 +124,7 @@ public:
m_quantile = (Float) normalQuantile(1-m_pval/2);
Log(EInfo, "Configuring for a %.1f%% confidence interval, quantile=%f, avg. luminance=%f",
(1-m_pval)*100, m_quantile, m_averageLuminance);
return true;
}
void renderBlock(const Scene *scene, const Camera *camera, Sampler *sampler,
@ -239,6 +242,12 @@ public:
m_subIntegrator->wakeup(params);
}
void cancel() {
SampleIntegrator::cancel();
m_subIntegrator->cancel();
}
const Integrator *getSubIntegrator() const {
return m_subIntegrator.get();
}

View File

@ -147,14 +147,16 @@ public:
}
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
if (!SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
if (m_subIntegrator == NULL)
Log(EError, "No sub-integrator was specified!");
m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
if (!m_subIntegrator->preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID))
return false;
ref<Scheduler> sched = Scheduler::getInstance();
m_irrCache = new IrradianceCache(scene->getAABB());
@ -185,6 +187,7 @@ public:
int subIntegratorResID = sched->registerResource(m_subIntegrator);
ref<OvertureProcess> proc = new OvertureProcess(job, m_resolution, m_gradients,
m_clampNeighbor, m_clampScreen, m_influenceMin, m_influenceMax, m_quality);
m_proc = proc;
proc->bindResource("scene", sceneResID);
proc->bindResource("camera", cameraResID);
proc->bindResource("subIntegrator", subIntegratorResID);
@ -192,9 +195,12 @@ public:
sched->schedule(proc);
sched->unregisterResource(subIntegratorResID);
sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
Log(EError, "The overture pass did not complete sucessfully!");
if (proc->getReturnStatus() != ParallelProcess::ESuccess) {
Log(EWarn, "The overture pass did not complete sucessfully!");
return false;
}
ref<const IrradianceRecordVector> vec = proc->getSamples();
Log(EDebug, "Overture pass generated %i irradiance samples", vec->size());
@ -203,6 +209,16 @@ public:
m_irrCache->setQuality(m_quality * m_qualityAdjustment);
}
return true;
}
void cancel() {
if (m_proc) {
Scheduler::getInstance()->cancel(m_proc);
} else {
SampleIntegrator::cancel();
m_subIntegrator->cancel();
}
}
Spectrum Li(const RayDifferential &ray, RadianceQueryRecord &rRec) const {
@ -316,6 +332,7 @@ private:
mutable ThreadLocal<Sampler> m_sampleGenerator;
mutable ref<IrradianceCache> m_irrCache;
ref<SampleIntegrator> m_subIntegrator;
ref<ParallelProcess> m_proc;
int m_resolution;
Float m_influenceMin, m_influenceMax;
Float m_quality, m_qualityAdjustment;

View File

@ -80,7 +80,7 @@ public:
stream->writeBool(m_multipleScattering);
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -91,6 +91,7 @@ public:
if (scene->getSubsurfaceIntegrators().size() > 0)
Log(EError, "Subsurface integrators are not supported by the particle tracer!");
m_sampleCount = scene->getSampler()->getSampleCount() * size.x * size.y;
return true;
}
void cancel() {

View File

@ -114,7 +114,7 @@ public:
sampler->request2DArray(m_glossySamples);
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
SampleIntegrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
/* Create a deterministic sampler for the photon gathering step */
@ -151,8 +151,13 @@ public:
proc->bindResource("scene", sceneResID);
proc->bindResource("sampler", qmcSamplerID);
m_proc = proc;
sched->schedule(proc);
sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
m_globalPhotonMap = proc->getPhotonMap();
m_globalPhotonMap->setScale(1 / (Float) proc->getShotPhotons());
@ -175,8 +180,13 @@ public:
proc->bindResource("scene", sceneResID);
proc->bindResource("sampler", qmcSamplerID);
m_proc = proc;
sched->schedule(proc);
sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
m_causticPhotonMap = proc->getPhotonMap();
m_causticPhotonMap->setScale(1 / (Float) proc->getShotPhotons());
@ -199,8 +209,13 @@ public:
proc->bindResource("scene", sceneResID);
proc->bindResource("sampler", qmcSamplerID);
m_proc = proc;
sched->schedule(proc);
sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
m_volumePhotonMap = proc->getPhotonMap();
m_volumePhotonMap->setScale(1 / (Float) proc->getShotPhotons());
@ -212,6 +227,7 @@ public:
}
sched->unregisterResource(qmcSamplerID);
return true;
}
/// Specify globally shared resources
@ -240,6 +256,12 @@ public:
}
void cancel() {
SampleIntegrator::cancel();
if (m_proc)
Scheduler::getInstance()->cancel(m_proc);
}
Spectrum Li(const RayDifferential &ray, RadianceQueryRecord &rRec) const {
Spectrum Li(0.0f), LiVol(0.0f);
Intersection &its = rRec.its;
@ -375,6 +397,7 @@ private:
ref<PhotonMap> m_globalPhotonMap;
ref<PhotonMap> m_causticPhotonMap;
ref<PhotonMap> m_volumePhotonMap;
ref<ParallelProcess> m_proc;
SampleIntegrator *m_parentIntegrator;
int m_globalPhotonMapID, m_causticPhotonMapID, m_volumePhotonMapID;
size_t m_globalPhotons, m_causticPhotons, m_volumePhotons;

View File

@ -90,7 +90,7 @@ public:
m_running = false;
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -102,6 +102,7 @@ public:
m_initialRadius = std::min(rad / filmSize.x, rad / filmSize.y) * 5;
}
return true;
}
bool render(Scene *scene, RenderQueue *queue,

View File

@ -86,7 +86,7 @@ public:
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -98,6 +98,7 @@ public:
m_initialRadius = std::min(rad / filmSize.x, rad / filmSize.y) * 5;
}
return true;
}
bool render(Scene *scene, RenderQueue *queue,

View File

@ -70,7 +70,7 @@ public:
m_shaderManager->drawBackground(clipToWorld, camPos);
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
Integrator::preprocess(scene, queue, job, sceneResID, cameraResID, samplerResID);
@ -80,6 +80,7 @@ public:
m_vpls[i].P *= normalization;
Log(EInfo, "Generated %i virtual point lights", m_vpls.size());
}
return true;
}
void cancel() {

View File

@ -32,8 +32,8 @@ Integrator::Integrator(Stream *stream, InstanceManager *manager)
: NetworkedObject(stream, manager) {
}
void Integrator::preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { }
bool Integrator::preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { return true; }
void Integrator::postprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) { }
void Integrator::configureSampler(Sampler *sampler) { }
@ -98,7 +98,8 @@ Spectrum SampleIntegrator::E(const Scene *scene, const Point &p, const Normal &n
}
void SampleIntegrator::cancel() {
Scheduler::getInstance()->cancel(m_process);
if (m_process)
Scheduler::getInstance()->cancel(m_process);
}
bool SampleIntegrator::render(Scene *scene,

View File

@ -107,14 +107,20 @@ void RenderJob::run() {
bool cancelled = false;
m_scene->initialize();
try {
m_scene->preprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID);
if (!m_scene->render(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID)) {
if (!m_scene->preprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID)) {
cancelled = true;
Log(EWarn, "Rendering of scene \"%s\" did not complete successfully!",
Log(EWarn, "Preprocessing of scene \"%s\" did not complete successfully!",
m_scene->getSourceFile().leaf().c_str());
}
m_scene->postprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID);
if (!cancelled) {
if (!m_scene->render(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID)) {
cancelled = true;
Log(EWarn, "Rendering of scene \"%s\" did not complete successfully!",
m_scene->getSourceFile().leaf().c_str());
}
m_scene->postprocess(m_queue, this, m_sceneResID, m_cameraResID, m_samplerResID);
}
if (m_testSupervisor.get())
m_testSupervisor->analyze(m_scene);

View File

@ -282,23 +282,26 @@ void Scene::initialize() {
}
}
void Scene::preprocess(RenderQueue *queue, const RenderJob *job,
bool Scene::preprocess(RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
/* Pre-process step for the main scene integrator */
m_integrator->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID);
if (!m_integrator->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID))
return false;
/* Pre-process step for all sub-surface integrators */
for (std::vector<Subsurface *>::iterator it = m_ssIntegrators.begin();
it != m_ssIntegrators.end(); ++it)
(*it)->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID);
if (!(*it)->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID))
return false;
/* Pre-process step for all participating media */
for (std::vector<Medium *>::iterator it = m_media.begin();
it != m_media.end(); ++it)
(*it)->preprocess(this, queue, job,
sceneResID, cameraResID, samplerResID);
return true;
}
bool Scene::render(RenderQueue *queue, const RenderJob *job,
@ -309,6 +312,9 @@ bool Scene::render(RenderQueue *queue, const RenderJob *job,
}
void Scene::cancel() {
for (std::vector<Subsurface *>::iterator it = m_ssIntegrators.begin();
it != m_ssIntegrators.end(); ++it)
(*it)->cancel();
m_integrator->cancel();
}

View File

@ -239,10 +239,10 @@ public:
return 0.5f * temp1 * temp1 * (1.0f + temp2 * temp2);
}
void preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
bool preprocess(const Scene *scene, RenderQueue *queue, const RenderJob *job,
int sceneResID, int cameraResID, int samplerResID) {
if (m_ready)
return;
return true;
if (!scene->getIntegrator()->getClass()
->derivesFrom(SampleIntegrator::m_theClass)) {
@ -280,8 +280,12 @@ public:
proc->bindResource("scene", sceneResID);
scene->bindUsedResources(proc);
m_proc = proc;
sched->schedule(proc);
sched->wait(proc);
m_proc = NULL;
if (proc->getReturnStatus() != ParallelProcess::ESuccess)
return false;
const IrradianceRecordVector &results = *proc->getSamples();
for (size_t i=0; i<results.size(); ++i)
@ -291,6 +295,7 @@ public:
m_octreeResID = Scheduler::getInstance()->registerResource(m_octree);
m_ready = true;
return false;
}
void wakeup(std::map<std::string, SerializableObject *> &params) {
@ -301,6 +306,10 @@ public:
}
}
void cancel() {
Scheduler::getInstance()->cancel(m_proc);
}
MTS_DECLARE_CLASS()
private:
Float m_minMFP, m_sampleMultiplier;
@ -308,6 +317,7 @@ private:
Spectrum m_mfp, m_sigmaTr, m_zr, m_zv, m_alphaPrime;
Spectrum m_sigmaSPrime, m_sigmaTPrime, m_D, m_ssFactor;
ref<IrradianceOctree> m_octree;
ref<ParallelProcess> m_proc;
int m_octreeResID, m_octreeIndex;
int m_maxDepth;
bool m_ready, m_requireSample;