Changeset View
Changeset View
Standalone View
Standalone View
intern/cycles/integrator/path_trace.cpp
| Show All 20 Lines | |||||
| CCL_NAMESPACE_BEGIN | CCL_NAMESPACE_BEGIN | ||||
| PathTrace::PathTrace(Device *device, | PathTrace::PathTrace(Device *device, | ||||
| Film *film, | Film *film, | ||||
| DeviceScene *device_scene, | DeviceScene *device_scene, | ||||
| RenderScheduler &render_scheduler, | RenderScheduler &render_scheduler, | ||||
| TileManager &tile_manager) | TileManager &tile_manager) | ||||
| : device_(device), | : device_(device), | ||||
| film_(film), | |||||
| device_scene_(device_scene), | device_scene_(device_scene), | ||||
| render_scheduler_(render_scheduler), | render_scheduler_(render_scheduler), | ||||
| tile_manager_(tile_manager) | tile_manager_(tile_manager) | ||||
| { | { | ||||
| DCHECK_NE(device_, nullptr); | DCHECK_NE(device_, nullptr); | ||||
| { | { | ||||
| vector<DeviceInfo> cpu_devices; | vector<DeviceInfo> cpu_devices; | ||||
| Show All 18 Lines | |||||
| PathTrace::~PathTrace() | PathTrace::~PathTrace() | ||||
| { | { | ||||
| destroy_gpu_resources(); | destroy_gpu_resources(); | ||||
| } | } | ||||
| void PathTrace::load_kernels() | void PathTrace::load_kernels() | ||||
| { | { | ||||
| if (denoiser_) { | if (denoiser_) { | ||||
| /* Activate graphics interop while denoiser device is created, so that it can choose a device | |||||
| * that supports interop for faster display updates. */ | |||||
| if (display_ && path_trace_works_.size() > 1) { | |||||
| display_->graphics_interop_activate(); | |||||
| } | |||||
| denoiser_->load_kernels(progress_); | denoiser_->load_kernels(progress_); | ||||
| if (display_ && path_trace_works_.size() > 1) { | |||||
| display_->graphics_interop_deactivate(); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| void PathTrace::alloc_work_memory() | void PathTrace::alloc_work_memory() | ||||
| { | { | ||||
| for (auto &&path_trace_work : path_trace_works_) { | for (auto &&path_trace_work : path_trace_works_) { | ||||
| path_trace_work->alloc_work_memory(); | path_trace_work->alloc_work_memory(); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 429 Lines • ▼ Show 20 Lines | if (!denoiser_) { | ||||
| return; | return; | ||||
| } | } | ||||
| VLOG_WORK << "Perform denoising work."; | VLOG_WORK << "Perform denoising work."; | ||||
| const double start_time = time_dt(); | const double start_time = time_dt(); | ||||
| RenderBuffers *buffer_to_denoise = nullptr; | RenderBuffers *buffer_to_denoise = nullptr; | ||||
| unique_ptr<RenderBuffers> multi_device_buffers; | |||||
| bool allow_inplace_modification = false; | bool allow_inplace_modification = false; | ||||
| if (path_trace_works_.size() == 1) { | |||||
| buffer_to_denoise = path_trace_works_.front()->get_render_buffers(); | |||||
| } | |||||
| else { | |||||
| Device *denoiser_device = denoiser_->get_denoiser_device(); | Device *denoiser_device = denoiser_->get_denoiser_device(); | ||||
| if (!denoiser_device) { | if (path_trace_works_.size() > 1 && denoiser_device && !denoiser_buffer_) { | ||||
| return; | denoiser_buffer_ = PathTraceWork::create(denoiser_device, film_, device_scene_, nullptr); | ||||
| } | } | ||||
| multi_device_buffers = make_unique<RenderBuffers>(denoiser_device); | if (denoiser_buffer_) { | ||||
| multi_device_buffers->reset(render_state_.effective_big_tile_params); | denoiser_buffer_->set_effective_buffer_params(render_state_.effective_big_tile_params, | ||||
| render_state_.effective_big_tile_params, | |||||
| render_state_.effective_big_tile_params); | |||||
| buffer_to_denoise = multi_device_buffers.get(); | buffer_to_denoise = denoiser_buffer_->get_render_buffers(); | ||||
| buffer_to_denoise->reset(render_state_.effective_big_tile_params); | |||||
| copy_to_render_buffers(multi_device_buffers.get()); | copy_to_render_buffers(buffer_to_denoise); | ||||
| allow_inplace_modification = true; | allow_inplace_modification = true; | ||||
| } | } | ||||
| else { | |||||
| DCHECK_EQ(path_trace_works_.size(), 1); | |||||
| buffer_to_denoise = path_trace_works_.front()->get_render_buffers(); | |||||
| } | |||||
| if (denoiser_->denoise_buffer(render_state_.effective_big_tile_params, | if (denoiser_->denoise_buffer(render_state_.effective_big_tile_params, | ||||
| buffer_to_denoise, | buffer_to_denoise, | ||||
| get_num_samples_in_buffer(), | get_num_samples_in_buffer(), | ||||
| allow_inplace_modification)) { | allow_inplace_modification)) { | ||||
| render_state_.has_denoised_result = true; | render_state_.has_denoised_result = true; | ||||
| } | } | ||||
| if (multi_device_buffers) { | |||||
| multi_device_buffers->copy_from_device(); | |||||
| parallel_for_each( | |||||
| path_trace_works_, [&multi_device_buffers](unique_ptr<PathTraceWork> &path_trace_work) { | |||||
| path_trace_work->copy_from_denoised_render_buffers(multi_device_buffers.get()); | |||||
| }); | |||||
| } | |||||
| render_scheduler_.report_denoise_time(render_work, time_dt() - start_time); | render_scheduler_.report_denoise_time(render_work, time_dt() - start_time); | ||||
| } | } | ||||
| void PathTrace::set_output_driver(unique_ptr<OutputDriver> driver) | void PathTrace::set_output_driver(unique_ptr<OutputDriver> driver) | ||||
| { | { | ||||
| output_driver_ = move(driver); | output_driver_ = move(driver); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (display_) { | ||||
| const PassMode pass_mode = render_work.display.use_denoised_result && | const PassMode pass_mode = render_work.display.use_denoised_result && | ||||
| render_state_.has_denoised_result ? | render_state_.has_denoised_result ? | ||||
| PassMode::DENOISED : | PassMode::DENOISED : | ||||
| PassMode::NOISY; | PassMode::NOISY; | ||||
| /* TODO(sergey): When using multi-device rendering map the GPUDisplay once and copy data from | /* TODO(sergey): When using multi-device rendering map the GPUDisplay once and copy data from | ||||
| * all works in parallel. */ | * all works in parallel. */ | ||||
| const int num_samples = get_num_samples_in_buffer(); | const int num_samples = get_num_samples_in_buffer(); | ||||
| if (denoiser_buffer_ && render_state_.has_denoised_result) { | |||||
| denoiser_buffer_->copy_to_display(display_.get(), pass_mode, num_samples); | |||||
| } | |||||
| else { | |||||
| for (auto &&path_trace_work : path_trace_works_) { | for (auto &&path_trace_work : path_trace_works_) { | ||||
| path_trace_work->copy_to_display(display_.get(), pass_mode, num_samples); | path_trace_work->copy_to_display(display_.get(), pass_mode, num_samples); | ||||
| } | } | ||||
| } | |||||
| display_->update_end(); | display_->update_end(); | ||||
| } | } | ||||
| render_scheduler_.report_display_update_time(render_work, time_dt() - start_time); | render_scheduler_.report_display_update_time(render_work, time_dt() - start_time); | ||||
| } | } | ||||
| void PathTrace::rebalance(const RenderWork &render_work) | void PathTrace::rebalance(const RenderWork &render_work) | ||||
| ▲ Show 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | void PathTrace::write_tile_buffer(const RenderWork &render_work) | ||||
| * of rendering (wither when all tiles are finished, or when rendering was requested to be | * of rendering (wither when all tiles are finished, or when rendering was requested to be | ||||
| * canceled). | * canceled). | ||||
| * | * | ||||
| * Important thing is: tile should be written to the software via callback only once. */ | * Important thing is: tile should be written to the software via callback only once. */ | ||||
| if (!has_multiple_tiles) { | if (!has_multiple_tiles) { | ||||
| VLOG_WORK << "Write tile result via buffer write callback."; | VLOG_WORK << "Write tile result via buffer write callback."; | ||||
| tile_buffer_write(); | tile_buffer_write(); | ||||
| } | } | ||||
| /* Write tile to disk, so that the render work's render buffer can be re-used for the next tile. | /* Write tile to disk, so that the render work's render buffer can be re-used for the next tile. | ||||
| */ | */ | ||||
| if (has_multiple_tiles) { | else { | ||||
| VLOG_WORK << "Write tile result into ."; | VLOG_WORK << "Write tile result to disk."; | ||||
| tile_buffer_write_to_disk(); | tile_buffer_write_to_disk(); | ||||
| } | } | ||||
| } | } | ||||
| void PathTrace::finalize_full_buffer_on_disk(const RenderWork &render_work) | void PathTrace::finalize_full_buffer_on_disk(const RenderWork &render_work) | ||||
| { | { | ||||
| if (!render_work.full.write) { | if (!render_work.full.write) { | ||||
| return; | return; | ||||
| ▲ Show 20 Lines • Show All 159 Lines • ▼ Show 20 Lines | |||||
| bool PathTrace::copy_render_tile_from_device() | bool PathTrace::copy_render_tile_from_device() | ||||
| { | { | ||||
| if (full_frame_state_.render_buffers) { | if (full_frame_state_.render_buffers) { | ||||
| /* Full-frame buffer is always allocated on CPU. */ | /* Full-frame buffer is always allocated on CPU. */ | ||||
| return true; | return true; | ||||
| } | } | ||||
| if (denoiser_buffer_ && render_state_.has_denoised_result) { | |||||
| return denoiser_buffer_->copy_render_buffers_from_device(); | |||||
| } | |||||
| bool success = true; | bool success = true; | ||||
| parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) { | parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) { | ||||
| if (!success) { | if (!success) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (!path_trace_work->copy_render_buffers_from_device()) { | if (!path_trace_work->copy_render_buffers_from_device()) { | ||||
| success = false; | success = false; | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
| bool PathTrace::get_render_tile_pixels(const PassAccessor &pass_accessor, | bool PathTrace::get_render_tile_pixels(const PassAccessor &pass_accessor, | ||||
| const PassAccessor::Destination &destination) | const PassAccessor::Destination &destination) | ||||
| { | { | ||||
| if (full_frame_state_.render_buffers) { | if (full_frame_state_.render_buffers) { | ||||
| return pass_accessor.get_render_tile_pixels(full_frame_state_.render_buffers, destination); | return pass_accessor.get_render_tile_pixels(full_frame_state_.render_buffers, destination); | ||||
| } | } | ||||
| if (denoiser_buffer_ && render_state_.has_denoised_result) { | |||||
| return denoiser_buffer_->get_render_tile_pixels(pass_accessor, destination); | |||||
| } | |||||
| bool success = true; | bool success = true; | ||||
| parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) { | parallel_for_each(path_trace_works_, [&](unique_ptr<PathTraceWork> &path_trace_work) { | ||||
| if (!success) { | if (!success) { | ||||
| return; | return; | ||||
| } | } | ||||
| if (!path_trace_work->get_render_tile_pixels(pass_accessor, destination)) { | if (!path_trace_work->get_render_tile_pixels(pass_accessor, destination)) { | ||||
| success = false; | success = false; | ||||
| ▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| /* Destroy any GPU resource which was used for graphics interop. | /* Destroy any GPU resource which was used for graphics interop. | ||||
| * Need to have access to the PathTraceDisplay as it is the only source of drawing context which | * Need to have access to the PathTraceDisplay as it is the only source of drawing context which | ||||
| * is used for interop. */ | * is used for interop. */ | ||||
| if (display_) { | if (display_) { | ||||
| for (auto &&path_trace_work : path_trace_works_) { | for (auto &&path_trace_work : path_trace_works_) { | ||||
| path_trace_work->destroy_gpu_resources(display_.get()); | path_trace_work->destroy_gpu_resources(display_.get()); | ||||
| } | } | ||||
| if (denoiser_buffer_) { | |||||
| denoiser_buffer_->destroy_gpu_resources(display_.get()); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /* -------------------------------------------------------------------- | /* -------------------------------------------------------------------- | ||||
| * Report generation. | * Report generation. | ||||
| */ | */ | ||||
| static const char *device_type_for_description(const DeviceType type) | static const char *device_type_for_description(const DeviceType type) | ||||
| ▲ Show 20 Lines • Show All 131 Lines • Show Last 20 Lines | |||||