diff options
-rw-r--r-- | intern/cycles/render/session.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/tile.cpp | 68 | ||||
-rw-r--r-- | intern/cycles/render/tile.h | 18 |
3 files changed, 75 insertions, 13 deletions
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index c8fdb755544..bf8d8ade37d 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -41,7 +41,7 @@ CCL_NAMESPACE_BEGIN 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 == false || params.progressive_refine, params.background, max(params.device.multi_devices.size(), 1)) { device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background); diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index a737f47457d..9928186a12f 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -24,13 +24,14 @@ CCL_NAMESPACE_BEGIN TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, - int preserve_tile_device_, int num_devices_) + bool preserve_tile_device_, bool background_, int num_devices_) { progressive = progressive_; tile_size = tile_size_; start_resolution = start_resolution_; num_devices = num_devices_; preserve_tile_device = preserve_tile_device_; + background = background_; BufferParams buffer_params; reset(buffer_params, 0); @@ -72,18 +73,57 @@ void TileManager::set_samples(int num_samples_) num_samples = num_samples_; } -void TileManager::set_tiles() +/* splits image into tiles and assigns equal amount of tiles to every render device */ +void TileManager::gen_tiles_global() { int resolution = state.resolution_divider; int image_w = max(1, params.width/resolution); int image_h = max(1, params.height/resolution); - int tile_index = 0; state.tiles.clear(); + int tile_w = (tile_size.x >= image_w)? 1: (image_w + tile_size.x - 1)/tile_size.x; + int tile_h = (tile_size.y >= image_h)? 1: (image_h + tile_size.y - 1)/tile_size.y; + int sub_w = (image_w + tile_w - 1)/tile_w; + int sub_h = (image_h + tile_h - 1)/tile_h; + int num_logical_devices = preserve_tile_device? num_devices: 1; + int num = min(image_h, num_logical_devices); + int tile_index = 0; + + int tiles_per_device = (tile_w * tile_h + num - 1) / num; + int cur_device = 0, cur_tiles = 0; + + for(int tile_y = 0; tile_y < tile_h; tile_y++) { + for(int tile_x = 0; tile_x < tile_w; tile_x++, tile_index++) { + 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; + + state.tiles.push_back(Tile(tile_index, x, y, w, h, cur_device)); + cur_tiles++; + + if(cur_tiles == tiles_per_device) { + cur_tiles = 0; + cur_device++; + } + } + } +} + +/* slices image into as much pieces as how many devices are rendering this image */ +void TileManager::gen_tiles_sliced() +{ + int resolution = state.resolution_divider; + int image_w = max(1, params.width/resolution); + int image_h = max(1, params.height/resolution); + + state.tiles.clear(); + int num_logical_devices = preserve_tile_device? num_devices: 1; int num = min(image_h, num_logical_devices); + int tile_index = 0; for(int device = 0; device < num; device++) { int device_y = (image_h/num)*device; @@ -105,6 +145,18 @@ void TileManager::set_tiles() } } } +} + +void TileManager::set_tiles() +{ + int resolution = state.resolution_divider; + int image_w = max(1, params.width/resolution); + int image_h = max(1, params.height/resolution); + + if(background) + gen_tiles_global(); + else + gen_tiles_sliced(); state.num_tiles = state.tiles.size(); @@ -126,15 +178,9 @@ list<Tile>::iterator TileManager::next_center_tile(int device) int image_h = max(1, params.height/resolution); int logical_device = preserve_tile_device? device: 0; - int num_logical_devices = preserve_tile_device? num_devices: 1; - - int num = min(image_h, num_logical_devices); - - int device_y = (image_h / num) * logical_device; - int device_h = (logical_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; + int64_t centx = image_w / 2, centy = image_h / 2, tot = 1; + int64_t mindist = (int64_t) image_w * (int64_t) image_h; /* find center of rendering tiles, image center counts for 1 too */ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index 3ccc73deed1..ad1e84cfb7b 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -59,7 +59,7 @@ public: } state; TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution, - int preserve_tile_device, int num_devices = 1); + bool preserve_tile_device, bool background, int num_devices = 1); ~TileManager(); void reset(BufferParams& params, int num_samples); @@ -86,6 +86,22 @@ protected: */ bool preserve_tile_device; + /* for background render tiles should exactly match render parts generated from + * blender side, which means image first gets split into tiles and then tiles are + * assigning to render devices + * + * however viewport rendering expects tiles to be allocated in a special way, + * meaning image is being sliced horizontally first and every device handles + * it's own slice + */ + bool background; + + /* splits image into tiles and assigns equal amount of tiles to every render device */ + void gen_tiles_global(); + + /* slices image into as much pieces as how many devices are rendering this image */ + void gen_tiles_sliced(); + list<Tile>::iterator next_center_tile(int device = 0); }; |