Blender V5.0
path_trace.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
7#include <functional>
8
10#include "integrator/guiding.h"
14
15#include "session/buffers.h"
16
17#include "util/guiding.h" // IWYU pragma: keep
18#include "util/thread.h"
19#include "util/unique_ptr.h"
20#include "util/vector.h"
21
23
25class Device;
26class DeviceScene;
27class DisplayDriver;
28class Film;
29class RenderBuffers;
30class RenderScheduler;
31class RenderWork;
33class OutputDriver;
34class Progress;
35class TileManager;
36
37/* PathTrace class takes care of kernel graph and scheduling on a (multi)device. It takes care of
38 * all the common steps of path tracing which are not device-specific. The list of tasks includes
39 * but is not limited to:
40 * - Kernel graph.
41 * - Scheduling logic.
42 * - Queues management.
43 * - Adaptive stopping. */
44class PathTrace {
45 public:
46 /* Render scheduler is used to report timing information and access things like start/finish
47 * sample. */
48 PathTrace(Device *device,
49 Device *denoise_device,
50 Film *film,
51 DeviceScene *device_scene,
52 RenderScheduler &render_scheduler,
53 TileManager &tile_manager);
54 ~PathTrace();
55
56 /* Create devices and load kernels which are created on-demand (for example, denoising devices).
57 * The progress is reported to the currently configure progress object (via `set_progress`). */
58 void load_kernels();
59
60 /* Allocate working memory. This runs before allocating scene memory so that we can estimate
61 * more accurately which scene device memory may need to allocated on the host. */
62 void alloc_work_memory();
63
64 /* Check whether now it is a good time to reset rendering.
65 * Used to avoid very often resets in the viewport, giving it a chance to draw intermediate
66 * render result. */
67 bool ready_to_reset();
68
69 void reset(const BufferParams &full_params,
70 const BufferParams &big_tile_params,
71 bool reset_rendering);
72
73 void device_free();
74
75 /* Set progress tracker.
76 * Used to communicate details about the progress to the outer world, check whether rendering is
77 * to be canceled.
78 *
79 * The path tracer writes to this object, and then at a convenient moment runs
80 * progress_update_cb() callback. */
81 void set_progress(Progress *progress);
82
83 /* NOTE: This is a blocking call. Meaning, it will not return until given number of samples are
84 * rendered (or until rendering is requested to be canceled). */
85 void render(const RenderWork &render_work);
86
87 /* TODO(sergey): Decide whether denoiser is really a part of path tracer. Currently it is
88 * convenient to have it here because then its easy to access render buffer. But the downside is
89 * that this adds too much of entities which can live separately with some clear API. */
90
91 /* Set denoiser parameters.
92 * Use this to configure the denoiser before rendering any samples. */
94
95 /* Set parameters used for adaptive sampling.
96 * Use this to configure the adaptive sampler before rendering any samples. */
97 void set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling);
98
99 /* Set the parameters for guiding.
100 * Use to setup the guiding structures before each rendering iteration. */
101 void set_guiding_params(const GuidingParams &params, const bool reset);
102
103 /* Sets output driver for render buffer output. */
105
106 /* Set display driver for interactive render buffer display. */
108
109 /* Clear the display buffer by filling it in with all zeroes. */
110 void zero_display();
111
112 /* Perform drawing of the current state of the DisplayDriver. */
113 void draw();
114
115 /* Flush outstanding display commands before ending the render loop. */
116 void flush_display();
117
118 /* Cancel rendering process as soon as possible, without waiting for full tile to be sampled.
119 * Used in cases like reset of render session.
120 *
121 * This is a blocking call, which returns as soon as there is no running `render_samples()` call.
122 */
123 void cancel();
124
125 /* Copy an entire render buffer to/from the path trace. */
126
127 /* Copy happens via CPU side buffer: data will be copied from every device of the path trace, and
128 * the data will be copied to the device of the given render buffers. */
130
131 /* Copy happens via CPU side buffer: data will be copied from the device of the given render
132 * buffers and will be copied to all devices of the path trace. */
134
135 /* Copy render buffers of the big tile from the device to host.
136 * Return true if all copies are successful. */
138
139 /* Read given full-frame file from disk, perform needed processing and write it to the software
140 * via the write callback. */
141 void process_full_buffer_from_disk(string_view filename);
142
143 /* Get number of samples in the current big tile render buffers. */
144 int get_num_render_tile_samples() const;
145
146 /* Get pass data of the entire big tile.
147 * This call puts pass render result from all devices into the final pixels storage.
148 *
149 * NOTE: Expects buffers to be copied to the host using `copy_render_tile_from_device()`.
150 *
151 * Returns false if any of the accessor's `get_render_tile_pixels()` returned false. */
152 bool get_render_tile_pixels(const PassAccessor &pass_accessor,
153 const PassAccessor::Destination &destination);
154
155 /* Set pass data for baking. */
156 bool set_render_tile_pixels(PassAccessor &pass_accessor, const PassAccessor::Source &source);
157
158 /* Check whether denoiser was run and denoised passes are available. */
160
161 /* Get size and offset (relative to the buffer's full x/y) of the currently rendering tile.
162 * In the case of tiled rendering this will return full-frame after all tiles has been rendered.
163 *
164 * NOTE: If the full-frame buffer processing is in progress, returns parameters of the full-frame
165 * instead. */
168 int2 get_render_size() const;
169
170 /* Get buffer parameters of the current tile.
171 *
172 * NOTE: If the full-frame buffer processing is in progress, returns parameters of the full-frame
173 * instead. */
175
176 /* Generate full multi-line report of the rendering process, including rendering parameters,
177 * times, and so on. */
178 string full_report() const;
179
180 /* Callback which is called to report current rendering progress.
181 *
182 * It is supposed to be cheaper than buffer update/write, hence can be called more often.
183 * Additionally, it might be called form the middle of wavefront (meaning, it is not guaranteed
184 * that the buffer is "uniformly" sampled at the moment of this callback). */
185 std::function<void(void)> progress_update_cb;
186
187 protected:
188 /* Actual implementation of the rendering pipeline.
189 * Calls steps in order, checking for the cancel to be requested in between.
190 *
191 * Is separate from `render()` to simplify dealing with the early outputs and keeping
192 * `render_cancel_` in the consistent state. */
193 void render_pipeline(RenderWork render_work);
194
195 /* Initialize kernel execution on all integrator queues. */
197
198 /* Make sure both allocated and effective buffer parameters of path tracer works are up to date
199 * with the current big tile parameters, performance-dependent slicing, and resolution divider.
200 */
201 void update_work_buffer_params_if_needed(const RenderWork &render_work);
203 void update_effective_work_buffer_params(const RenderWork &render_work);
204
205 /* Perform various steps of the render work.
206 *
207 * Note that some steps might modify the work, forcing some steps to happen within this iteration
208 * of rendering. */
209 void init_render_buffers(const RenderWork &render_work);
210 void path_trace(RenderWork &render_work);
211 void adaptive_sample(RenderWork &render_work);
212 void denoise(const RenderWork &render_work);
213 void denoise_volume_guiding_buffers(const RenderWork &render_work, const bool has_volume);
214 void cryptomatte_postprocess(const RenderWork &render_work);
215 void update_display(const RenderWork &render_work);
216 void rebalance(const RenderWork &render_work);
217 void write_tile_buffer(const RenderWork &render_work);
218 void finalize_full_buffer_on_disk(const RenderWork &render_work);
219
220 /* Updates/initializes the guiding structures after a rendering iteration.
221 * The structures are updated using the training data/samples generated during the previous
222 * rendering iteration */
224
225 /* Prepares the per-kernel thread related guiding structures (e.g., PathSegmentStorage,
226 * pointers to the global Field and SegmentStorage)*/
228
229 /* Get number of samples in the current state of the render buffers. */
231
232 /* Check whether user requested to cancel rendering, so that path tracing is to be finished as
233 * soon as possible. */
234 bool is_cancel_requested();
235
236 /* Write the big tile render buffer via the write callback. */
237 void tile_buffer_write();
238
239 /* Read the big tile render buffer via the read callback. */
240 void tile_buffer_read();
241
242 /* Write current tile into the file on disk. */
244
245 /* Run the progress_update_cb callback if it is needed. */
246 void progress_update_if_needed(const RenderWork &render_work);
247
248 void progress_set_status(const string &status, const string &substatus = "");
249
250 /* Destroy GPU resources (such as graphics interop) used by work. */
252
253 /* Pointer to a device which is configured to be used for path tracing. If multiple devices
254 * are configured this is a `MultiDevice`. */
255 Device *device_ = nullptr;
256
257 /* Pointer to a device which is configured to be used for denoising. Can be identical
258 * to the device */
260
261 /* CPU device for creating temporary render buffers on the CPU side. */
263
266
269
270 /* Display driver for interactive render buffer display. */
272
273 /* Output driver to write render buffer to. */
275
276 /* Per-compute device descriptors of work which is responsible for path tracing on its configured
277 * device. */
279
280 /* Per-path trace work information needed for multi-device balancing. */
282
283 /* Render buffer parameters of the full frame and current big tile. */
286
287 /* Denoiser which takes care of denoising the big tile. */
289
290 /* Denoiser device descriptor which holds the denoised big tile for multi-device workloads. */
292
293#if defined(WITH_PATH_GUIDING)
294 /* Guiding related attributes */
295 GuidingParams guiding_params_;
296
297 /* The guiding field which holds the representation of the incident radiance field for the
298 * complete scene. */
299 unique_ptr<openpgl::cpp::Field> guiding_field_;
300
301 /* The storage container which holds the training data/samples generated during the last
302 * rendering iteration. */
303 unique_ptr<openpgl::cpp::SampleStorage> guiding_sample_data_storage_;
304
305 /* The number of already performed training iterations for the guiding field. */
306 int guiding_update_count = 0;
307#endif
308
309 /* State which is common for all the steps of the render work.
310 * Is brought up to date in the `render()` call and is accessed from all the steps involved into
311 * rendering the work. */
312 struct {
313 /* Denotes whether render buffers parameters of path trace works are to be reset for the new
314 * value of the big tile parameters. */
315 bool need_reset_params = false;
316
317 /* Divider of the resolution for faster previews.
318 *
319 * Allows to re-use same render buffer, but have less pixels rendered into in it. The way to
320 * think of render buffer in this case is as an over-allocated array: the resolution divider
321 * affects both resolution and stride as visible by the integrator kernels. */
323
324 /* Parameters of the big tile with the current resolution divider applied. */
326
327 /* Denoiser was run and there are denoised versions of the passes in the render buffers. */
329
330 /* Current tile has been written (to either disk or callback.
331 * Indicates that no more work will be done on this tile. */
332 bool tile_written = false;
334
335 /* Progress object which is used to communicate sample progress. */
337
338 /* Fields required for canceling render on demand, as quickly as possible. */
339 struct {
340 /* Indicates whether there is an on-going `render_samples()` call. */
341 bool is_rendering = false;
342
343 /* Indicates whether rendering is requested to be canceled by `cancel()`. */
344 bool is_requested = false;
345
346 /* Synchronization between thread which does `render_samples()` and thread which does
347 * `cancel()`. */
351
352 /* Indicates whether a render result was drawn after latest session reset.
353 * Used by `ready_to_reset()` to implement logic which feels the most interactive. */
355
356 /* State of the full frame processing and writing to the software. */
357 struct {
360};
361
void reset()
clear internal cached data and reset random seed
Definition film.h:29
void device_free()
Progress * progress_
Definition path_trace.h:336
thread_condition_variable condition
Definition path_trace.h:349
void denoise(const RenderWork &render_work)
BufferParams effective_big_tile_params
Definition path_trace.h:325
int2 get_render_tile_size() const
void finalize_full_buffer_on_disk(const RenderWork &render_work)
std::function< void(void)> progress_update_cb
Definition path_trace.h:185
void process_full_buffer_from_disk(string_view filename)
void tile_buffer_write()
Device * device_
Definition path_trace.h:255
unique_ptr< Denoiser > denoiser_
Definition path_trace.h:288
void update_effective_work_buffer_params(const RenderWork &render_work)
BufferParams full_params_
Definition path_trace.h:284
void rebalance(const RenderWork &render_work)
bool is_cancel_requested()
struct PathTrace::@134371127017210132007075065004246317237136077123 render_state_
void init_render_buffers(const RenderWork &render_work)
void copy_to_render_buffers(RenderBuffers *render_buffers)
void destroy_gpu_resources()
bool has_denoised_result() const
void set_progress(Progress *progress)
vector< unique_ptr< PathTraceWork > > path_trace_works_
Definition path_trace.h:278
void copy_from_render_buffers(RenderBuffers *render_buffers)
Device * denoise_device_
Definition path_trace.h:259
void set_denoiser_params(const DenoiseParams &params)
struct PathTrace::@045127216101200035253035102154226266260300121335 full_frame_state_
void progress_update_if_needed(const RenderWork &render_work)
bool need_reset_params
Definition path_trace.h:315
void update_display(const RenderWork &render_work)
void progress_set_status(const string &status, const string &substatus="")
void set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling)
void set_output_driver(unique_ptr< OutputDriver > driver)
void reset(const BufferParams &full_params, const BufferParams &big_tile_params, bool reset_rendering)
DeviceScene * device_scene_
Definition path_trace.h:265
bool ready_to_reset()
bool get_render_tile_pixels(const PassAccessor &pass_accessor, const PassAccessor::Destination &destination)
void cancel()
void guiding_update_structures()
PathTrace(Device *device, Device *denoise_device, Film *film, DeviceScene *device_scene, RenderScheduler &render_scheduler, TileManager &tile_manager)
void zero_display()
void guiding_prepare_structures()
int2 get_render_tile_offset() const
unique_ptr< Device > cpu_device_
Definition path_trace.h:262
void denoise_volume_guiding_buffers(const RenderWork &render_work, const bool has_volume)
thread_mutex mutex
Definition path_trace.h:348
void set_guiding_params(const GuidingParams &params, const bool reset)
void tile_buffer_write_to_disk()
void set_display_driver(unique_ptr< DisplayDriver > driver)
void path_trace(RenderWork &render_work)
void render_pipeline(RenderWork render_work)
unique_ptr< OutputDriver > output_driver_
Definition path_trace.h:274
bool tile_written
Definition path_trace.h:332
unique_ptr< PathTraceDisplay > display_
Definition path_trace.h:271
vector< WorkBalanceInfo > work_balance_infos_
Definition path_trace.h:281
RenderBuffers * render_buffers
Definition path_trace.h:358
bool copy_render_tile_from_device()
bool has_denoised_result
Definition path_trace.h:328
bool is_rendering
Definition path_trace.h:341
bool did_draw_after_reset_
Definition path_trace.h:354
void render_init_kernel_execution()
int2 get_render_size() const
struct PathTrace::@264204132215367063060273366367103232030034067245 render_cancel_
TileManager & tile_manager_
Definition path_trace.h:268
unique_ptr< PathTraceWork > big_tile_denoise_work_
Definition path_trace.h:291
void update_work_buffer_params_if_needed(const RenderWork &render_work)
void alloc_work_memory()
BufferParams big_tile_params_
Definition path_trace.h:285
void draw()
void write_tile_buffer(const RenderWork &render_work)
void tile_buffer_read()
bool set_render_tile_pixels(PassAccessor &pass_accessor, const PassAccessor::Source &source)
void render(const RenderWork &render_work)
Film * film_
Definition path_trace.h:264
string full_report() const
void adaptive_sample(RenderWork &render_work)
void load_kernels()
const BufferParams & get_render_tile_params() const
int resolution_divider
Definition path_trace.h:322
int get_num_render_tile_samples() const
bool is_requested
Definition path_trace.h:344
void flush_display()
RenderScheduler & render_scheduler_
Definition path_trace.h:267
int get_num_samples_in_buffer()
void cryptomatte_postprocess(const RenderWork &render_work)
void update_allocated_work_buffer_params()
#define CCL_NAMESPACE_END
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
const int status
std::mutex thread_mutex
Definition thread.h:27
std::condition_variable thread_condition_variable
Definition thread.h:29