Blender V4.3
path_trace_display.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2021-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#pragma once
6
8
9#include "util/half.h"
10#include "util/thread.h"
11#include "util/types.h"
12#include "util/unique_ptr.h"
13
15
16class BufferParams;
17
18/* PathTraceDisplay is used for efficient render buffer display.
19 *
20 * The host applications implements a DisplayDriver, storing a render pass in a GPU-side
21 * textures. This texture is continuously updated by the path tracer and drawn by the host
22 * application.
23 *
24 * PathTraceDisplay is a wrapper around the DisplayDriver, adding thread safety, state tracking
25 * and error checking. */
26
28 public:
29 explicit PathTraceDisplay(unique_ptr<DisplayDriver> driver);
30 virtual ~PathTraceDisplay() = default;
31
32 /* Reset the display for the new state of render session. Is called whenever session is reset,
33 * which happens on changes like viewport navigation or viewport dimension change.
34 *
35 * This call will configure parameters for a changed buffer and reset the texture state.
36 *
37 * When the `reset_rendering` a complete display reset happens. When it is false reset happens
38 * for a new state of the buffer parameters which is assumed to correspond to the next tile. */
39 void reset(const BufferParams &buffer_params, bool reset_rendering);
40
41 /* --------------------------------------------------------------------
42 * Update procedure.
43 *
44 * These calls indicates a desire of the caller to update content of the displayed texture. */
45
46 /* Returns true when update is ready. Update should be finished with update_end().
47 *
48 * If false is returned then no update is possible, and no update_end() call is needed.
49 *
50 * The texture width and height denotes an actual resolution of the underlying render result. */
51 bool update_begin(int texture_width, int texture_height);
52
53 void update_end();
54
55 /* Get currently configured texture size of the display (as configured by `update_begin()`. */
56 int2 get_texture_size() const;
57
58 /* --------------------------------------------------------------------
59 * Texture update from CPU buffer.
60 *
61 * NOTE: The PathTraceDisplay should be marked for an update being in process with
62 * `update_begin()`.
63 *
64 * Most portable implementation, which must be supported by all platforms. Might not be the most
65 * efficient one.
66 */
67
68 /* Copy buffer of rendered pixels of a given size into a given position of the texture.
69 *
70 * This function does not acquire a lock. The reason for this is to allow use of this function
71 * for partial updates from different devices. In this case the caller will acquire the lock
72 * once, update all the slices and release
73 * the lock once. This will ensure that draw() will never use partially updated texture. */
75 const half4 *rgba_pixels, int texture_x, int texture_y, int pixels_width, int pixels_height);
76
77 /* --------------------------------------------------------------------
78 * Texture buffer mapping.
79 *
80 * This functionality is used to update GPU-side texture content without need to maintain CPU
81 * side buffer on the caller.
82 *
83 * NOTE: The PathTraceDisplay should be marked for an update being in process with
84 * `update_begin()`.
85 *
86 * NOTE: Texture buffer can not be mapped while graphics interoperability is active. This means
87 * that `map_texture_buffer()` is not allowed between `graphics_interop_begin()` and
88 * `graphics_interop_end()` calls.
89 */
90
91 /* Map pixels memory form texture to a buffer available for write from CPU. Width and height will
92 * define a requested size of the texture to write to.
93 * Upon success a non-null pointer is returned and the texture buffer is to be unmapped.
94 * If an error happens during mapping, or if mapping is not supported by this GPU display a
95 * null pointer is returned and the buffer is NOT to be unmapped.
96 *
97 * NOTE: Usually the implementation will rely on a GPU context of some sort, and the GPU context
98 * is often can not be bound to two threads simultaneously, and can not be released from a
99 * different thread. This means that the mapping API should be used from the single thread only,
100 */
103
104 /* --------------------------------------------------------------------
105 * Graphics interoperability.
106 *
107 * A special code path which allows to update texture content directly from the GPU compute
108 * device. Complementary part of DeviceGraphicsInterop.
109 *
110 * NOTE: Graphics interoperability can not be used while the texture buffer is mapped. This means
111 * that `graphics_interop_get()` is not allowed between `map_texture_buffer()` and
112 * `unmap_texture_buffer()` calls. */
113
114 /* Get PathTraceDisplay graphics interoperability information which acts as a destination for the
115 * device API. */
117
118 /* (De)activate GPU display for graphics interoperability outside of regular display update
119 * routines. */
122
123 /* --------------------------------------------------------------------
124 * Drawing.
125 */
126
127 /* Clear the texture by filling it with all zeroes.
128 *
129 * This call might happen in parallel with draw, but can never happen in parallel with the
130 * update.
131 *
132 * The actual zeroing can be deferred to a later moment. What is important is that after clear
133 * and before pixels update the drawing texture will be fully empty, and that partial update
134 * after clear will write new pixel values for an updating area, leaving everything else zeroed.
135 *
136 * If the GPU display supports graphics interoperability then the zeroing the display is to be
137 * delegated to the device via the `DisplayDriver::GraphicsInterop`. */
138 void clear();
139
140 /* Draw the current state of the texture.
141 *
142 * Returns true if this call did draw an updated state of the texture. */
143 bool draw();
144
145 /* Flush outstanding display commands before ending the render loop. */
146 void flush();
147
148 private:
149 /* Display driver implemented by the host application. */
150 unique_ptr<DisplayDriver> driver_;
151
152 /* Current display parameters */
153 thread_mutex mutex_;
154 DisplayDriver::Params params_;
155
156 /* Mark texture as its content has been updated.
157 * Used from places which knows that the texture content has been brought up-to-date, so that the
158 * drawing knows whether it can be performed, and whether drawing happened with an up-to-date
159 * texture state. */
160 void mark_texture_updated();
161
162 /* State of the update process. */
163 struct {
164 /* True when update is in process, indicated by `update_begin()` / `update_end()`. */
165 bool is_active = false;
166 } update_state_;
167
168 /* State of the texture, which is needed for an integration with render session and interactive
169 * updates and navigation. */
170 struct {
171 /* Texture is considered outdated after `reset()` until the next call of
172 * `copy_pixels_to_texture()`. */
173 bool is_outdated = true;
174
175 /* Texture size in pixels. */
176 int2 size = make_int2(0, 0);
177 } texture_state_;
178
179 /* State of the texture buffer. Is tracked to perform sanity checks. */
180 struct {
181 /* True when the texture buffer is mapped with `map_texture_buffer()`. */
182 bool is_mapped = false;
183 } texture_buffer_state_;
184};
185
void reset()
clear internal cached data and reset random seed
virtual ~PathTraceDisplay()=default
int2 get_texture_size() const
PathTraceDisplay(unique_ptr< DisplayDriver > driver)
DisplayDriver::GraphicsInterop graphics_interop_get()
bool update_begin(int texture_width, int texture_height)
void copy_pixels_to_texture(const half4 *rgba_pixels, int texture_x, int texture_y, int pixels_width, int pixels_height)
#define CCL_NAMESPACE_END
ccl_device_forceinline int2 make_int2(const int x, const int y)
Definition half.h:61
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
Definition thread.h:29