From b5e1419e5be6cf2dbbb5fd8868dadea17dc23fbf Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 3 Aug 2012 15:18:42 +0000 Subject: [PATCH] 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. --- intern/cycles/blender/blender_session.cpp | 53 +++++++++++------------ intern/cycles/blender/blender_session.h | 13 +++--- intern/cycles/blender/blender_util.h | 1 - intern/cycles/device/device_cpu.cpp | 2 + intern/cycles/device/device_cuda.cpp | 6 ++- intern/cycles/device/device_opencl.cpp | 10 ++++- intern/cycles/render/buffers.cpp | 2 +- intern/cycles/render/buffers.h | 3 +- intern/cycles/render/session.cpp | 17 ++++---- intern/cycles/render/session.h | 4 +- intern/cycles/util/util_progress.h | 24 +++++----- 11 files changed, 73 insertions(+), 62 deletions(-) diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 540f6294820..2ebeedc8218 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -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 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() diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h index 5f458aa888b..4666b5982e1 100644 --- a/intern/cycles/blender/blender_session.h +++ b/intern/cycles/blender/blender_session.h @@ -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 diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index ab1f7cf7907..b08c1e7e765 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -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 diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp index 9febd7ae27c..fe32e9a2760 100644 --- a/intern/cycles/device/device_cpu.cpp +++ b/intern/cycles/device/device_cpu.cpp @@ -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); } } diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index 35f541d0c9c..c8dcfdc2f3d 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -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); } diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 471ada60eea..3c78b4895ae 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -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); } } diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index bd8c6cd22dd..51568f65323 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -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; diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h index f8df2b3587e..ee0d78a1cd8 100644 --- a/intern/cycles/render/buffers.h +++ b/intern/cycles/render/buffers.h @@ -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; diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index addd97ca840..3bd2c6af6d8 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -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 */ diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index be834409756..6c5e40bca63 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -105,8 +105,8 @@ public: TileManager tile_manager; int sample; - boost::function write_render_buffers_cb; - boost::function update_render_buffers_cb; + boost::function write_render_tile_cb; + boost::function update_render_tile_cb; Session(const SessionParams& params); ~Session(); diff --git a/intern/cycles/util/util_progress.h b/intern/cycles/util/util_progress.h index c63aa841c52..e21f1b90166 100644 --- a/intern/cycles/util/util_progress.h +++ b/intern/cycles/util/util_progress.h @@ -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 update_cb; boost::function cancel_cb; - int sample; + int tile; double start_time; double total_time; - double sample_time; + double tile_time; string status; string substatus;