Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/render/session.cpp')
-rw-r--r--intern/cycles/render/session.cpp135
1 files changed, 119 insertions, 16 deletions
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index cd410e4e011..41212c2db84 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -34,16 +34,22 @@
CCL_NAMESPACE_BEGIN
+/* Note about preserve_tile_device option for tile manager:
+ * progressive refine and viewport rendering does requires tiles to
+ * always be allocated for the same device
+ */
Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
- (params.background)? 1: max(params.device.multi_devices.size(), 1))
+ params.background == false || params.progressive_refine, params.background,
+ max(params.device.multi_devices.size(), 1)),
+ stats()
{
device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
TaskScheduler::init(params.threads);
- device = Device::create(params.device, params.background, params.threads);
+ device = Device::create(params.device, stats, params.background);
if(params.background) {
buffers = NULL;
@@ -96,6 +102,9 @@ Session::~Session()
display->write(device, params.output_path);
}
+ foreach(RenderBuffers *buffers, tile_buffers)
+ delete buffers;
+
delete buffers;
delete display;
delete scene;
@@ -173,9 +182,12 @@ bool Session::draw_gpu(BufferParams& buffer_params)
void Session::run_gpu()
{
+ bool tiles_written = false;
+
start_time = time_dt();
reset_time = time_dt();
paused_time = 0.0;
+ last_update_time = time_dt();
if(!params.background)
progress.set_start_time(start_time + paused_time);
@@ -267,10 +279,15 @@ void Session::run_gpu()
if(device->error_message() != "")
progress.set_cancel(device->error_message());
+ tiles_written = update_progressive_refine(progress.get_cancel());
+
if(progress.get_cancel())
break;
}
}
+
+ if(!tiles_written)
+ update_progressive_refine(true);
}
/* CPU Session */
@@ -313,14 +330,18 @@ bool Session::draw_cpu(BufferParams& buffer_params)
bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
{
- if(progress.get_cancel())
- return false;
+ if(progress.get_cancel()) {
+ if(params.progressive_refine == false) {
+ /* for progressive refine current sample should be finished for all tiles */
+ return false;
+ }
+ }
thread_scoped_lock tile_lock(tile_mutex);
/* get next tile from manager */
Tile tile;
- int device_num = (params.background)? 0: device->device_number(tile_device);
+ int device_num = device->device_number(tile_device);
if(!tile_manager.next_tile(tile, device_num))
return false;
@@ -338,7 +359,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_tile_cb) {
+ if(!params.background) {
tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
rtile.buffer = buffers->buffer.device_pointer;
@@ -360,9 +381,30 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
buffer_params.get_offset_stride(rtile.offset, rtile.stride);
- /* allocate buffers */
RenderBuffers *tilebuffers = new RenderBuffers(tile_device);
- tilebuffers->reset(tile_device, buffer_params);
+
+ /* allocate buffers */
+ if(params.progressive_refine) {
+ tile_lock.lock();
+
+ if(tile_buffers.size() == 0)
+ tile_buffers.resize(tile_manager.state.num_tiles, NULL);
+
+ tilebuffers = tile_buffers[tile.index];
+ if(tilebuffers == NULL) {
+ tilebuffers = new RenderBuffers(tile_device);
+ tile_buffers[tile.index] = tilebuffers;
+
+ tilebuffers->reset(tile_device, buffer_params);
+ }
+
+ tile_lock.unlock();
+ }
+ else {
+ tilebuffers = new RenderBuffers(tile_device);
+
+ tilebuffers->reset(tile_device, buffer_params);
+ }
rtile.buffer = tilebuffers->buffer.device_pointer;
rtile.rng_state = tilebuffers->rng_state.device_pointer;
@@ -377,9 +419,11 @@ void Session::update_tile_sample(RenderTile& rtile)
thread_scoped_lock tile_lock(tile_mutex);
if(update_render_tile_cb) {
- /* todo: optimize this by making it thread safe and removing lock */
+ if(params.progressive_refine == false) {
+ /* todo: optimize this by making it thread safe and removing lock */
- update_render_tile_cb(rtile);
+ update_render_tile_cb(rtile);
+ }
}
update_status_time();
@@ -390,10 +434,12 @@ void Session::release_tile(RenderTile& rtile)
thread_scoped_lock tile_lock(tile_mutex);
if(write_render_tile_cb) {
- /* todo: optimize this by making it thread safe and removing lock */
- write_render_tile_cb(rtile);
+ if(params.progressive_refine == false) {
+ /* todo: optimize this by making it thread safe and removing lock */
+ write_render_tile_cb(rtile);
- delete rtile.buffers;
+ delete rtile.buffers;
+ }
}
update_status_time();
@@ -401,6 +447,10 @@ void Session::release_tile(RenderTile& rtile)
void Session::run_cpu()
{
+ bool tiles_written = false;
+
+ last_update_time = time_dt();
+
{
/* reset once to start */
thread_scoped_lock reset_lock(delayed_reset.mutex);
@@ -502,10 +552,15 @@ void Session::run_cpu()
if(device->error_message() != "")
progress.set_cancel(device->error_message());
+
+ tiles_written = update_progressive_refine(progress.get_cancel());
}
progress.set_update();
}
+
+ if(!tiles_written)
+ update_progressive_refine(true);
}
void Session::run()
@@ -657,10 +712,13 @@ void Session::update_status_time(bool show_pause, bool show_done)
string status, substatus;
if(!params.progressive) {
+ bool is_gpu = params.device.type == DEVICE_CUDA || params.device.type == DEVICE_OPENCL;
+ bool is_multidevice = params.device.multi_devices.size() > 1;
+ bool is_cpu = params.device.type == DEVICE_CPU;
+
substatus = string_printf("Path Tracing Tile %d/%d", tile, num_tiles);
- if(params.device.type == DEVICE_CUDA || params.device.type == DEVICE_OPENCL ||
- (params.device.type == DEVICE_CPU && num_tiles == 1)) {
+ if((is_gpu && !is_multidevice) || (is_cpu && num_tiles == 1)) {
/* when rendering on GPU multithreading happens within single tile, as in
* tiles are handling sequentially and in this case we could display
* currently rendering sample number
@@ -722,6 +780,7 @@ void Session::path_trace()
task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1);
task.update_progress_sample = function_bind(&Session::update_progress_sample, this);
+ task.need_finish_queue = params.progressive_refine;
device->task_add(task);
}
@@ -752,5 +811,49 @@ void Session::tonemap()
display_outdated = false;
}
-CCL_NAMESPACE_END
+bool Session::update_progressive_refine(bool cancel)
+{
+ int sample = tile_manager.state.sample + 1;
+ bool write = sample == params.samples || cancel;
+ double current_time = time_dt();
+
+ if (current_time - last_update_time < 1.0) {
+ /* if last sample was processed, we need to write buffers anyway */
+ if (!write)
+ return false;
+ }
+
+ if(params.progressive_refine) {
+ foreach(RenderBuffers *buffers, tile_buffers) {
+ RenderTile rtile;
+ rtile.buffers = buffers;
+ rtile.sample = sample;
+
+ if(write)
+ write_render_tile_cb(rtile);
+ else
+ update_render_tile_cb(rtile);
+ }
+ }
+
+ last_update_time = current_time;
+
+ return write;
+}
+
+void Session::device_free()
+{
+ scene->device_free();
+
+ foreach(RenderBuffers *buffers, tile_buffers)
+ delete buffers;
+
+ tile_buffers.clear();
+
+ /* used from background render only, so no need to
+ * re-create render/display buffers here
+ */
+}
+
+CCL_NAMESPACE_END