[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51299] trunk/blender: Cycles: progressive refine option

Sergey Sharybin sergey.vfx at gmail.com
Sat Oct 13 14:38:32 CEST 2012


Revision: 51299
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51299
Author:   nazgul
Date:     2012-10-13 12:38:32 +0000 (Sat, 13 Oct 2012)
Log Message:
-----------
Cycles: progressive refine option

Just makes progressive refine :)

This means the whole image would be refined gradually using as much
threads as it's set in performance settings. Having enough tiles is
required to have this option working as it's expected.

Technically it's implemented by repeatedly computing next sample for
all the tiles before switching to next sample.

This works around 7-12% slower than regular tile-based rendering, so
use this option only if you really need it.

This commit also fixes progressive update of image when Save Buffers
option is enabled.

And one more thing this commit fixes is handling display buffer with
Save Buffers option enabled. If this option is enabled image buffer
wouldn't have neither byte nor float buffer until image is fully
rendered which could backfire in missing image while rendering in
cases color management cache became full.

This issue solved by allocating byte buffer for image buffer from
tile update callback.

Patch was reviewed by Brecht. He also made some minor edits to
original version to patch. Thanks, man!

Modified Paths:
--------------
    trunk/blender/intern/cycles/blender/addon/properties.py
    trunk/blender/intern/cycles/blender/addon/ui.py
    trunk/blender/intern/cycles/blender/blender_session.cpp
    trunk/blender/intern/cycles/blender/blender_sync.cpp
    trunk/blender/intern/cycles/device/device_cpu.cpp
    trunk/blender/intern/cycles/device/device_cuda.cpp
    trunk/blender/intern/cycles/device/device_opencl.cpp
    trunk/blender/intern/cycles/device/device_task.h
    trunk/blender/intern/cycles/render/session.cpp
    trunk/blender/intern/cycles/render/session.h
    trunk/blender/intern/cycles/render/tile.cpp
    trunk/blender/intern/cycles/render/tile.h
    trunk/blender/source/blender/blenkernel/intern/image.c
    trunk/blender/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp
    trunk/blender/source/blender/editors/render/render_internal.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
    trunk/blender/source/blender/imbuf/IMB_colormanagement.h
    trunk/blender/source/blender/imbuf/intern/colormanagement.c

Modified: trunk/blender/intern/cycles/blender/addon/properties.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/properties.py	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/blender/addon/properties.py	2012-10-13 12:38:32 UTC (rev 51299)
@@ -284,6 +284,11 @@
                 description="Cache last built BVH to disk for faster re-render if no geometry changed",
                 default=False,
                 )
+        cls.use_progressive_refine = BoolProperty(
+                name="Progressive Refine",
+                description="Instead of rendering each tile until it is finished, refine the whole image progressively so rendering can be stopped manually when the noise is low enough",
+                default=False,
+                )
 
     @classmethod
     def unregister(cls):

Modified: trunk/blender/intern/cycles/blender/addon/ui.py
===================================================================
--- trunk/blender/intern/cycles/blender/addon/ui.py	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/blender/addon/ui.py	2012-10-13 12:38:32 UTC (rev 51299)
@@ -198,6 +198,8 @@
         sub.prop(rd, "parts_x", text="X")
         sub.prop(rd, "parts_y", text="Y")
 
+        sub.prop(cscene, "use_progressive_refine")
+
         subsub = sub.column()
         subsub.enabled = not rd.use_border
         subsub.prop(rd, "use_save_buffers")

Modified: trunk/blender/intern/cycles/blender/blender_session.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_session.cpp	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/blender/blender_session.cpp	2012-10-13 12:38:32 UTC (rev 51299)
@@ -466,9 +466,12 @@
 	session->progress.get_tile(tile, total_time, tile_time);
 
 	sample = session->progress.get_sample();
-	samples_per_tile = session->tile_manager.state.num_samples;
+	samples_per_tile = session->params.samples;
 
-	progress = ((float)sample/(float)(tile_total * samples_per_tile));
+	if(samples_per_tile)
+		progress = ((float)sample/(float)(tile_total * samples_per_tile));
+	else
+		progress = 0.0;
 }
 
 void BlenderSession::update_status_progress()

Modified: trunk/blender/intern/cycles/blender/blender_sync.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_sync.cpp	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/blender/blender_sync.cpp	2012-10-13 12:38:32 UTC (rev 51299)
@@ -380,8 +380,14 @@
 	params.reset_timeout = get_float(cscene, "debug_reset_timeout");
 	params.text_timeout = get_float(cscene, "debug_text_timeout");
 
+	params.progressive_refine = get_boolean(cscene, "use_progressive_refine");
+
 	if(background) {
-		params.progressive = false;
+		if(params.progressive_refine)
+			params.progressive = true;
+		else
+			params.progressive = false;
+
 		params.start_resolution = INT_MAX;
 	}
 	else

