[Bf-blender-cvs] [1c92841] soc-2016-cycles_denoising: Cycles: Add denoise-only mode the the Session

Lukas Stockner noreply at git.blender.org
Wed Jul 6 04:28:55 CEST 2016


Commit: 1c92841e1efa1d379cccb67ad4f8426218da63ed
Author: Lukas Stockner
Date:   Wed Jul 6 04:16:29 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rB1c92841e1efa1d379cccb67ad4f8426218da63ed

Cycles: Add denoise-only mode the the Session

This mode just creates the Device, generates tiles and runs the denoising kernel
on each tile.
Compared to the regular mode of operation, a lot is missing: No interactivity, no
scene syncing, no progressive rendering etc. However, these features aren't needed
for the denoise-after-render feature, and so this mode saves a lot of code when
calling it from the bindings.

Internally, it uses one single large buffer to hold the image, instead of a small buffer
per tile. That requires some changes to the TileManager and is also the reason for the
earlier region-of-interest commit.

===================================================================

M	intern/cycles/device/device_cuda.cpp
M	intern/cycles/render/session.cpp
M	intern/cycles/render/session.h
M	intern/cycles/render/tile.cpp
M	intern/cycles/render/tile.h

===================================================================

diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 3d4c9ba..392b62d 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1300,7 +1300,7 @@ public:
 					}
 				}
 				else if(tile.task == RenderTile::DENOISE) {
-					assert(!"Explicitly scheduling tiles for denoising isn't supported on GPUs!");
+					assert(!"Explicitly scheduling tiles for denoising isn't supported on GPUs yet!");
 				}
 
 				task->release_tile(tile);
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index a6a99f7..d1462a1 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -46,7 +46,7 @@ Session::Session(const SessionParams& params_)
 : params(params_),
   tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
        params.background == false || params.progressive_refine, params.background, params.tile_order,
-       max(params.device.multi_devices.size(), 1)),
+       max(params.device.multi_devices.size(), 1), params.only_denoise),
   stats()
 {
 	device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
@@ -133,6 +133,11 @@ void Session::start()
 	session_thread = new thread(function_bind(&Session::run, this));
 }
 
+void Session::start_denoise()
+{
+	session_thread = new thread(function_bind(&Session::run_denoise, this));
+}
+
 bool Session::ready_to_reset()
 {
 	double dt = time_dt() - reset_time;
@@ -407,19 +412,17 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 		return true;
 	}
 
-	/* fill buffer parameters */
-	BufferParams buffer_params = tile_manager.params;
-	buffer_params.full_x = rtile.x;
-	buffer_params.full_y = rtile.y;
-	buffer_params.width = rtile.w;
-	buffer_params.height = rtile.h;
-	buffer_params.overscan = overscan;
-	buffer_params.final_width = rtile.w - 2*overscan;
-	buffer_params.final_height = rtile.h - 2*overscan;
-
-	buffer_params.get_offset_stride(rtile.offset, rtile.stride);
-
 	if(tile->buffers == NULL) {
+		/* fill buffer parameters */
+		BufferParams buffer_params = tile_manager.params;
+		buffer_params.full_x = rtile.x;
+		buffer_params.full_y = rtile.y;
+		buffer_params.width = rtile.w;
+		buffer_params.height = rtile.h;
+		buffer_params.overscan = overscan;
+		buffer_params.final_width = rtile.w - 2*overscan;
+		buffer_params.final_height = rtile.h - 2*overscan;
+
 		/* allocate buffers */
 		if(params.progressive_refine) {
 			tile_lock.lock();
@@ -449,6 +452,8 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 		}
 	}
 
+	tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride);
+
 	rtile.buffer = tile->buffers->buffer.device_pointer;
 	rtile.rng_state = tile->buffers->rng_state.device_pointer;
 	rtile.buffers = tile->buffers;
@@ -526,12 +531,7 @@ void Session::get_neighbor_tiles(RenderTile *tiles)
 				tiles[i].w = tile->w;
 				tiles[i].h = tile->h;
 
