Tomato Cycles: internal cleanup of tile-based integrator
This commit solves couple of issues appeared with new integrator: - Render job progress bar is now shows progress based on number of rendered tiles. This is the same as Blender Internal does. This still requires some further thoughts because for GPU it's better to use single tile and in this case progress bar should be based on number of rendered samples. - Removes "global" sample counter from progress descriptor. There's no more global-being sample which makes sense. This counter was replaced with tile counter. - Use proper sample number when copying render buffer to blender. It used to be final sample number used which lead to tiles appearing from complete dark to normal brightness as they're being rendered. Now tile would be displayed with proper brightness starting from the very first sample. Use sample counter stored in render tile descriptor and pass it to update / write callbacks. This was tested on CPU and GPU CUDA rendering. Additional change: OpenCL rendering now should be cancellable before it finished rendering all the samples (the same change as for CPU/CUDA from a while ago). This part of commit wasn't actually tested, would do it later.
This commit is contained in:
@@ -189,9 +189,9 @@ static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr,
|
||||
RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data, (int)cancel);
|
||||
}
|
||||
|
||||
void BlenderSession::do_write_update_render_buffers(RenderBuffers *buffers, bool do_update_only)
|
||||
void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only)
|
||||
{
|
||||
BufferParams& params = buffers->params;
|
||||
BufferParams& params = rtile.buffers->params;
|
||||
int x = params.full_x - session->tile_manager.params.full_x;
|
||||
int y = params.full_y - session->tile_manager.params.full_y;
|
||||
int w = params.width;
|
||||
@@ -211,31 +211,31 @@ void BlenderSession::do_write_update_render_buffers(RenderBuffers *buffers, bool
|
||||
|
||||
if (do_update_only) {
|
||||
/* update only needed */
|
||||
update_render_result(b_rr, b_rlay, buffers);
|
||||
update_render_result(b_rr, b_rlay, rtile);
|
||||
end_render_result(b_engine, b_rr, true);
|
||||
}
|
||||
else {
|
||||
/* write result */
|
||||
write_render_result(b_rr, b_rlay, buffers);
|
||||
write_render_result(b_rr, b_rlay, rtile);
|
||||
end_render_result(b_engine, b_rr);
|
||||
}
|
||||
}
|
||||
|
||||
void BlenderSession::write_render_buffers(RenderBuffers *buffers)
|
||||
void BlenderSession::write_render_tile(RenderTile& rtile)
|
||||
{
|
||||
do_write_update_render_buffers(buffers, false);
|
||||
do_write_update_render_tile(rtile, false);
|
||||
}
|
||||
|
||||
void BlenderSession::update_render_buffers(RenderBuffers *buffers)
|
||||
void BlenderSession::update_render_tile(RenderTile& rtile)
|
||||
{
|
||||
do_write_update_render_buffers(buffers, true);
|
||||
do_write_update_render_tile(rtile, true);
|
||||
}
|
||||
|
||||
void BlenderSession::render()
|
||||
{
|
||||
/* set callback to write out render results */
|
||||
session->write_render_buffers_cb = function_bind(&BlenderSession::write_render_buffers, this, _1);
|
||||
session->update_render_buffers_cb = function_bind(&BlenderSession::update_render_buffers, this, _1);
|
||||
session->write_render_tile_cb = function_bind(&BlenderSession::write_render_tile, this, _1);
|
||||
session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1);
|
||||
|
||||
/* get buffer parameters */
|
||||
SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
|
||||
@@ -305,22 +305,20 @@ void BlenderSession::render()
|
||||
}
|
||||
|
||||
/* clear callback */
|
||||
session->write_render_buffers_cb = NULL;
|
||||
session->update_render_buffers_cb = NULL;
|
||||
session->write_render_tile_cb = NULL;
|
||||
session->update_render_tile_cb = NULL;
|
||||
}
|
||||
|
||||
void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderBuffers *buffers, bool do_update_only)
|
||||
void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only)
|
||||
{
|
||||
RenderBuffers *buffers = rtile.buffers;
|
||||
|
||||
/* copy data from device */
|
||||
if(!buffers->copy_from_device())
|
||||
return;
|
||||
|
||||
BufferParams& params = buffers->params;
|
||||
float exposure = scene->film->exposure;
|
||||
double total_time, sample_time;
|
||||
int sample;
|
||||
|
||||
session->progress.get_sample(sample, total_time, sample_time);
|
||||
|
||||
vector<float> pixels(params.width*params.height*4);
|
||||
|
||||
@@ -336,27 +334,27 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::Re
|
||||
int components = b_pass.channels();
|
||||
|
||||
/* copy pixels */
|
||||
if(buffers->get_pass(pass_type, exposure, sample, components, &pixels[0]))
|
||||
if(buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0]))
|
||||
rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy combined pass */
|
||||
if(buffers->get_pass(PASS_COMBINED, exposure, sample, 4, &pixels[0]))
|
||||
if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0]))
|
||||
rna_RenderLayer_rect_set(&b_rlay.ptr, &pixels[0]);
|
||||
|
||||
/* tag result as updated */
|
||||
RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
|
||||
}
|
||||
|
||||
void BlenderSession::write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderBuffers *buffers)
|
||||
void BlenderSession::write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile)
|
||||
{
|
||||
do_write_update_render_result(b_rr, b_rlay, buffers, false);
|
||||
do_write_update_render_result(b_rr, b_rlay, rtile, false);
|
||||
}
|
||||
|
||||
void BlenderSession::update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderBuffers *buffers)
|
||||
void BlenderSession::update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile)
|
||||
{
|
||||
do_write_update_render_result(b_rr, b_rlay, buffers, true);
|
||||
do_write_update_render_result(b_rr, b_rlay, rtile, true);
|
||||
}
|
||||
|
||||
void BlenderSession::synchronize()
|
||||
@@ -461,11 +459,12 @@ void BlenderSession::get_status(string& status, string& substatus)
|
||||
|
||||
void BlenderSession::get_progress(float& progress, double& total_time)
|
||||
{
|
||||
double sample_time;
|
||||
int sample;
|
||||
double tile_time;
|
||||
int tile;
|
||||
int tile_total = session->tile_manager.state.num_tiles;
|
||||
|
||||
session->progress.get_sample(sample, total_time, sample_time);
|
||||
progress = ((float)sample/(float)session->params.samples);
|
||||
session->progress.get_tile(tile, total_time, tile_time);
|
||||
progress = ((float)tile/(float)tile_total);
|
||||
}
|
||||
|
||||
void BlenderSession::update_status_progress()
|
||||
|
||||
@@ -30,6 +30,7 @@ CCL_NAMESPACE_BEGIN
|
||||
class Scene;
|
||||
class Session;
|
||||
class RenderBuffers;
|
||||
class RenderTile;
|
||||
|
||||
class BlenderSession {
|
||||
public:
|
||||
@@ -48,14 +49,14 @@ public:
|
||||
/* offline render */
|
||||
void render();
|
||||
|
||||
void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderBuffers *buffers);
|
||||
void write_render_buffers(RenderBuffers *buffers);
|
||||
void write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile);
|
||||
void write_render_tile(RenderTile& rtile);
|
||||
|
||||
/* update functions are used to update display buffer only after sample was rendered
|
||||
* only needed for better visual feedback
|
||||
*/
|
||||
void update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderBuffers *buffers);
|
||||
void update_render_buffers(RenderBuffers *buffers);
|
||||
void update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile);
|
||||
void update_render_tile(RenderTile& rtile);
|
||||
|
||||
/* interactive updates */
|
||||
void synchronize();
|
||||
@@ -89,8 +90,8 @@ public:
|
||||
int width, height;
|
||||
|
||||
protected:
|
||||
void do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderBuffers *buffers, bool do_update_only);
|
||||
void do_write_update_render_buffers(RenderBuffers *buffers, bool do_update_only);
|
||||
void do_write_update_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile, bool do_update_only);
|
||||
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
||||
@@ -55,7 +55,6 @@ void rna_ColorRamp_eval(void *coba, float position, float color[4]);
|
||||
void rna_Scene_frame_set(void *scene, int frame, float subframe);
|
||||
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
|
||||
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
|
||||
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
@@ -167,6 +167,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
tile.sample = sample + 1;
|
||||
task.update_progress(tile);
|
||||
}
|
||||
}
|
||||
@@ -189,6 +190,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
tile.sample = sample + 1;
|
||||
task.update_progress(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -837,11 +837,13 @@ public:
|
||||
int end_sample = tile.start_sample + tile.num_samples;
|
||||
|
||||
for(int sample = start_sample; sample < end_sample; sample++) {
|
||||
if (task->get_cancel()) {
|
||||
if (task->get_cancel())
|
||||
break;
|
||||
}
|
||||
|
||||
path_trace(tile, sample);
|
||||
|
||||
tile.sample = sample + 1;
|
||||
|
||||
task->update_progress(tile);
|
||||
}
|
||||
|
||||
|
||||
@@ -685,9 +685,17 @@ public:
|
||||
int start_sample = tile.start_sample;
|
||||
int end_sample = tile.start_sample + tile.num_samples;
|
||||
|
||||
for(int sample = start_sample; sample < end_sample; sample++)
|
||||
for(int sample = start_sample; sample < end_sample; sample++) {
|
||||
if (task->get_cancel())
|
||||
break;
|
||||
|
||||
path_trace(tile, sample);
|
||||
|
||||
tile.sample = sample + 1;
|
||||
|
||||
task->update_progress(tile);
|
||||
}
|
||||
|
||||
task->release_tile(tile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ bool RenderBuffers::copy_from_device()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderBuffers::get_pass(PassType type, float exposure, int sample, int components, float *pixels)
|
||||
bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int components, float *pixels)
|
||||
{
|
||||
int pass_offset = 0;
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
void reset(Device *device, BufferParams& params);
|
||||
|
||||
bool copy_from_device();
|
||||
bool get_pass(PassType type, float exposure, int sample, int components, float *pixels);
|
||||
bool get_pass_rect(PassType type, float exposure, int sample, int components, float *pixels);
|
||||
|
||||
protected:
|
||||
void device_free();
|
||||
@@ -129,6 +129,7 @@ public:
|
||||
int x, y, w, h;
|
||||
int start_sample;
|
||||
int num_samples;
|
||||
int sample;
|
||||
int resolution;
|
||||
int offset;
|
||||
int stride;
|
||||
|
||||
@@ -339,7 +339,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
|
||||
|
||||
/* in case of a permant buffer, return it, otherwise we will allocate
|
||||
* a new temporary buffer */
|
||||
if(!write_render_buffers_cb) {
|
||||
if(!write_render_tile_cb) {
|
||||
tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
|
||||
|
||||
rtile.buffer = buffers->buffer.device_pointer;
|
||||
@@ -377,11 +377,11 @@ void Session::update_tile_sample(RenderTile& rtile)
|
||||
{
|
||||
thread_scoped_lock tile_lock(tile_mutex);
|
||||
|
||||
if(update_render_buffers_cb) {
|
||||
if(update_render_tile_cb) {
|
||||
/* todo: optimize this by making it thread safe and removing lock */
|
||||
|
||||
if(!progress.get_cancel())
|
||||
update_render_buffers_cb(rtile.buffers);
|
||||
update_render_tile_cb(rtile);
|
||||
}
|
||||
|
||||
update_status_time();
|
||||
@@ -391,10 +391,10 @@ void Session::release_tile(RenderTile& rtile)
|
||||
{
|
||||
thread_scoped_lock tile_lock(tile_mutex);
|
||||
|
||||
if(write_render_buffers_cb) {
|
||||
if(write_render_tile_cb) {
|
||||
/* todo: optimize this by making it thread safe and removing lock */
|
||||
if(!progress.get_cancel())
|
||||
write_render_buffers_cb(rtile.buffers);
|
||||
write_render_tile_cb(rtile);
|
||||
delete rtile.buffers;
|
||||
}
|
||||
|
||||
@@ -648,8 +648,6 @@ void Session::update_scene()
|
||||
|
||||
void Session::update_status_time(bool show_pause, bool show_done)
|
||||
{
|
||||
int sample = tile_manager.state.sample;
|
||||
int num_samples = tile_manager.state.num_samples;
|
||||
int resolution = tile_manager.state.resolution;
|
||||
int num_tiles = tile_manager.state.num_tiles;
|
||||
int tile = tile_manager.state.num_rendered_tiles;
|
||||
@@ -677,14 +675,15 @@ void Session::update_status_time(bool show_pause, bool show_done)
|
||||
if(preview_time == 0.0 && resolution == 1)
|
||||
preview_time = time_dt();
|
||||
|
||||
double sample_time = (sample == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
|
||||
double tile_time = (tile == 0)? 0.0: (time_dt() - preview_time - paused_time)/(sample);
|
||||
|
||||
/* negative can happen when we pause a bit before rendering, can discard that */
|
||||
if(preview_time < 0.0) preview_time = 0.0;
|
||||
|
||||
progress.set_sample(sample + num_samples, sample_time);
|
||||
progress.set_tile(tile, tile_time);
|
||||
}
|
||||
|
||||
|
||||
void Session::path_trace()
|
||||
{
|
||||
/* add path trace task */
|
||||
|
||||
@@ -105,8 +105,8 @@ public:
|
||||
TileManager tile_manager;
|
||||
int sample;
|
||||
|
||||
boost::function<void(RenderBuffers*)> write_render_buffers_cb;
|
||||
boost::function<void(RenderBuffers*)> update_render_buffers_cb;
|
||||
boost::function<void(RenderTile&)> write_render_tile_cb;
|
||||
boost::function<void(RenderTile&)> update_render_tile_cb;
|
||||
|
||||
Session(const SessionParams& params);
|
||||
~Session();
|
||||
|
||||
@@ -36,10 +36,10 @@ class Progress {
|
||||
public:
|
||||
Progress()
|
||||
{
|
||||
sample = 0;
|
||||
tile = 0;
|
||||
start_time = time_dt();
|
||||
total_time = 0.0f;
|
||||
sample_time = 0.0f;
|
||||
tile_time = 0.0f;
|
||||
status = "Initializing";
|
||||
substatus = "";
|
||||
update_cb = NULL;
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
{
|
||||
thread_scoped_lock lock(progress.progress_mutex);
|
||||
|
||||
progress.get_sample(sample, total_time, sample_time);
|
||||
progress.get_status(status, substatus);
|
||||
progress.get_tile(tile, total_time, tile_time);
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
cancel_cb = function;
|
||||
}
|
||||
|
||||
/* sample and timing information */
|
||||
/* tile and timing information */
|
||||
|
||||
void set_start_time(double start_time_)
|
||||
{
|
||||
@@ -99,22 +99,22 @@ public:
|
||||
start_time = start_time_;
|
||||
}
|
||||
|
||||
void set_sample(int sample_, double sample_time_)
|
||||
void set_tile(int tile_, double tile_time_)
|
||||
{
|
||||
thread_scoped_lock lock(progress_mutex);
|
||||
|
||||
sample = sample_;
|
||||
tile = tile_;
|
||||
total_time = time_dt() - start_time;
|
||||
sample_time = sample_time_;
|
||||
tile_time = tile_time_;
|
||||
}
|
||||
|
||||
void get_sample(int& sample_, double& total_time_, double& sample_time_)
|
||||
void get_tile(int& tile_, double& total_time_, double& tile_time_)
|
||||
{
|
||||
thread_scoped_lock lock(progress_mutex);
|
||||
|
||||
sample_ = sample;
|
||||
tile_ = tile;
|
||||
total_time_ = (total_time > 0.0)? total_time: 0.0;
|
||||
sample_time_ = sample_time;
|
||||
tile_time_ = tile_time;
|
||||
}
|
||||
|
||||
/* status messages */
|
||||
@@ -170,11 +170,11 @@ protected:
|
||||
boost::function<void(void)> update_cb;
|
||||
boost::function<void(void)> cancel_cb;
|
||||
|
||||
int sample;
|
||||
int tile;
|
||||
|
||||
double start_time;
|
||||
double total_time;
|
||||
double sample_time;
|
||||
double tile_time;
|
||||
|
||||
string status;
|
||||
string substatus;
|
||||
|
||||
Reference in New Issue
Block a user