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