-				buffer_params.full_x = tiles[i].x;
-				buffer_params.full_y = tiles[i].y;
-				buffer_params.width  = tiles[i].w;
-				buffer_params.height = tiles[i].h;
-
-				buffer_params.get_offset_stride(tiles[i].offset, tiles[i].stride);
+				tile->buffers->params.get_offset_stride(tiles[i].offset, tiles[i].stride);
 			}
 			else {
 				tiles[i].buffer = (device_ptr)NULL;
@@ -541,6 +541,8 @@ void Session::get_neighbor_tiles(RenderTile *tiles)
 			}
 		}
 	}
+
+	assert(tiles[4].buffers);
 }
 
 void Session::run_cpu()
@@ -760,6 +762,56 @@ void Session::run()
 		progress.set_update();
 }
 
+void Session::run_denoise()
+{
+	if(!progress.get_cancel()) {
+		progress.reset_sample();
+		tile_manager.reset(buffers->params, params.samples);
+		tile_manager.state.global_buffers = buffers;
+		start_time = time_dt();
+		progress.set_render_start_time(start_time);
+
+		/* Set up KernelData. */
+		KernelData kernel_data;
+		kernel_data.integrator.half_window = params.half_window;
+		kernel_data.film.pass_stride = buffers->params.get_passes_size();
+		kernel_data.film.pass_denoising = buffers->params.get_denoise_offset();
+		kernel_data.film.pass_no_denoising = buffers->params.selective_denoising? kernel_data.film.pass_denoising+20 : 0;
+		device->const_copy_to("__data", &kernel_data, sizeof(kernel_data));
+
+		/* Generate tiles. */
+		tile_manager.next();
+		{
+			thread_scoped_lock buffers_lock(buffers_mutex);
+
+			if(!device->error_message().empty())
+				progress.set_error(device->error_message());
+
+			/* update status and timing */
+			update_status_time();
+
+			/* render */
+			render();
+
+			/* update status and timing */
+			update_status_time();
+
+
+			if(!device->error_message().empty())
+				progress.set_error(device->error_message());
+		}
+
+		device->task_wait();
+
+		progress.set_update();
+	}
+
+	if(progress.get_cancel())
+		progress.set_status("Cancel", progress.get_cancel_message());
+	else
+		progress.set_update();
+}
+
 bool Session::draw(BufferParams& buffer_params, DeviceDrawParams &draw_params)
 {
 	if(device_use_gl)
@@ -986,7 +1038,7 @@ void Session::render()
 	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;
-	task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH;
+	task.integrator_branched = !params.only_denoise && (scene->integrator->method == Integrator::BRANCHED_PATH);
 	task.requested_tile_size = params.tile_size;
 
 	device->task_add(task);
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 700e399..8939b4e 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -59,6 +59,9 @@ public:
 
 	bool display_buffer_linear;
 
+	bool only_denoise;
+	int half_window;
+
 	double cancel_timeout;
 	double reset_timeout;
 	double text_timeout;
@@ -83,6 +86,9 @@ public:
 
 		display_buffer_linear = false;
 
+		only_denoise = false;
+		half_window = 8;
+
 		cancel_timeout = 0.1;
 		reset_timeout = 0.1;
 		text_timeout = 1.0;
@@ -105,6 +111,8 @@ public:
 		&& start_resolution == params.start_resolution
 		&& threads == params.threads
 		&& denoise_result == params.denoise_result
+		&& only_denoise == params.only_denoise
+		&& half_window == params.half_window
 		&& display_buffer_linear == params.display_buffer_linear
 		&& cancel_timeout == params.cancel_timeout
 		&& reset_timeout == params.reset_timeout
@@ -138,6 +146,7 @@ public:
 	~Session();
 
 	void start();
+	void start_denoise();
 	bool draw(BufferParams& params, DeviceDrawParams& draw_params);
 	void wait();
 
@@ -160,6 +169,7 @@ protected:
 	} delayed_reset;
 
 	void run();
