Blender V5.0
path_trace_work.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "device/device.h"
6
11
12#include "scene/film.h"
13#include "scene/scene.h"
14
15#include "session/buffers.h"
16
17#include "kernel/types.h"
18
20
22 Film *film,
23 DeviceScene *device_scene,
24 const bool *cancel_requested_flag)
25{
26 if (device->info.type == DEVICE_CPU) {
27 return make_unique<PathTraceWorkCPU>(device, film, device_scene, cancel_requested_flag);
28 }
29 if (device->info.type == DEVICE_DUMMY) {
30 /* Dummy devices can't perform any work. */
31 return nullptr;
32 }
33
34 return make_unique<PathTraceWorkGPU>(device, film, device_scene, cancel_requested_flag);
35}
36
38 Film *film,
39 DeviceScene *device_scene,
40 const bool *cancel_requested_flag)
41 : device_(device),
42 film_(film),
43 device_scene_(device_scene),
44 buffers_(make_unique<RenderBuffers>(device)),
46 cancel_requested_flag_(cancel_requested_flag)
47{
48}
49
51
56
58 const BufferParams &effective_big_tile_params,
59 const BufferParams &effective_buffer_params)
60{
61 effective_full_params_ = effective_full_params;
62 effective_big_tile_params_ = effective_big_tile_params;
63 effective_buffer_params_ = effective_buffer_params;
64}
65
67{
68 /* Assume if there are multiple works working on the same big tile none of the works gets the
69 * entire big tile to work on. */
74}
75
77{
79
80 const int64_t width = effective_buffer_params_.width;
81 const int64_t height = effective_buffer_params_.height;
82 const int64_t pass_stride = effective_buffer_params_.pass_stride;
83 const int64_t row_stride = width * pass_stride;
84 const int64_t data_size = row_stride * height * sizeof(float);
85
86 const int64_t offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
87 const int64_t offset_in_floats = offset_y * row_stride;
88
89 const float *src = buffers_->buffer.data();
90 float *dst = render_buffers->buffer.data() + offset_in_floats;
91
92 memcpy(dst, src, data_size);
93}
94
96{
97 const int64_t width = effective_buffer_params_.width;
98 const int64_t height = effective_buffer_params_.height;
99 const int64_t pass_stride = effective_buffer_params_.pass_stride;
100 const int64_t row_stride = width * pass_stride;
101 const int64_t data_size = row_stride * height * sizeof(float);
102
103 const int64_t offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
104 const int64_t offset_in_floats = offset_y * row_stride;
105
106 const float *src = render_buffers->buffer.data() + offset_in_floats;
107 float *dst = buffers_->buffer.data();
108
109 memcpy(dst, src, data_size);
110
112}
113
115{
116 const int64_t width = effective_buffer_params_.width;
117 const int64_t offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
118 const int64_t offset = offset_y * width;
119
121 buffers_.get(), effective_buffer_params_, render_buffers, effective_buffer_params_, offset);
122
124}
125
127 const PassAccessor::Destination &destination)
128{
129 const int offset_y = (effective_buffer_params_.full_y + effective_buffer_params_.window_y) -
131 const int width = effective_buffer_params_.width;
132
133 PassAccessor::Destination slice_destination = destination;
134 slice_destination.offset += offset_y * width;
135
136 return pass_accessor.get_render_tile_pixels(buffers_.get(), slice_destination);
137}
138
140 const PassAccessor::Source &source)
141{
142 const int offset_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y;
143 const int width = effective_buffer_params_.width;
144
145 PassAccessor::Source slice_source = source;
146 slice_source.offset += offset_y * width;
147
148 return pass_accessor.set_render_tile_pixels(buffers_.get(), slice_source);
149}
150
152{
153 const KernelFilm &kfilm = device_scene_->data.film;
154 const KernelBackground &kbackground = device_scene_->data.background;
155
156 const BufferParams &params = buffers_->params;
157
158 const BufferPass *display_pass = params.get_actual_display_pass(film_->get_display_pass());
159 if (display_pass == nullptr) {
160 /* Happens when interactive session changes display pass but render
161 * buffer does not contain it yet. */
163 }
164
165 PassAccessor::PassAccessInfo pass_access_info;
166 pass_access_info.type = display_pass->type;
167 pass_access_info.offset = PASS_UNUSED;
168
169 if (pass_mode == PassMode::DENOISED) {
170 pass_access_info.mode = PassMode::DENOISED;
171 pass_access_info.offset = params.get_pass_offset(pass_access_info.type, PassMode::DENOISED);
172 }
173
174 if (pass_access_info.offset == PASS_UNUSED) {
175 pass_access_info.mode = PassMode::NOISY;
176 pass_access_info.offset = params.get_pass_offset(pass_access_info.type);
177 }
178
179 pass_access_info.use_approximate_shadow_catcher = kfilm.use_approximate_shadow_catcher;
181 kfilm.use_approximate_shadow_catcher && !kbackground.transparent;
182
183 pass_access_info.show_active_pixels = film_->get_show_active_pixels();
184
185 return pass_access_info;
186}
187
189 const PathTraceDisplay *display, const PassMode mode) const
190{
191 PassAccessor::Destination destination(film_->get_display_pass(), mode);
192
193 const int2 display_texture_size = display->get_texture_size();
194 const int texture_x = effective_buffer_params_.full_x - effective_big_tile_params_.full_x +
196 const int texture_y = effective_buffer_params_.full_y - effective_big_tile_params_.full_y +
198
199 destination.offset = texture_y * display_texture_size.x + texture_x;
200 destination.stride = display_texture_size.x;
201
202 return destination;
203}
204
long long int int64_t
void render_buffers_host_copy_denoised(RenderBuffers *dst, const BufferParams &dst_params, const RenderBuffers *src, const BufferParams &src_params, const size_t src_offset)
Definition buffers.cpp:304
NODE_DECLARE PassType type
Definition buffers.h:28
DeviceType type
DeviceInfo info
Definition film.h:29
bool set_render_tile_pixels(RenderBuffers *render_buffers, const Source &source)
bool get_render_tile_pixels(const RenderBuffers *render_buffers, const Destination &destination) const
int2 get_texture_size() const
void copy_from_denoised_render_buffers(const RenderBuffers *render_buffers)
PassAccessor::Destination get_display_destination_template(const PathTraceDisplay *display, const PassMode mode) const
RenderBuffers * get_render_buffers()
unique_ptr< RenderBuffers > buffers_
BufferParams effective_full_params_
virtual bool copy_render_buffers_from_device()=0
static unique_ptr< PathTraceWork > create(Device *device, Film *film, DeviceScene *device_scene, const bool *cancel_requested_flag)
PassAccessor::PassAccessInfo get_display_pass_access_info(PassMode pass_mode) const
BufferParams effective_big_tile_params_
bool get_render_tile_pixels(const PassAccessor &pass_accessor, const PassAccessor::Destination &destination)
virtual bool copy_render_buffers_to_device()=0
bool has_multiple_works() const
void copy_to_render_buffers(RenderBuffers *render_buffers)
void set_effective_buffer_params(const BufferParams &effective_full_params, const BufferParams &effective_big_tile_params, const BufferParams &effective_buffer_params)
void copy_from_render_buffers(const RenderBuffers *render_buffers)
BufferParams effective_buffer_params_
DeviceScene * device_scene_
PathTraceWork(Device *device, Film *film, DeviceScene *device_scene, const bool *cancel_requested_flag)
const bool * cancel_requested_flag_
virtual ~PathTraceWork()
bool set_render_tile_pixels(PassAccessor &pass_accessor, const PassAccessor::Source &source)
device_vector< float > buffer
Definition buffers.h:158
nullptr float
#define PASS_UNUSED
#define CCL_NAMESPACE_END
@ DEVICE_DUMMY
@ DEVICE_CPU
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
PassMode
Definition pass.h:20
@ DENOISED
Definition pass.h:22
@ NOISY
Definition pass.h:21