diff options
Diffstat (limited to 'intern/cycles/integrator/tile.cpp')
-rw-r--r-- | intern/cycles/integrator/tile.cpp | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/intern/cycles/integrator/tile.cpp b/intern/cycles/integrator/tile.cpp index 7ea73451d80..b49e1b27b83 100644 --- a/intern/cycles/integrator/tile.cpp +++ b/intern/cycles/integrator/tile.cpp @@ -48,7 +48,8 @@ ccl_device_inline uint round_up_to_power_of_two(uint x) TileSize tile_calculate_best_size(const int2 &image_size, const int num_samples, - const int max_num_path_states) + const int max_num_path_states, + const float scrambling_distance) { if (max_num_path_states == 1) { /* Simple case: avoid any calculation, which could cause rounding issues. */ @@ -71,17 +72,54 @@ TileSize tile_calculate_best_size(const int2 &image_size, * - Keep values a power of two, for more integer fit into the maximum number of paths. */ TileSize tile_size; - - /* Calculate tile size as if it is the most possible one to fit an entire range of samples. - * The idea here is to keep tiles as small as possible, and keep device occupied by scheduling - * multiple tiles with the same coordinates rendering different samples. */ const int num_path_states_per_sample = max_num_path_states / num_samples; - if (num_path_states_per_sample != 0) { - tile_size.width = round_down_to_power_of_two(lround(sqrt(num_path_states_per_sample))); - tile_size.height = tile_size.width; + if (scrambling_distance < 0.9f) { + /* Prefer large tiles for scrambling distance. */ + if (image_size.x * image_size.y <= num_path_states_per_sample) { + tile_size.width = image_size.x; + tile_size.height = image_size.y; + } + else { + /* Pick the option with the biggest tile size */ + int heightOption = num_path_states_per_sample / image_size.x; + int widthOption = num_path_states_per_sample / image_size.y; + // Check if these options are possible + if ((heightOption > 0) || (widthOption > 0)) { + int area1 = image_size.x * heightOption; + int area2 = widthOption * image_size.y; + /* The option with the biggest pixel area */ + if (area1 >= area2) { + tile_size.width = image_size.x; + tile_size.height = heightOption; + } + else { + tile_size.width = widthOption; + tile_size.height = image_size.y; + } + } + else { // Large tiles are not an option so use square tiles + if (num_path_states_per_sample != 0) { + tile_size.width = round_down_to_power_of_two(lround(sqrt(num_path_states_per_sample))); + tile_size.height = tile_size.width; + } + else { + tile_size.width = tile_size.height = 1; + } + } + } } else { - tile_size.width = tile_size.height = 1; + /* Calculate tile size as if it is the most possible one to fit an entire range of samples. + * The idea here is to keep tiles as small as possible, and keep device occupied by scheduling + * multiple tiles with the same coordinates rendering different samples. */ + + if (num_path_states_per_sample != 0) { + tile_size.width = round_down_to_power_of_two(lround(sqrt(num_path_states_per_sample))); + tile_size.height = tile_size.width; + } + else { + tile_size.width = tile_size.height = 1; + } } if (num_samples == 1) { @@ -93,7 +131,7 @@ TileSize tile_calculate_best_size(const int2 &image_size, tile_size.num_samples = min(round_up_to_power_of_two(lround(sqrt(num_samples / 2))), static_cast<uint>(num_samples)); - const int tile_area = tile_size.width / tile_size.height; + const int tile_area = tile_size.width * tile_size.height; tile_size.num_samples = min(tile_size.num_samples, max_num_path_states / tile_area); } |