Fix T75432: Cycles progressive refine render slow with denoising data
Only perform denoising prefilter for the last sample, not every sample.
This commit is contained in:
parent
475bd6b829
commit
05274ca829
@ -293,14 +293,12 @@ 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 */
|
||||
bool delayed_denoise = false;
|
||||
const bool need_denoise = render_need_denoise(delayed_denoise);
|
||||
render(need_denoise);
|
||||
|
||||
device->task_wait();
|
||||
@ -311,7 +309,7 @@ void Session::run_gpu()
|
||||
/* update status and timing */
|
||||
update_status_time();
|
||||
|
||||
gpu_need_display_buffer_update = need_denoise || !params.run_denoising;
|
||||
gpu_need_display_buffer_update = !delayed_denoise;
|
||||
gpu_draw_ready = true;
|
||||
progress.set_update();
|
||||
|
||||
@ -477,7 +475,7 @@ void Session::update_tile_sample(RenderTile &rtile)
|
||||
update_status_time();
|
||||
}
|
||||
|
||||
void Session::release_tile(RenderTile &rtile)
|
||||
void Session::release_tile(RenderTile &rtile, const bool need_denoise)
|
||||
{
|
||||
thread_scoped_lock tile_lock(tile_mutex);
|
||||
|
||||
@ -485,7 +483,7 @@ void Session::release_tile(RenderTile &rtile)
|
||||
|
||||
bool delete_tile;
|
||||
|
||||
if (tile_manager.finish_tile(rtile.tile_index, delete_tile)) {
|
||||
if (tile_manager.finish_tile(rtile.tile_index, need_denoise, delete_tile)) {
|
||||
if (write_render_tile_cb && params.progressive_refine == false) {
|
||||
write_render_tile_cb(rtile);
|
||||
}
|
||||
@ -687,21 +685,19 @@ void Session::run_cpu()
|
||||
* 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 */
|
||||
bool delayed_denoise = false;
|
||||
const bool need_denoise = render_need_denoise(delayed_denoise);
|
||||
render(need_denoise);
|
||||
|
||||
/* update status and timing */
|
||||
update_status_time();
|
||||
|
||||
if (!params.background)
|
||||
need_copy_to_display_buffer = need_denoise || !params.run_denoising;
|
||||
need_copy_to_display_buffer = !delayed_denoise;
|
||||
|
||||
if (!device->error_message().empty())
|
||||
progress.set_error(device->error_message());
|
||||
@ -1083,7 +1079,46 @@ void Session::update_status_time(bool show_pause, bool show_done)
|
||||
progress.set_status(status, substatus);
|
||||
}
|
||||
|
||||
void Session::render(bool with_denoising)
|
||||
bool Session::render_need_denoise(bool &delayed)
|
||||
{
|
||||
delayed = false;
|
||||
|
||||
/* Denoising enabled? */
|
||||
if (!params.run_denoising) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (params.background) {
|
||||
/* Background render, only denoise when rendering the last sample. */
|
||||
return tile_manager.done();
|
||||
}
|
||||
|
||||
/* Viewport render. */
|
||||
|
||||
/* 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 false;
|
||||
}
|
||||
|
||||
/* Do not denoise until the sample at which denoising should start is reached. */
|
||||
if (tile_manager.state.sample < params.denoising_start_sample) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Cannot denoise with resolution divider and separate denoising devices.
|
||||
* It breaks the copy in 'MultiDevice::map_neighbor_tiles' (which operates on
|
||||
* the full buffer dimensions and not the scaled ones). */
|
||||
if (!params.device.denoising_devices.empty() && tile_manager.state.resolution_divider > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Avoid excessive denoising in viewport after reaching a certain amount of samples. */
|
||||
delayed = (tile_manager.state.sample >= 20 &&
|
||||
(time_dt() - last_display_time) < params.progressive_update_timeout);
|
||||
return !delayed;
|
||||
}
|
||||
|
||||
void Session::render(bool need_denoise)
|
||||
{
|
||||
if (buffers && tile_manager.state.sample == tile_manager.range_start_sample) {
|
||||
/* Clear buffers. */
|
||||
@ -1098,7 +1133,7 @@ void Session::render(bool with_denoising)
|
||||
DeviceTask task(DeviceTask::RENDER);
|
||||
|
||||
task.acquire_tile = function_bind(&Session::acquire_tile, this, _2, _1, _3);
|
||||
task.release_tile = function_bind(&Session::release_tile, this, _1);
|
||||
task.release_tile = function_bind(&Session::release_tile, this, _1, need_denoise);
|
||||
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);
|
||||
@ -1115,27 +1150,7 @@ void Session::render(bool with_denoising)
|
||||
/* Acquire render tiles by default. */
|
||||
task.tile_types = RenderTile::PATH_TRACE;
|
||||
|
||||
with_denoising = params.run_denoising && with_denoising;
|
||||
if (with_denoising) {
|
||||
/* Do not denoise viewport until the sample at which denoising should start is reached. */
|
||||
if (!params.background && tile_manager.state.sample < params.denoising_start_sample) {
|
||||
with_denoising = false;
|
||||
}
|
||||
|
||||
/* Cannot denoise with resolution divider and separate denoising devices.
|
||||
* It breaks the copy in 'MultiDevice::map_neighbor_tiles' (which operates on the full buffer
|
||||
* dimensions and not the scaled ones). */
|
||||
if (!params.device.denoising_devices.empty() && tile_manager.state.resolution_divider > 1) {
|
||||
with_denoising = false;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
with_denoising = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (with_denoising) {
|
||||
if (need_denoise) {
|
||||
task.denoising = params.denoising;
|
||||
|
||||
task.pass_stride = scene->film->pass_stride;
|
||||
|
@ -186,7 +186,7 @@ class Session {
|
||||
|
||||
void update_status_time(bool show_pause = false, bool show_done = false);
|
||||
|
||||
void render(bool with_denoising);
|
||||
void render(bool use_denoise);
|
||||
void copy_to_display_buffer(int sample);
|
||||
|
||||
void reset_(BufferParams ¶ms, int samples);
|
||||
@ -199,9 +199,11 @@ class Session {
|
||||
bool draw_gpu(BufferParams ¶ms, DeviceDrawParams &draw_params);
|
||||
void reset_gpu(BufferParams ¶ms, int samples);
|
||||
|
||||
bool render_need_denoise(bool &delayed);
|
||||
|
||||
bool acquire_tile(RenderTile &tile, Device *tile_device, uint tile_types);
|
||||
void update_tile_sample(RenderTile &tile);
|
||||
void release_tile(RenderTile &tile);
|
||||
void release_tile(RenderTile &tile, const bool need_denoise);
|
||||
|
||||
void map_neighbor_tiles(RenderTile *tiles, Device *tile_device);
|
||||
void unmap_neighbor_tiles(RenderTile *tiles, Device *tile_device);
|
||||
|
@ -441,13 +441,13 @@ bool TileManager::check_neighbor_state(int index, Tile::State min_state)
|
||||
|
||||
/* Returns whether the tile should be written (and freed if no denoising is used) instead of
|
||||
* updating. */
|
||||
bool TileManager::finish_tile(int index, bool &delete_tile)
|
||||
bool TileManager::finish_tile(const int index, const bool need_denoise, bool &delete_tile)
|
||||
{
|
||||
delete_tile = false;
|
||||
|
||||
switch (state.tiles[index].state) {
|
||||
case Tile::RENDER: {
|
||||
if (!schedule_denoising) {
|
||||
if (!(schedule_denoising && need_denoise)) {
|
||||
state.tiles[index].state = Tile::DONE;
|
||||
delete_tile = !progressive;
|
||||
return true;
|
||||
|
@ -107,7 +107,7 @@ class TileManager {
|
||||
void set_samples(int num_samples);
|
||||
bool next();
|
||||
bool next_tile(Tile *&tile, int device, uint tile_types);
|
||||
bool finish_tile(int index, bool &delete_tile);
|
||||
bool finish_tile(const int index, const bool need_denoise, bool &delete_tile);
|
||||
bool done();
|
||||
bool has_tiles();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user