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