[Bf-blender-cvs] [49018d2] soc-2016-cycles_denoising: Cycles Denoise: Modify TileManager to allow multiple tasks per tile

Lukas Stockner noreply at git.blender.org
Fri May 27 21:47:17 CEST 2016


Commit: 49018d273c6662ca9e679f7c21515577e848ff28
Author: Lukas Stockner
Date:   Wed May 25 19:38:34 2016 +0200
Branches: soc-2016-cycles_denoising
https://developer.blender.org/rB49018d273c6662ca9e679f7c21515577e848ff28

Cycles Denoise: Modify TileManager to allow multiple tasks per tile

This commit changes the TileManager and Session so that one tile can be processed
in multiple steps, here rendering and denoising. The reason for that is that a tile
can only be denoised as soon as all its neighbors are rendered (since the filter window
will cross tile borders) and only be freed as soon as all its neighbors are denoised
(otherwise they wouldn't have the out-of-tile data either).
Therefore, Tiles now have a State and are actually stored for the whole render process.
Tile Highlighting also needed a bit of tweaking to un-highlight tiles between rendering
and denoising.

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

M	intern/cycles/blender/blender_session.cpp
M	intern/cycles/blender/blender_session.h
M	intern/cycles/render/buffers.h
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/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 7a5243d..14f6e36 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -379,7 +379,7 @@ static void end_render_result(BL::RenderEngine& b_engine,
 	b_engine.end_result(b_rr, (int)cancel, (int)do_merge_results);
 }
 
-void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only)
+void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight)
 {
 	BufferParams& params = rtile.buffers->params;
 	int x = params.full_x - session->tile_manager.params.full_x;
@@ -415,7 +415,7 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
 			update_render_result(b_rr, b_rlay, rtile);
 		}
 
-		end_render_result(b_engine, b_rr, true, true);
+		end_render_result(b_engine, b_rr, highlight, true);
 	}
 	else {
 		/* write result */
@@ -426,26 +426,26 @@ void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_upda
 
 void BlenderSession::write_render_tile(RenderTile& rtile)
 {
-	do_write_update_render_tile(rtile, false);
+	do_write_update_render_tile(rtile, false, false);
 }
 
-void BlenderSession::update_render_tile(RenderTile& rtile)
+void BlenderSession::update_render_tile(RenderTile& rtile, bool highlight)
 {
 	/* use final write for preview renders, otherwise render result wouldn't be
 	 * be updated in blender side
 	 * would need to be investigated a bit further, but for now shall be fine
 	 */
 	if(!b_engine.is_preview())
-		do_write_update_render_tile(rtile, true);
+		do_write_update_render_tile(rtile, true, highlight);
 	else
-		do_write_update_render_tile(rtile, false);
+		do_write_update_render_tile(rtile, false, false);
 }
 
 void BlenderSession::render()
 {
 	/* set callback to write out render results */
 	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);
+	session->update_render_tile_cb = function_bind(&BlenderSession::update_render_tile, this, _1, _2);
 
 	/* get buffer parameters */
 	SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index 66a6945..3fe5cb6 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -79,7 +79,7 @@ public:
 	void update_render_result(BL::RenderResult& b_rr,
 	                          BL::RenderLayer& b_rlay,
 	                          RenderTile& rtile);
-	void update_render_tile(RenderTile& rtile);
+	void update_render_tile(RenderTile& rtile, bool highlight);
 
 	/* interactive updates */
 	void synchronize();
@@ -142,7 +142,7 @@ protected:
 	                                   BL::RenderLayer& b_rlay,
 	                                   RenderTile& rtile,
 	                                   bool do_update_only);
-	void do_write_update_render_tile(RenderTile& rtile, bool do_update_only);
+	void do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight);
 
 	int builtin_image_frame(const string &builtin_name);
 	void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels);
diff --git a/intern/cycles/render/buffers.h b/intern/cycles/render/buffers.h
index 52d031b..dca2d1d 100644
--- a/intern/cycles/render/buffers.h
+++ b/intern/cycles/render/buffers.h
@@ -141,6 +141,7 @@ public:
 	int resolution;
 	int offset;
 	int stride;
+	int tile_index;
 
 	device_ptr buffer;
 	device_ptr rng_state;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 8b30772..3cba497 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -363,21 +363,22 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 	thread_scoped_lock tile_lock(tile_mutex);
 
 	/* get next tile from manager */
-	Tile tile;
+	Tile *tile;
 	int device_num = device->device_number(tile_device);
 
 	if(!tile_manager.next_tile(tile, device_num))
 		return false;
 	
 	/* fill render tile */
-	rtile.x = tile_manager.state.buffer.full_x + tile.x;
-	rtile.y = tile_manager.state.buffer.full_y + tile.y;
-	rtile.w = tile.w;
-	rtile.h = tile.h;
+	rtile.x = tile_manager.state.buffer.full_x + tile->x;
+	rtile.y = tile_manager.state.buffer.full_y + tile->y;
+	rtile.w = tile->w;
+	rtile.h = tile->h;
 	rtile.start_sample = tile_manager.state.sample;
 	rtile.num_samples = tile_manager.state.num_samples;
 	rtile.resolution = tile_manager.state.resolution_divider;
-	rtile.task = RenderTile::PATH_TRACE;
+	rtile.tile_index = tile->index;
+	rtile.task = (tile->state == Tile::DENOISE)? RenderTile::DENOISE: RenderTile::PATH_TRACE;
 
 	tile_lock.unlock();
 
