diff options
Diffstat (limited to 'intern/cycles/render')
-rw-r--r-- | intern/cycles/render/buffers.cpp | 2 | ||||
-rw-r--r-- | intern/cycles/render/session.cpp | 246 | ||||
-rw-r--r-- | intern/cycles/render/session.h | 11 | ||||
-rw-r--r-- | intern/cycles/render/tile.cpp | 131 | ||||
-rw-r--r-- | intern/cycles/render/tile.h | 10 |
5 files changed, 292 insertions, 108 deletions
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp index b08b6c84c1d..41e1b73fdac 100644 --- a/intern/cycles/render/buffers.cpp +++ b/intern/cycles/render/buffers.cpp @@ -146,7 +146,7 @@ void RenderBuffers::reset(BufferParams ¶ms_) params = params_; /* re-allocate buffer */ - buffer.alloc(params.width * params.height * params.get_passes_size()); + buffer.alloc(params.width * params.get_passes_size(), params.height); buffer.zero_to_device(); } diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index dac7fbac806..160b77d5f14 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -183,7 +183,8 @@ bool Session::draw_gpu(BufferParams &buffer_params, DeviceDrawParams &draw_param if (gpu_draw_ready) { /* then verify the buffers have the expected size, so we don't * draw previous results in a resized window */ - if (!buffer_params.modified(display->params)) { + if (buffer_params.width == display->params.width && + buffer_params.height == display->params.height) { /* for CUDA we need to do tone-mapping still, since we can * only access GL buffers from the main thread. */ if (gpu_need_display_buffer_update) { @@ -211,6 +212,7 @@ void Session::run_gpu() reset_time = time_dt(); last_update_time = time_dt(); + last_display_time = last_update_time; progress.set_render_start_time(); @@ -291,12 +293,21 @@ void Session::run_gpu() * reset and draw in between */ thread_scoped_lock buffers_lock(buffers_mutex); + /* avoid excessive denoising in viewport after reaching a certain amount of samples */ + bool need_denoise = tile_manager.schedule_denoising || tile_manager.state.sample < 20 || + (time_dt() - last_display_time) >= params.progressive_update_timeout; + /* update status and timing */ update_status_time(); /* render */ render(); + /* denoise */ + if (need_denoise) { + denoise(); + } + device->task_wait(); if (!device->error_message().empty()) @@ -305,7 +316,7 @@ void Session::run_gpu() /* update status and timing */ update_status_time(); - gpu_need_display_buffer_update = true; + gpu_need_display_buffer_update = need_denoise || !params.run_denoising; gpu_draw_ready = true; progress.set_update(); @@ -359,7 +370,8 @@ bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_param if (display->draw_ready()) { /* then verify the buffers have the expected size, so we don't * draw previous results in a resized window */ - if (!buffer_params.modified(display->params)) { + if (buffer_params.width == display->params.width && + buffer_params.height == display->params.height) { display->draw(device, draw_params); if (display_outdated && (time_dt() - reset_time) > params.text_timeout) @@ -372,7 +384,7 @@ bool Session::draw_cpu(BufferParams &buffer_params, DeviceDrawParams &draw_param return false; } -bool Session::acquire_tile(Device *tile_device, RenderTile &rtile) +bool Session::acquire_tile(Device *tile_device, RenderTile &rtile, RenderTile::Task task) { if (progress.get_cancel()) { if (params.progressive_refine == false) { @@ -387,8 +399,14 @@ bool Session::acquire_tile(Device *tile_device, RenderTile &rtile) Tile *tile; int device_num = device->device_number(tile_device); - if (!tile_manager.next_tile(tile, device_num)) + while (!tile_manager.next_tile(tile, device_num, task == RenderTile::DENOISE)) { + /* Wait for denoising tiles to become available */ + if (task == RenderTile::DENOISE && !progress.get_cancel() && tile_manager.has_tiles()) { + denoising_cond.wait(tile_lock); + continue; + } return false; + } /* fill render tile */ rtile.x = tile_manager.state.buffer.full_x + tile->x; @@ -399,7 +417,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile &rtile) rtile.num_samples = tile_manager.state.num_samples; rtile.resolution = tile_manager.state.resolution_divider; rtile.tile_index = tile->index; - rtile.task = (tile->state == Tile::DENOISE) ? RenderTile::DENOISE : RenderTile::PATH_TRACE; + rtile.task = task; tile_lock.unlock(); @@ -413,6 +431,9 @@ bool Session::acquire_tile(Device *tile_device, RenderTile &rtile) device->map_tile(tile_device, rtile); + /* Reset copy state, since buffer contents change after the tile was acquired */ + buffers->map_neighbor_copied = false; + return true; } @@ -429,6 +450,8 @@ bool Session::acquire_tile(Device *tile_device, RenderTile &rtile) tile->buffers->reset(buffer_params); } + tile->buffers->map_neighbor_copied = false; + tile->buffers->params.get_offset_stride(rtile.offset, rtile.stride); rtile.buffer = tile->buffers->buffer.device_pointer; @@ -484,45 +507,75 @@ void Session::release_tile(RenderTile &rtile) } update_status_time(); + + /* Notify denoising thread that a tile was finished. */ + denoising_cond.notify_all(); } void Session::map_neighbor_tiles(RenderTile *tiles, Device *tile_device) { thread_scoped_lock tile_lock(tile_mutex); - int center_idx = tiles[4].tile_index; - assert(tile_manager.state.tiles[center_idx].state == Tile::DENOISE); - BufferParams buffer_params = tile_manager.params; - int4 image_region = make_int4(buffer_params.full_x, - buffer_params.full_y, - buffer_params.full_x + buffer_params.width, - buffer_params.full_y + buffer_params.height); - - for (int dy = -1, i = 0; dy <= 1; dy++) { - for (int dx = -1; dx <= 1; dx++, i++) { - int px = tiles[4].x + dx * params.tile_size.x; - int py = tiles[4].y + dy * params.tile_size.y; - if (px >= image_region.x && py >= image_region.y && px < image_region.z && - py < image_region.w) { - int tile_index = center_idx + dy * tile_manager.state.tile_stride + dx; - Tile *tile = &tile_manager.state.tiles[tile_index]; - assert(tile->buffers); - - tiles[i].buffer = tile->buffers->buffer.device_pointer; - tiles[i].x = tile_manager.state.buffer.full_x + tile->x; - tiles[i].y = tile_manager.state.buffer.full_y + tile->y; - tiles[i].w = tile->w; - tiles[i].h = tile->h; - tiles[i].buffers = tile->buffers; - - tile->buffers->params.get_offset_stride(tiles[i].offset, tiles[i].stride); - } - else { - tiles[i].buffer = (device_ptr)NULL; - tiles[i].buffers = NULL; - tiles[i].x = clamp(px, image_region.x, image_region.z); - tiles[i].y = clamp(py, image_region.y, image_region.w); - tiles[i].w = tiles[i].h = 0; + const int4 image_region = make_int4( + tile_manager.state.buffer.full_x, + tile_manager.state.buffer.full_y, + tile_manager.state.buffer.full_x + tile_manager.state.buffer.width, + tile_manager.state.buffer.full_y + tile_manager.state.buffer.height); + + if (!tile_manager.schedule_denoising) { + /* Fix up tile slices with overlap. */ + if (tile_manager.slice_overlap != 0) { + int y = max(tiles[4].y - tile_manager.slice_overlap, image_region.y); + tiles[4].h = min(tiles[4].y + tiles[4].h + tile_manager.slice_overlap, image_region.w) - y; + tiles[4].y = y; + } + + /* Tiles are not being denoised individually, which means the entire image is processed. */ + tiles[3].x = tiles[4].x; + tiles[1].y = tiles[4].y; + tiles[5].x = tiles[4].x + tiles[4].w; + tiles[7].y = tiles[4].y + tiles[4].h; + } + else { + int center_idx = tiles[4].tile_index; + assert(tile_manager.state.tiles[center_idx].state == Tile::DENOISE); + + for (int dy = -1, i = 0; dy <= 1; dy++) { + for (int dx = -1; dx <= 1; dx++, i++) { + int nindex = tile_manager.get_neighbor_index(center_idx, i); + if (nindex >= 0) { + Tile *tile = &tile_manager.state.tiles[nindex]; + + tiles[i].x = image_region.x + tile->x; + tiles[i].y = image_region.y + tile->y; + tiles[i].w = tile->w; + tiles[i].h = tile->h; + + if (buffers) { + tile_manager.state.buffer.get_offset_stride(tiles[i].offset, tiles[i].stride); + + tiles[i].buffer = buffers->buffer.device_pointer; + tiles[i].buffers = buffers; + } + else { + assert(tile->buffers); + tile->buffers->params.get_offset_stride(tiles[i].offset, tiles[i].stride); + + tiles[i].buffer = tile->buffers->buffer.device_pointer; + tiles[i].buffers = tile->buffers; + } + } + else { + int px = tiles[4].x + dx * params.tile_size.x; + int py = tiles[4].y + dy * params.tile_size.y; + + tiles[i].x = clamp(px, image_region.x, image_region.z); + tiles[i].y = clamp(py, image_region.y, image_region.w); + tiles[i].w = tiles[i].h = 0; + + tiles[i].buffer = (device_ptr)NULL; + tiles[i].buffers = NULL; + } } } } @@ -545,6 +598,7 @@ void Session::run_cpu() bool tiles_written = false; last_update_time = time_dt(); + last_display_time = last_update_time; { /* reset once to start */ @@ -620,11 +674,6 @@ void Session::run_cpu() } if (!no_tiles) { - /* buffers mutex is locked entirely while rendering each - * sample, and released/reacquired on each iteration to allow - * reset and draw in between */ - thread_scoped_lock buffers_lock(buffers_mutex); - /* update scene */ scoped_timer update_timer; if (update_scene()) { @@ -638,17 +687,31 @@ void Session::run_cpu() if (progress.get_cancel()) break; + /* buffers mutex is locked entirely while rendering each + * sample, and released/reacquired on each iteration to allow + * reset and draw in between */ + thread_scoped_lock buffers_lock(buffers_mutex); + + /* avoid excessive denoising in viewport after reaching a certain amount of samples */ + bool need_denoise = tile_manager.schedule_denoising || tile_manager.state.sample < 20 || + (time_dt() - last_display_time) >= params.progressive_update_timeout; + /* update status and timing */ update_status_time(); /* render */ render(); + /* denoise */ + if (need_denoise) { + denoise(); + } + /* update status and timing */ update_status_time(); if (!params.background) - need_copy_to_display_buffer = true; + need_copy_to_display_buffer = need_denoise || !params.run_denoising; if (!device->error_message().empty()) progress.set_error(device->error_message()); @@ -869,6 +932,20 @@ void Session::set_pause(bool pause_) pause_cond.notify_all(); } +void Session::set_denoising(bool denoising, bool optix_denoising) +{ + /* Lock buffers so no denoising operation is triggered while the settings are changed here. */ + thread_scoped_lock buffers_lock(buffers_mutex); + + params.run_denoising = denoising; + params.full_denoising = !optix_denoising; + params.optix_denoising = optix_denoising; + + // TODO(pmours): Query the required overlap value for denoising from the device? + tile_manager.slice_overlap = denoising && !params.background ? 64 : 0; + tile_manager.schedule_denoising = denoising && !buffers; +} + void Session::wait() { if (session_thread) { @@ -1016,33 +1093,74 @@ void Session::render() /* Add path trace task. */ DeviceTask task(DeviceTask::RENDER); - task.acquire_tile = function_bind(&Session::acquire_tile, this, _1, _2); + task.acquire_tile = function_bind(&Session::acquire_tile, this, _1, _2, RenderTile::PATH_TRACE); task.release_tile = function_bind(&Session::release_tile, this, _1); - task.map_neighbor_tiles = function_bind(&Session::map_neighbor_tiles, this, _1, _2); - task.unmap_neighbor_tiles = function_bind(&Session::unmap_neighbor_tiles, this, _1, _2); task.get_cancel = function_bind(&Progress::get_cancel, &this->progress); task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1); task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2); task.need_finish_queue = params.progressive_refine; task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH; - task.requested_tile_size = params.tile_size; - task.passes_size = tile_manager.params.get_passes_size(); - if (params.run_denoising) { - task.denoising = params.denoising; - - assert(!scene->film->need_update); - task.pass_stride = scene->film->pass_stride; - task.target_pass_stride = task.pass_stride; - task.pass_denoising_data = scene->film->denoising_data_offset; - task.pass_denoising_clean = scene->film->denoising_clean_offset; - - task.denoising_from_render = true; - task.denoising_do_filter = params.full_denoising; - task.denoising_use_optix = params.optix_denoising; - task.denoising_write_passes = params.write_denoising_passes; + device->task_add(task); +} + +void Session::denoise() +{ + if (!params.run_denoising) { + return; + } + + /* It can happen that denoising was already enabled, but the scene still needs an update. */ + if (scene->film->need_update || !scene->film->denoising_data_offset) { + return; } + /* Add separate denoising task. */ + DeviceTask task(DeviceTask::DENOISE); + + if (tile_manager.schedule_denoising) { + /* Run denoising on each tile. */ + task.acquire_tile = function_bind(&Session::acquire_tile, this, _1, _2, RenderTile::DENOISE); + task.release_tile = function_bind(&Session::release_tile, this, _1); + task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1); + task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2); + } + else { + assert(buffers); + + /* Wait for rendering to finish. */ + device->task_wait(); + + /* Run denoising on the whole image at once. */ + task.type = DeviceTask::DENOISE_BUFFER; + task.x = tile_manager.state.buffer.full_x; + task.y = tile_manager.state.buffer.full_y; + task.w = tile_manager.state.buffer.width; + task.h = tile_manager.state.buffer.height; + task.buffer = buffers->buffer.device_pointer; + task.sample = tile_manager.state.sample; + task.num_samples = tile_manager.state.num_samples; + tile_manager.state.buffer.get_offset_stride(task.offset, task.stride); + task.buffers = buffers; + } + + task.get_cancel = function_bind(&Progress::get_cancel, &this->progress); + task.need_finish_queue = params.progressive_refine; + task.map_neighbor_tiles = function_bind(&Session::map_neighbor_tiles, this, _1, _2); + task.unmap_neighbor_tiles = function_bind(&Session::unmap_neighbor_tiles, this, _1, _2); + + task.denoising = params.denoising; + + task.pass_stride = scene->film->pass_stride; + task.target_pass_stride = task.pass_stride; + task.pass_denoising_data = scene->film->denoising_data_offset; + task.pass_denoising_clean = scene->film->denoising_clean_offset; + + task.denoising_from_render = true; + task.denoising_do_filter = params.full_denoising; + task.denoising_use_optix = params.optix_denoising; + task.denoising_write_passes = params.write_denoising_passes; + device->task_add(task); } @@ -1067,6 +1185,8 @@ void Session::copy_to_display_buffer(int sample) /* set display to new size */ display->draw_set(task.w, task.h); + + last_display_time = time_dt(); } display_outdated = false; diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h index ec465601541..3ef2b70879a 100644 --- a/intern/cycles/render/session.h +++ b/intern/cycles/render/session.h @@ -154,6 +154,7 @@ class Session { void reset(BufferParams ¶ms, int samples); void set_samples(int samples); void set_pause(bool pause); + void set_denoising(bool denoising, bool optix_denoising); bool update_scene(); bool load_kernels(bool lock_scene = true); @@ -178,8 +179,10 @@ class Session { void update_status_time(bool show_pause = false, bool show_done = false); - void copy_to_display_buffer(int sample); void render(); + void denoise(); + void copy_to_display_buffer(int sample); + void reset_(BufferParams ¶ms, int samples); void run_cpu(); @@ -190,7 +193,7 @@ class Session { bool draw_gpu(BufferParams ¶ms, DeviceDrawParams &draw_params); void reset_gpu(BufferParams ¶ms, int samples); - bool acquire_tile(Device *tile_device, RenderTile &tile); + bool acquire_tile(Device *tile_device, RenderTile &tile, RenderTile::Task task); void update_tile_sample(RenderTile &tile); void release_tile(RenderTile &tile); @@ -213,14 +216,16 @@ class Session { thread_mutex tile_mutex; thread_mutex buffers_mutex; thread_mutex display_mutex; + thread_condition_variable denoising_cond; bool kernels_loaded; DeviceRequestedFeatures loaded_kernel_features; double reset_time; + double last_update_time; + double last_display_time; /* progressive refine */ - double last_update_time; bool update_progressive_refine(bool cancel); DeviceRequestedFeatures get_requested_device_features(); 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()) diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h index 017c1af0ead..14c693683c4 100644 --- a/intern/cycles/render/tile.h +++ b/intern/cycles/render/tile.h @@ -89,6 +89,7 @@ class TileManager { } state; int num_samples; + int slice_overlap; TileManager(bool progressive, int num_samples, @@ -105,15 +106,19 @@ class TileManager { void reset(BufferParams ¶ms, int num_samples); void set_samples(int num_samples); bool next(); - bool next_tile(Tile *&tile, int device = 0); + bool next_tile(Tile *&tile, int device, bool denoising); bool finish_tile(int index, bool &delete_tile); bool done(); + bool has_tiles(); void set_tile_order(TileOrder tile_order_) { tile_order = tile_order_; } + int get_neighbor_index(int index, int neighbor); + bool check_neighbor_state(int index, Tile::State state); + /* ** Sample range rendering. ** */ /* Start sample in the range. */ @@ -160,9 +165,6 @@ class TileManager { /* Generate tile list, return number of tiles. */ int gen_tiles(bool sliced); void gen_render_tiles(); - - int get_neighbor_index(int index, int neighbor); - bool check_neighbor_state(int index, Tile::State state); }; CCL_NAMESPACE_END |