Modified: trunk/blender/intern/cycles/device/device_cpu.cpp
===================================================================
--- trunk/blender/intern/cycles/device/device_cpu.cpp	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/device/device_cpu.cpp	2012-10-13 12:38:32 UTC (rev 51299)
@@ -135,8 +135,10 @@
 
 	void thread_path_trace(DeviceTask& task)
 	{
-		if(task_pool.cancelled())
-			return;
+		if(task_pool.cancelled()) {
+			if(task.need_finish_queue == false)
+				return;
+		}
 
 #ifdef WITH_OSL
 		if(kernel_osl_use(kg))
@@ -154,8 +156,10 @@
 #ifdef WITH_OPTIMIZED_KERNEL
 			if(system_cpu_support_optimized()) {
 				for(int sample = start_sample; sample < end_sample; sample++) {
-					if (task.get_cancel() || task_pool.cancelled())
-						break;
+					if (task.get_cancel() || task_pool.cancelled()) {
+						if(task.need_finish_queue == false)
+							break;
+					}
 
 					for(int y = tile.y; y < tile.y + tile.h; y++) {
 						for(int x = tile.x; x < tile.x + tile.w; x++) {
@@ -173,8 +177,10 @@
 #endif
 			{
 				for(int sample = start_sample; sample < end_sample; sample++) {
-					if (task.get_cancel() || task_pool.cancelled())
-						break;
+					if (task.get_cancel() || task_pool.cancelled()) {
+						if(task.need_finish_queue == false)
+							break;
+					}
 
 					for(int y = tile.y; y < tile.y + tile.h; y++) {
 						for(int x = tile.x; x < tile.x + tile.w; x++) {
@@ -191,8 +197,10 @@
 
 			task.release_tile(tile);
 
-			if(task_pool.cancelled())
-				break;
+			if(task_pool.cancelled()) {
+				if(task.need_finish_queue == false)
+					break;
+			}
 		}
 
 #ifdef WITH_OSL

Modified: trunk/blender/intern/cycles/device/device_cuda.cpp
===================================================================
--- trunk/blender/intern/cycles/device/device_cuda.cpp	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/device/device_cuda.cpp	2012-10-13 12:38:32 UTC (rev 51299)
@@ -837,8 +837,10 @@
 				int end_sample = tile.start_sample + tile.num_samples;
 
 				for(int sample = start_sample; sample < end_sample; sample++) {
-					if (task->get_cancel())
-						break;
+					if (task->get_cancel()) {
+						if(task->need_finish_queue == false)
+							break;
+					}
 
 					path_trace(tile, sample);
 

Modified: trunk/blender/intern/cycles/device/device_opencl.cpp
===================================================================
--- trunk/blender/intern/cycles/device/device_opencl.cpp	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/device/device_opencl.cpp	2012-10-13 12:38:32 UTC (rev 51299)
@@ -686,8 +686,10 @@
 				int end_sample = tile.start_sample + tile.num_samples;
 
 				for(int sample = start_sample; sample < end_sample; sample++) {
-					if (task->get_cancel())
-						break;
+					if (task->get_cancel()) {
+						if(task->need_finish_queue == false)
+							break;
+					}
 
 					path_trace(tile, sample);
 

Modified: trunk/blender/intern/cycles/device/device_task.h
===================================================================
--- trunk/blender/intern/cycles/device/device_task.h	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/device/device_task.h	2012-10-13 12:38:32 UTC (rev 51299)
@@ -65,6 +65,7 @@
 	boost::function<void(RenderTile&)> release_tile;
 	boost::function<bool(void)> get_cancel;
 
+	bool need_finish_queue;
 protected:
 	double last_update_time;
 };

Modified: trunk/blender/intern/cycles/render/session.cpp
===================================================================
--- trunk/blender/intern/cycles/render/session.cpp	2012-10-13 12:11:01 UTC (rev 51298)
+++ trunk/blender/intern/cycles/render/session.cpp	2012-10-13 12:38:32 UTC (rev 51299)
@@ -96,6 +96,9 @@
 		display->write(device, params.output_path);
 	}
 
+	foreach(RenderBuffers *buffers, tile_buffers)
+		delete buffers;
+
 	delete buffers;
 	delete display;
 	delete scene;
@@ -173,6 +176,8 @@
 
 void Session::run_gpu()
 {
+	bool tiles_written = false;
+
 	start_time = time_dt();
 	reset_time = time_dt();
 	paused_time = 0.0;
@@ -267,10 +272,15 @@
 			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,8 +323,12 @@
 
 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);
 
@@ -338,7 +352,7 @@
 
 	/* 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,10 +374,36 @@
 
 	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) {
+		int tile_x = rtile.x / params.tile_size.x;
+		int tile_y = rtile.y / params.tile_size.y;
+
+		int tile_index = tile_y * tile_manager.state.tile_w + tile_x;
+
+		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;
 	rtile.rgba = 0;
@@ -377,9 +417,11 @@
 	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 +432,12 @@
 	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 +445,8 @@
 
 void Session::run_cpu()
 {
+	bool tiles_written = false;
+
 	{
 		/* reset once to start */
 		thread_scoped_lock reset_lock(delayed_reset.mutex);
@@ -502,10 +548,15 @@
 
 			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()
@@ -722,6 +773,7 @@
 	task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list