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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2012-09-04 17:29:07 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2012-09-04 17:29:07 +0400
commitadea12cb01e4c4f18f345dfbbf49e9e622192e4e (patch)
treeb43018344c696e4d59437fabc7f17f5b9d6a8e80 /intern/cycles/render/tile.cpp
parent68563134d4800be4eb46aa6b598fd719cdaf2980 (diff)
Cycles: merge of changes from tomato branch.
Regular rendering now works tiled, and supports save buffers to save memory during render and cache render results. Brick texture node by Thomas. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Brick_Texture Image texture Blended Box Mapping. http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Nodes/Textures#Image_Texture http://mango.blender.org/production/blended_box/ Various bug fixes by Sergey and Campbell. * Fix for reading freed memory in some node setups. * Fix incorrect memory read when synchronizing mesh motion. * Fix crash appearing when direct light usage is different on different layers. * Fix for vector pass gives wrong result in some circumstances. * Fix for wrong resolution used for rendering Render Layer node. * Option to cancel rendering when doing initial synchronization. * No more texture limit when using CPU render. * Many fixes for new tiled rendering.
Diffstat (limited to 'intern/cycles/render/tile.cpp')
-rw-r--r--intern/cycles/render/tile.cpp138
1 files changed, 106 insertions, 32 deletions
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 04e48d44029..b4156fd9471 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -19,14 +19,16 @@
#include "tile.h"
#include "util_algorithm.h"
+#include "util_types.h"
CCL_NAMESPACE_BEGIN
-TileManager::TileManager(bool progressive_, int samples_, int tile_size_, int min_size_)
+TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int resolution_, int num_devices_)
{
progressive = progressive_;
tile_size = tile_size_;
- min_size = min_size_;
+ resolution = resolution_;
+ num_devices = num_devices_;
BufferParams buffer_params;
reset(buffer_params, 0);
@@ -36,34 +38,24 @@ TileManager::~TileManager()
{
}
-void TileManager::reset(BufferParams& params_, int samples_)
+void TileManager::reset(BufferParams& params_, int num_samples_)
{
params = params_;
- start_resolution = 1;
-
- int w = params.width, h = params.height;
-
- if(min_size != INT_MAX) {
- while(w*h > min_size*min_size) {
- w = max(1, w/2);
- h = max(1, h/2);
-
- start_resolution *= 2;
- }
- }
-
- samples = samples_;
+ num_samples = num_samples_;
state.buffer = BufferParams();
state.sample = -1;
- state.resolution = start_resolution;
+ state.num_tiles = 0;
+ state.num_rendered_tiles = 0;
+ state.num_samples = 0;
+ state.resolution = resolution;
state.tiles.clear();
}
-void TileManager::set_samples(int samples_)
+void TileManager::set_samples(int num_samples_)
{
- samples = samples_;
+ num_samples = num_samples_;
}
void TileManager::set_tiles()
@@ -71,24 +63,34 @@ void TileManager::set_tiles()
int resolution = state.resolution;
int image_w = max(1, params.width/resolution);
int image_h = max(1, params.height/resolution);
- int tile_w = (tile_size >= image_w)? 1: (image_w + tile_size - 1)/tile_size;
- int tile_h = (tile_size >= image_h)? 1: (image_h + tile_size - 1)/tile_size;
- int sub_w = image_w/tile_w;
- int sub_h = image_h/tile_h;
state.tiles.clear();
- for(int tile_y = 0; tile_y < tile_h; tile_y++) {
- for(int tile_x = 0; tile_x < tile_w; tile_x++) {
- int x = tile_x * sub_w;
- int y = tile_y * sub_h;
- int w = (tile_x == tile_w-1)? image_w - x: sub_w;
- int h = (tile_y == tile_h-1)? image_h - y: sub_h;
+ int num = min(image_h, num_devices);
+
+ for(int device = 0; device < num; device++) {
+ int device_y = (image_h/num)*device;
+ int device_h = (device == num-1)? image_h - device*(image_h/num): image_h/num;
+
+ int tile_w = (tile_size.x >= image_w)? 1: (image_w + tile_size.x - 1)/tile_size.x;
+ int tile_h = (tile_size.y >= device_h)? 1: (device_h + tile_size.y - 1)/tile_size.y;
+ int sub_w = (image_w + tile_w - 1)/tile_w;
+ int sub_h = (device_h + tile_h - 1)/tile_h;
- state.tiles.push_back(Tile(x, y, w, h));
+ for(int tile_y = 0; tile_y < tile_h; tile_y++) {
+ for(int tile_x = 0; tile_x < tile_w; tile_x++) {
+ int x = tile_x * sub_w;
+ int y = tile_y * sub_h;
+ int w = (tile_x == tile_w-1)? image_w - x: sub_w;
+ int h = (tile_y == tile_h-1)? device_h - y: sub_h;
+
+ state.tiles.push_back(Tile(x, y + device_y, w, h, device));
+ }
}
}
+ state.num_tiles = state.tiles.size();
+
state.buffer.width = image_w;
state.buffer.height = image_h;
@@ -98,9 +100,74 @@ void TileManager::set_tiles()
state.buffer.full_height = max(1, params.full_height/resolution);
}
+list<Tile>::iterator TileManager::next_center_tile(int device)
+{
+ list<Tile>::iterator iter, best = state.tiles.end();
+
+ int resolution = state.resolution;
+ int image_w = max(1, params.width/resolution);
+ int image_h = max(1, params.height/resolution);
+
+ int num = min(image_h, num_devices);
+
+ int device_y = (image_h / num) * device;
+ int device_h = (device == num - 1) ? image_h - device * (image_h / num) : image_h / num;
+
+ int64_t centx = image_w / 2, centy = device_y + device_h / 2, tot = 1;
+ int64_t mindist = (int64_t) image_w * (int64_t) device_h;
+
+ /* find center of rendering tiles, image center counts for 1 too */
+ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
+ if(iter->rendering) {
+ Tile &cur_tile = *iter;
+ centx += cur_tile.x + cur_tile.w / 2;
+ centy += cur_tile.y + cur_tile.h / 2;
+ tot++;
+ }
+ }
+
+ centx /= tot;
+ centy /= tot;
+
+ /* closest of the non-rendering tiles */
+ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
+ if(iter->device == device && iter->rendering == false) {
+ Tile &cur_tile = *iter;
+
+ int64_t distx = centx - (cur_tile.x + cur_tile.w / 2);
+ int64_t disty = centy - (cur_tile.y + cur_tile.h / 2);
+ distx = (int64_t) sqrt((double)distx * distx + disty * disty);
+
+ if(distx < mindist) {
+ best = iter;
+ mindist = distx;
+ }
+ }
+ }
+
+ return best;
+}
+
+bool TileManager::next_tile(Tile& tile, int device)
+{
+ list<Tile>::iterator tile_it;
+
+ tile_it = next_center_tile(device);
+
+ if(tile_it != state.tiles.end()) {
+ tile_it->rendering = true;
+ tile = *tile_it;
+ state.num_rendered_tiles++;
+
+ return true;
+ }
+
+ return false;
+}
+
bool TileManager::done()
{
- return (state.sample+1 >= samples && state.resolution == 1);
+ return (state.sample+state.num_samples >= num_samples && state.resolution == 1);
}
bool TileManager::next()
@@ -111,10 +178,17 @@ bool TileManager::next()
if(progressive && state.resolution > 1) {
state.sample = 0;
state.resolution /= 2;
+ state.num_samples = 1;
set_tiles();
}
else {
state.sample++;
+
+ if(progressive)
+ state.num_samples = 1;
+ else
+ state.num_samples = num_samples;
+
state.resolution = 1;
set_tiles();
}