+	void run_denoise();
 
 	void update_status_time(bool show_pause = false, bool show_done = false);
 
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 277a89f..0e298a5 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -88,7 +88,7 @@ enum SpiralDirection {
 }  /* namespace */
 
 TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
-                         bool preserve_tile_device_, bool background_, TileOrder tile_order_, int num_devices_)
+                         bool preserve_tile_device_, bool background_, TileOrder tile_order_, int num_devices_, bool only_denoise_)
 {
 	progressive = progressive_;
 	tile_size = tile_size_;
@@ -99,6 +99,7 @@ TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, i
 	preserve_tile_device = preserve_tile_device_;
 	background = background_;
 	schedule_denoising = false;
+	only_denoise = only_denoise_;
 
 	range_start_sample = 0;
 	range_num_samples = -1;
@@ -130,6 +131,7 @@ void TileManager::reset(BufferParams& params_, int num_samples_)
 	num_samples = num_samples_;
 
 	state.buffer = BufferParams();
+	state.global_buffers = NULL;
 	state.sample = range_start_sample - 1;
 	state.num_tiles = 0;
 	state.num_rendered_tiles = 0;
@@ -168,7 +170,11 @@ int TileManager::gen_tiles(bool sliced)
 	state.render_tiles.resize(num);
 	state.denoise_tiles.resize(num);
 	state.tile_stride = tile_w;
-	vector<list<int> >::iterator tile_list = state.render_tiles.begin();
+	vector<list<int> >::iterator tile_list;
+	if(only_denoise)
+		tile_list = state.denoise_tiles.begin();
+	else
+		tile_list = state.render_tiles.begin();
 
 	if(tile_order == TILE_HILBERT_SPIRAL) {
 		assert(!sliced);
@@ -215,7 +221,7 @@ int TileManager::gen_tiles(bool sliced)
 					int h = min(tile_size.y, image_h - pos.y);
 					int2 ipos = pos / tile_size;
 					int idx = ipos.y*tile_w + ipos.x;
-					state.tiles[idx] = Tile(idx, pos.x, pos.y, w, h, cur_device);
+					state.tiles[idx] = Tile(idx, pos.x, pos.y, w, h, cur_device, only_denoise? Tile::DENOISE : Tile::RENDER, state.global_buffers);
 					tile_list->push_front(idx);
 					cur_tiles++;
 
@@ -281,7 +287,7 @@ int TileManager::gen_tiles(bool sliced)
 				int h = (tile_y == tile_slice_h-1)? slice_h - y: tile_size.y;
 
 				int idx = tile_y*tile_w + tile_x;
-				state.tiles[idx] = Tile(idx, x, y + slice_y, w, h, sliced? slice: cur_device);
+				state.tiles[idx] = Tile(idx, x, y + slice_y, w, h, sliced? slice: cur_device, only_denoise? Tile::DENOISE : Tile::RENDER, state.global_buffers);
 				tile_list->push_back(idx);
 
 				if(!sliced) {
@@ -339,6 +345,8 @@ bool TileManager::return_tile(int index, bool &delete_tile)
 	switch(state.tiles[index].state) {
 		case Tile::RENDER:
 		{
+			assert(!only_denoise);
+
 			if(!schedule_denoising) {
 				state.tiles[index].state = Tile::DONE;
 				delete_tile = true;
@@ -373,6 +381,11 @@ bool TileManager::return_tile(int index, bool &delete_tile)
 		}
 		case Tile::DENOISE:
 		{
+			if(only_denoise) {
+				state.tiles[index].state = Tile::DONE;
+				delete_tile = false;
+				return true;
+			}
 			state.tiles[index].state = Tile::DENOISED;
 			/* For each neighbor and the tile itself, check whether all of its neighbors have been denoised. If yes, it can be freed. */
 			for(int n = 0; n < 9; n++) {
@@ -425,6 +438,8 @@ bool TileManager::next_tile(Tile* &tile, int device)
 		int idx = state.denoise_tiles[logical_device].fron

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list