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:
Diffstat (limited to 'intern/cycles/render/tile.cpp')
-rw-r--r--intern/cycles/render/tile.cpp131
1 files changed, 94 insertions, 37 deletions
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 9ef0c695667..4ddfd56cd01 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -101,6 +101,7 @@ TileManager::TileManager(bool progressive_,
tile_order = tile_order_;
start_resolution = start_resolution_;
pixel_size = pixel_size_;
+ slice_overlap = 0;
num_samples = num_samples_;
num_devices = num_devices_;
preserve_tile_device = preserve_tile_device_;
@@ -201,8 +202,7 @@ int TileManager::gen_tiles(bool sliced)
int image_h = max(1, params.height / resolution);
int2 center = make_int2(image_w / 2, image_h / 2);
- int num_logical_devices = preserve_tile_device ? num_devices : 1;
- int num = min(image_h, num_logical_devices);
+ int num = preserve_tile_device || sliced ? min(image_h, num_devices) : 1;
int slice_num = sliced ? num : 1;
int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
@@ -216,7 +216,7 @@ int TileManager::gen_tiles(bool sliced)
tile_list = state.render_tiles.begin();
if (tile_order == TILE_HILBERT_SPIRAL) {
- assert(!sliced);
+ assert(!sliced && slice_overlap == 0);
int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
state.tiles.resize(tile_w * tile_h);
@@ -319,6 +319,12 @@ int TileManager::gen_tiles(bool sliced)
int slice_h = (slice == slice_num - 1) ? image_h - slice * (image_h / slice_num) :
image_h / slice_num;
+ if (slice_overlap != 0) {
+ int slice_y_offset = max(slice_y - slice_overlap, 0);
+ slice_h = min(slice_y + slice_h + slice_overlap, image_h) - slice_y_offset;
+ slice_y = slice_y_offset;
+ }
+
int tile_h = (tile_size.y >= slice_h) ? 1 : divide_up(slice_h, tile_size.y);
int tiles_per_device = divide_up(tile_w * tile_h, num);
@@ -363,6 +369,7 @@ void TileManager::gen_render_tiles()
{
/* Regenerate just the render tiles for progressive render. */
foreach (Tile &tile, state.tiles) {
+ tile.state = Tile::RENDER;
state.render_tiles[tile.device].push_back(tile.index);
}
}
@@ -386,17 +393,29 @@ void TileManager::set_tiles()
int TileManager::get_neighbor_index(int index, int neighbor)
{
- static const int dx[] = {-1, 0, 1, -1, 1, -1, 0, 1, 0}, dy[] = {-1, -1, -1, 0, 0, 1, 1, 1, 0};
+ /* Neighbor indices:
+ * 0 1 2
+ * 3 4 5
+ * 6 7 8
+ */
+ static const int dx[] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
+ static const int dy[] = {-1, -1, -1, 0, 0, 0, 1, 1, 1};
int resolution = state.resolution_divider;
int image_w = max(1, params.width / resolution);
int image_h = max(1, params.height / resolution);
+
+ int num = min(image_h, num_devices);
+ int slice_num = !background ? num : 1;
+ int slice_h = image_h / slice_num;
+
int tile_w = (tile_size.x >= image_w) ? 1 : divide_up(image_w, tile_size.x);
- int tile_h = (tile_size.y >= image_h) ? 1 : divide_up(image_h, tile_size.y);
+ int tile_h = (tile_size.y >= slice_h) ? 1 : divide_up(slice_h, tile_size.y);
- int nx = state.tiles[index].x / tile_size.x + dx[neighbor],
- ny = state.tiles[index].y / tile_size.y + dy[neighbor];
- if (nx < 0 || ny < 0 || nx >= tile_w || ny >= tile_h)
+ /* Tiles in the state tile list are always indexed from left to right, top to bottom. */
+ int nx = (index % tile_w) + dx[neighbor];
+ int ny = (index / tile_w) + dy[neighbor];
+ if (nx < 0 || ny < 0 || nx >= tile_w || ny >= tile_h * slice_num)
return -1;
return ny * state.tile_stride + nx;
@@ -426,15 +445,11 @@ bool TileManager::finish_tile(int index, bool &delete_tile)
{
delete_tile = false;
- if (progressive) {
- return true;
- }
-
switch (state.tiles[index].state) {
case Tile::RENDER: {
if (!schedule_denoising) {
state.tiles[index].state = Tile::DONE;
- delete_tile = true;
+ delete_tile = !progressive;
return true;
}
state.tiles[index].state = Tile::RENDERED;
@@ -457,15 +472,18 @@ bool TileManager::finish_tile(int index, bool &delete_tile)
int nindex = get_neighbor_index(index, neighbor);
if (check_neighbor_state(nindex, Tile::DENOISED)) {
state.tiles[nindex].state = Tile::DONE;
- /* It can happen that the tile just finished denoising and already can be freed here.
- * However, in that case it still has to be written before deleting, so we can't delete
- * it yet. */
- if (neighbor == 8) {
- delete_tile = true;
- }
- else {
- delete state.tiles[nindex].buffers;
- state.tiles[nindex].buffers = NULL;
+ /* Do not delete finished tiles in progressive mode. */
+ if (!progressive) {
+ /* It can happen that the tile just finished denoising and already can be freed here.
+ * However, in that case it still has to be written before deleting, so we can't delete
+ * it yet. */
+ if (neighbor == 4) {
+ delete_tile = true;
+ }
+ else {
+ delete state.tiles[nindex].buffers;
+ state.tiles[nindex].buffers = NULL;
+ }
}
}
}
@@ -477,27 +495,56 @@ bool TileManager::finish_tile(int index, bool &delete_tile)
}
}
-bool TileManager::next_tile(Tile *&tile, int device)
+bool TileManager::next_tile(Tile *&tile, int device, bool denoising)
{
- int logical_device = preserve_tile_device ? device : 0;
+ /* Preserve device if requested, unless this is a separate denoising device that just wants to
+ * grab any available tile. */
+ const bool preserve_device = preserve_tile_device && device < num_devices;
+
+ int tile_index = -1;
+ int logical_device = preserve_device ? device : 0;
+
+ if (denoising) {
+ while (logical_device < state.denoising_tiles.size()) {
+ if (state.denoising_tiles[logical_device].empty()) {
+ if (preserve_device) {
+ return false;
+ }
+ else {
+ logical_device++;
+ continue;
+ }
+ }
- if (logical_device >= state.render_tiles.size())
- return false;
+ tile_index = state.denoising_tiles[logical_device].front();
+ state.denoising_tiles[logical_device].pop_front();
+ break;
+ }
+ }
+ else {
+ while (logical_device < state.render_tiles.size()) {
+ if (state.render_tiles[logical_device].empty()) {
+ if (preserve_device) {
+ return false;
+ }
+ else {
+ logical_device++;
+ continue;
+ }
+ }
- if (!state.denoising_tiles[logical_device].empty()) {
- int idx = state.denoising_tiles[logical_device].front();
- state.denoising_tiles[logical_device].pop_front();
- tile = &state.tiles[idx];
- return true;
+ tile_index = state.render_tiles[logical_device].front();
+ state.render_tiles[logical_device].pop_front();
+ break;
+ }
}
- if (state.render_tiles[logical_device].empty())
- return false;
+ if (tile_index >= 0) {
+ tile = &state.tiles[tile_index];
+ return true;
+ }
- int idx = state.render_tiles[logical_device].front();
- state.render_tiles[logical_device].pop_front();
- tile = &state.tiles[idx];
- return true;
+ return false;
}
bool TileManager::done()
@@ -508,6 +555,16 @@ bool TileManager::done()
(state.sample + state.num_samples >= end_sample);
}
+bool TileManager::has_tiles()
+{
+ foreach (Tile &tile, state.tiles) {
+ if (tile.state != Tile::DONE) {
+ return true;
+ }
+ }
+ return false;
+}
+
bool TileManager::next()
{
if (done())