d32d787f5f
For example ``` OIIOOutputDriver::~OIIOOutputDriver() { } ``` becomes ``` OIIOOutputDriver::~OIIOOutputDriver() {} ``` Saves quite some vertical space, which is especially handy for constructors. Pull Request: https://projects.blender.org/blender/blender/pulls/105594
198 lines
7.4 KiB
C++
198 lines
7.4 KiB
C++
/* SPDX-License-Identifier: Apache-2.0
|
|
* Copyright 2011-2022 Blender Foundation */
|
|
|
|
#include "device/device.h"
|
|
|
|
#include "integrator/path_trace_display.h"
|
|
#include "integrator/path_trace_work.h"
|
|
#include "integrator/path_trace_work_cpu.h"
|
|
#include "integrator/path_trace_work_gpu.h"
|
|
#include "scene/film.h"
|
|
#include "scene/scene.h"
|
|
#include "session/buffers.h"
|
|
|
|
#include "kernel/types.h"
|
|
|
|
CCL_NAMESPACE_BEGIN
|
|
|
|
unique_ptr<PathTraceWork> PathTraceWork::create(Device *device,
|
|
Film *film,
|
|
DeviceScene *device_scene,
|
|
bool *cancel_requested_flag)
|
|
{
|
|
if (device->info.type == DEVICE_CPU) {
|
|
return make_unique<PathTraceWorkCPU>(device, film, device_scene, cancel_requested_flag);
|
|
}
|
|
if (device->info.type == DEVICE_DUMMY) {
|
|
/* Dummy devices can't perform any work. */
|
|
return nullptr;
|
|
}
|
|
|
|
return make_unique<PathTraceWorkGPU>(device, film, device_scene, cancel_requested_flag);
|
|
}
|
|
|
|
PathTraceWork::PathTraceWork(Device *device,
|
|
Film *film,
|
|
DeviceScene *device_scene,
|
|
bool *cancel_requested_flag)
|
|
: device_(device),
|
|
film_(film),
|
|
device_scene_(device_scene),
|
|
buffers_(make_unique<RenderBuffers>(device)),
|
|
effective_buffer_params_(buffers_->params),
|
|
cancel_requested_flag_(cancel_requested_flag)
|
|
{
|
|
}
|
|
|
|
PathTraceWork::~PathTraceWork() {}
|
|
|
|
RenderBuffers *PathTraceWork::get_render_buffers()
|
|
{
|
|
return buffers_.get();
|
|
}
|
|
|
|
void PathTraceWork::set_effective_buffer_params(const BufferParams &effective_full_params,
|
|
const BufferParams &effective_big_tile_params,
|
|
const BufferParams &effective_buffer_params)
|
|
{
|
|
effective_full_params_ = effective_full_params;
|
|
effective_big_tile_params_ = effective_big_tile_params;
|
|
effective_buffer_params_ = effective_buffer_params;
|
|
}
|
|
|
|
bool PathTraceWork::has_multiple_works() const
|
|
{
|
|
/* Assume if there are multiple works working on the same big tile none of the works gets the
|
|
* entire big tile to work on. */
|
|
return !(effective_big_tile_params_.width == effective_buffer_params_.width &&
|
|
effective_big_tile_params_.height == effective_buffer_params_.height &&
|
|
effective_big_tile_params_.full_x == effective_buffer_params_.full_x &&
|
|
effective_big_tile_params_.full_y == effective_buffer_params_.full_y);
|
|
}
|
|
|
|
void PathTraceWork::copy_to_render_buffers(RenderBuffers *render_buffers)
|
|
{
|
|
copy_render_buffers_from_device();
|
|
|
|
const int64_t width = effective_buffer_params_.width;
|
|
const int64_t height = effective_buffer_params_.height;
|
|
const int64_t pass_stride = effective_buffer_params_.pass_stride;
|
|
const int64_t row_stride = width * pass_stride;
|
|
const int64_t data_size = row_stride * height * sizeof(float);
|
|
|
|
const int64_t offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
|
|
const int64_t offset_in_floats = offset_y * row_stride;
|
|
|
|
const float *src = buffers_->buffer.data();
|
|
float *dst = render_buffers->buffer.data() + offset_in_floats;
|
|
|
|
memcpy(dst, src, data_size);
|
|
}
|
|
|
|
void PathTraceWork::copy_from_render_buffers(const RenderBuffers *render_buffers)
|
|
{
|
|
const int64_t width = effective_buffer_params_.width;
|
|
const int64_t height = effective_buffer_params_.height;
|
|
const int64_t pass_stride = effective_buffer_params_.pass_stride;
|
|
const int64_t row_stride = width * pass_stride;
|
|
const int64_t data_size = row_stride * height * sizeof(float);
|
|
|
|
const int64_t offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
|
|
const int64_t offset_in_floats = offset_y * row_stride;
|
|
|
|
const float *src = render_buffers->buffer.data() + offset_in_floats;
|
|
float *dst = buffers_->buffer.data();
|
|
|
|
memcpy(dst, src, data_size);
|
|
|
|
copy_render_buffers_to_device();
|
|
}
|
|
|
|
void PathTraceWork::copy_from_denoised_render_buffers(const RenderBuffers *render_buffers)
|
|
{
|
|
const int64_t width = effective_buffer_params_.width;
|
|
const int64_t offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
|
|
const int64_t offset = offset_y * width;
|
|
|
|
render_buffers_host_copy_denoised(
|
|
buffers_.get(), effective_buffer_params_, render_buffers, effective_buffer_params_, offset);
|
|
|
|
copy_render_buffers_to_device();
|
|
}
|
|
|
|
bool PathTraceWork::get_render_tile_pixels(const PassAccessor &pass_accessor,
|
|
const PassAccessor::Destination &destination)
|
|
{
|
|
const int offset_y = (effective_buffer_params_.full_y + effective_buffer_params_.window_y) -
|
|
(effective_big_tile_params_.full_y + effective_big_tile_params_.window_y);
|
|
const int width = effective_buffer_params_.width;
|
|
|
|
PassAccessor::Destination slice_destination = destination;
|
|
slice_destination.offset += offset_y * width;
|
|
|
|
return pass_accessor.get_render_tile_pixels(buffers_.get(), slice_destination);
|
|
}
|
|
|
|
bool PathTraceWork::set_render_tile_pixels(PassAccessor &pass_accessor,
|
|
const PassAccessor::Source &source)
|
|
{
|
|
const int offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
|
|
const int width = effective_buffer_params_.width;
|
|
|
|
PassAccessor::Source slice_source = source;
|
|
slice_source.offset += offset_y * width;
|
|
|
|
return pass_accessor.set_render_tile_pixels(buffers_.get(), slice_source);
|
|
}
|
|
|
|
PassAccessor::PassAccessInfo PathTraceWork::get_display_pass_access_info(PassMode pass_mode) const
|
|
{
|
|
const KernelFilm &kfilm = device_scene_->data.film;
|
|
const KernelBackground &kbackground = device_scene_->data.background;
|
|
|
|
const BufferParams ¶ms = buffers_->params;
|
|
|
|
const BufferPass *display_pass = params.get_actual_display_pass(film_->get_display_pass());
|
|
|
|
PassAccessor::PassAccessInfo pass_access_info;
|
|
pass_access_info.type = display_pass->type;
|
|
pass_access_info.offset = PASS_UNUSED;
|
|
|
|
if (pass_mode == PassMode::DENOISED) {
|
|
pass_access_info.mode = PassMode::DENOISED;
|
|
pass_access_info.offset = params.get_pass_offset(pass_access_info.type, PassMode::DENOISED);
|
|
}
|
|
|
|
if (pass_access_info.offset == PASS_UNUSED) {
|
|
pass_access_info.mode = PassMode::NOISY;
|
|
pass_access_info.offset = params.get_pass_offset(pass_access_info.type);
|
|
}
|
|
|
|
pass_access_info.use_approximate_shadow_catcher = kfilm.use_approximate_shadow_catcher;
|
|
pass_access_info.use_approximate_shadow_catcher_background =
|
|
kfilm.use_approximate_shadow_catcher && !kbackground.transparent;
|
|
|
|
pass_access_info.show_active_pixels = film_->get_show_active_pixels();
|
|
|
|
return pass_access_info;
|
|
}
|
|
|
|
PassAccessor::Destination PathTraceWork::get_display_destination_template(
|
|
const PathTraceDisplay *display) const
|
|
{
|
|
PassAccessor::Destination destination(film_->get_display_pass());
|
|
|
|
const int2 display_texture_size = display->get_texture_size();
|
|
const int texture_x = effective_buffer_params_.full_x - effective_big_tile_params_.full_x +
|
|
effective_buffer_params_.window_x - effective_big_tile_params_.window_x;
|
|
const int texture_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y +
|
|
effective_buffer_params_.window_y - effective_big_tile_params_.window_y;
|
|
|
|
destination.offset = texture_y * display_texture_size.x + texture_x;
|
|
destination.stride = display_texture_size.x;
|
|
|
|
return destination;
|
|
}
|
|
|
|
CCL_NAMESPACE_END
|