diff options
Diffstat (limited to 'intern/cycles/render/tile.cpp')
-rw-r--r-- | intern/cycles/render/tile.cpp | 105 |
1 files changed, 86 insertions, 19 deletions
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp index 874f1a6b3aa..bbcdb47260e 100644 --- a/intern/cycles/render/tile.cpp +++ b/intern/cycles/render/tile.cpp @@ -23,12 +23,15 @@ CCL_NAMESPACE_BEGIN -TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, int num_devices_) +TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, + 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); @@ -70,7 +73,45 @@ 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); + + 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 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 * tile_size.x; + int y = tile_y * tile_size.y; + int w = (tile_x == tile_w-1)? image_w - x: tile_size.x; + int h = (tile_y == tile_h-1)? image_h - y: tile_size.y; + + 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); @@ -78,7 +119,9 @@ void TileManager::set_tiles() state.tiles.clear(); - int num = min(image_h, num_devices); + 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; @@ -86,20 +129,30 @@ void TileManager::set_tiles() 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; 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; + for(int tile_x = 0; tile_x < tile_w; tile_x++, tile_index++) { + int x = tile_x * tile_size.x; + int y = tile_y * tile_size.y; + int w = (tile_x == tile_w-1)? image_w - x: tile_size.x; + int h = (tile_y == tile_h-1)? device_h - y: tile_size.y; - state.tiles.push_back(Tile(x, y + device_y, w, h, device)); + state.tiles.push_back(Tile(tile_index, x, y + device_y, w, h, device)); } } } +} + +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(); @@ -120,13 +173,10 @@ list<Tile>::iterator TileManager::next_center_tile(int device) 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; + int logical_device = preserve_tile_device? device: 0; - 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++) { @@ -143,7 +193,7 @@ list<Tile>::iterator TileManager::next_center_tile(int device) /* closest of the non-rendering tiles */ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { - if(iter->device == device && iter->rendering == false) { + if(iter->device == logical_device && iter->rendering == false) { Tile &cur_tile = *iter; int64_t distx = centx - (cur_tile.x + cur_tile.w / 2); @@ -160,11 +210,28 @@ list<Tile>::iterator TileManager::next_center_tile(int device) return best; } +list<Tile>::iterator TileManager::next_simple_tile(int device) +{ + list<Tile>::iterator iter; + + int logical_device = preserve_tile_device? device: 0; + + for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) { + if(iter->device == logical_device && iter->rendering == false) + return iter; + } + + return state.tiles.end(); +} + bool TileManager::next_tile(Tile& tile, int device) { list<Tile>::iterator tile_it; - tile_it = next_center_tile(device); + if(background) + tile_it = next_center_tile(device); + else + tile_it = next_simple_tile(device); if(tile_it != state.tiles.end()) { tile_it->rendering = true; |