@@ -389,6 +390,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 		rtile.buffer = buffers->buffer.device_pointer;
 		rtile.rng_state = buffers->rng_state.device_pointer;
 		rtile.buffers = buffers;
+		tile->buffers = buffers;
 
 		device->map_tile(tile_device, rtile);
 
@@ -404,39 +406,39 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
 
 	buffer_params.get_offset_stride(rtile.offset, rtile.stride);
 
-	RenderBuffers *tilebuffers;
+	if(tile->buffers == NULL) {
+		/* allocate buffers */
+		if(params.progressive_refine) {
+			tile_lock.lock();
 
-	/* allocate buffers */
-	if(params.progressive_refine) {
-		tile_lock.lock();
+			if(tile_buffers.size() == 0)
+				tile_buffers.resize(tile_manager.state.num_tiles, NULL);
 
-		if(tile_buffers.size() == 0)
-			tile_buffers.resize(tile_manager.state.num_tiles, NULL);
+			/* In certain circumstances number of tiles in the tile manager could
+			 * be changed. This is not supported by the progressive refine feature.
+			 */
+			assert(tile_buffers.size() == tile_manager.state.num_tiles);
 
-		/* In certain circumstances number of tiles in the tile manager could
-		 * be changed. This is not supported by the progressive refine feature.
-		 */
-		assert(tile_buffers.size() == tile_manager.state.num_tiles);
+			tile->buffers = tile_buffers[tile->index];
+			if(tile->buffers == NULL) {
+				tile->buffers = new RenderBuffers(tile_device);
+				tile_buffers[tile->index] = tile->buffers;
 
-		tilebuffers = tile_buffers[tile.index];
-		if(tilebuffers == NULL) {
-			tilebuffers = new RenderBuffers(tile_device);
-			tile_buffers[tile.index] = tilebuffers;
+				tile->buffers->reset(tile_device, buffer_params);
+			}
 
-			tilebuffers->reset(tile_device, buffer_params);
+			tile_lock.unlock();
 		}
+		else {
+			tile->buffers = new RenderBuffers(tile_device);
 
-		tile_lock.unlock();
-	}
-	else {
-		tilebuffers = new RenderBuffers(tile_device);
-
-		tilebuffers->reset(tile_device, buffer_params);
+			tile->buffers->reset(tile_device, buffer_params);
+		}
 	}
 
-	rtile.buffer = tilebuffers->buffer.device_pointer;
-	rtile.rng_state = tilebuffers->rng_state.device_pointer;
-	rtile.buffers = tilebuffers;
+	rtile.buffer = tile->buffers->buffer.device_pointer;
+	rtile.rng_state = tile->buffers->rng_state.device_pointer;
+	rtile.buffers = tile->buffers;
 
 	/* this will tag tile as IN PROGRESS in blender-side render pipeline,
 	 * which is needed to highlight currently rendering tile before first
@@ -455,7 +457,7 @@ void Session::update_tile_sample(RenderTile& rtile)
 		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, true);
 		}
 	}
 
@@ -466,12 +468,21 @@ void Session::release_tile(RenderTile& rtile)
 {
 	thread_scoped_lock tile_lock(tile_mutex);
 
-	if(write_render_tile_cb) {
-		if(params.progressive_refine == false) {
-			/* todo: optimize this by making it thread safe and removing lock */
-			write_render_tile_cb(rtile);
+	bool delete_tile;
 
-			delete rtile.buffers;
+	if(tile_manager.return_tile(rtile.tile_index, delete_tile)) {
+		if(write_render_tile_cb && params.progressive_refine == false) {
+			write_render_tile_cb(rtile);
+			if(delete_tile) {
+				delete rtile.buffers;
+				/* TODO(lukas): Set buffers in tile_manager.state.tiles[] to zero.
+				 * Shoudn't matter in theory since the tile won't be used again, but it's more error-proof. */
+			}
+		}
+	}
+	else {
+		if(update_render_tile_cb && params.progressive_refine == false) {
+			update_render_tile_cb(rtile, false);
 		}
 	}
 
@@ -977,7 +988,7 @@ bool Session::update_progressive_refine(bool cancel)
 			}
 			else {
 				if(update_render_tile_cb)
-					update_render_tile_cb(rtile);
+					update_render_tile_cb(rtile, true);
 			}
 		}
 	}
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 68d4561..4776f59 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -127,7 +127,7 @@ public:
 	Stats stats;
 
 	function<void(RenderTile&)> write_render_tile_cb;
-	function<void(RenderTile&)> update_render_tile_cb;
+	function<void(RenderTile&, bool)> update_render_tile_cb;
 
 	explicit Session(const SessionParams& params);
 	~Session();
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 3a6dfea..edfa33b 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -25,37 +25,39 @@ namespace {
 
 class TileComparator {
 public:
-	TileComparator(TileOrder order, int2 center)
-	 :  order_(order),
-	    center_(center)
+	TileComparator(TileOrder order_, int2 center_, Tile *tiles_)
+	 :  order(order_),
+	    center(center_),
+	    tiles(tiles_)
 	{}
 
-	bool operator()(Tile &a, Tile &b)
+	bool operator()(int a, int b)
 	{
-		switch(order_) {
+		switch(order) {
 			case TILE_CENTER:
 			{
-				float2 dist_a = make_float2(center_.x - (a.x + a.w/2),
-				                            center_.y - (a.y + a.h/2));
-				float2 dist_b = make_float2(center_.x - (b.x + b.w/2),
-				                            center_.y - (b.y + b.h/2));
+				float2 dist_a = make_float2(center.x - (tiles[a].x + tiles[a].w/2),
+				    

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list